mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-23 21:51:29 +00:00
Merge ed9c1464a1
into df7ebf977a
This commit is contained in:
commit
04f57e456b
22 changed files with 238 additions and 51 deletions
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="PROJECT" dialect="MySQL" />
|
||||
</component>
|
||||
</project>
|
|
@ -93,4 +93,13 @@
|
|||
<data name="read_only_warn" xml:space="preserve">
|
||||
<value>This instance is currently in read-only mode. Level and photo uploads, comments, reviews, and certain profile changes will be restricted until read-only mode is disabled.</value>
|
||||
</data>
|
||||
<data name="email_enforcement_message_main" xml:space="preserve">
|
||||
<value>This instance has email enforcement enabled. If you haven't already, you will need to set and verify an email address to use most features.</value>
|
||||
</data>
|
||||
<data name="email_enforcement_message_no_email" xml:space="preserve">
|
||||
<value>You do not have an email set on your account. You can set an email by opening the text chat and typing "/setemail [youremail@example.com]" (do not include the brackets.)</value>
|
||||
</data>
|
||||
<data name="email_enforcement_message_verify_email" xml:space="preserve">
|
||||
<value>You have set an email address on your account, but you have not verified it. Make sure to check your inbox for a verification email. If you have not recieved an email, please contact an instance administrator for further assistance.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -26,5 +26,10 @@ public static class BaseLayoutStrings
|
|||
public static readonly TranslatableString ReadOnlyWarnTitle = create("read_only_warn_title");
|
||||
public static readonly TranslatableString ReadOnlyWarn = create("read_only_warn");
|
||||
|
||||
public static readonly TranslatableString EmailEnforcementWarnMain = create("email_enforcement_message_main");
|
||||
public static readonly TranslatableString EmailEnforcementWarnNoEmail = create("email_enforcement_message_no_email");
|
||||
public static readonly TranslatableString EmailEnforcementWarnVerifyEmail = create("email_enforcement_message_verify_email");
|
||||
|
||||
|
||||
private static TranslatableString create(string key) => new(TranslationAreas.BaseLayout, key);
|
||||
}
|
|
@ -49,7 +49,7 @@ public class CommentController : ControllerBase
|
|||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.Unauthorized();
|
||||
if (user == null) return this.Forbid();
|
||||
|
||||
if ((slotId == 0 || SlotHelper.IsTypeInvalid(slotType)) == (username == null)) return this.BadRequest();
|
||||
|
||||
|
@ -97,7 +97,7 @@ public class CommentController : ControllerBase
|
|||
.ApplyPagination(pageData)
|
||||
.ToListAsync()).ToSerializableList(c => GameComment.CreateFromEntity(c, token.UserId));
|
||||
|
||||
if (type == CommentType.Level && slotType == "developer" && user.IsModerator && pageData.PageStart == 1)
|
||||
if (type == CommentType.Level && slotType == "developer" && user.IsModerator && pageData.PageStart == 1)
|
||||
{
|
||||
comments.Insert(0, new GameComment
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ using LBPUnion.ProjectLighthouse.Extensions;
|
|||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Interaction;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Level;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
|
||||
using LBPUnion.ProjectLighthouse.Types.Users;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
@ -100,6 +101,9 @@ public class EnterLevelController : ControllerBase
|
|||
{
|
||||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.Unauthorized();
|
||||
|
||||
if (SlotHelper.IsTypeInvalid(slotType)) return this.BadRequest();
|
||||
|
||||
if (slotType == "developer") return this.Ok();
|
||||
|
|
|
@ -41,7 +41,7 @@ public class MatchController : ControllerBase
|
|||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.Forbid();
|
||||
if (user == null) return this.Unauthorized();
|
||||
|
||||
await LastContactHelper.SetLastContact(this.database, user, token.GameVersion, token.Platform);
|
||||
|
||||
|
|
|
@ -55,16 +55,31 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.";
|
|||
{
|
||||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
string username = await this.database.UsernameFromGameToken(token);
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.BadRequest();
|
||||
|
||||
StringBuilder announceText = new(ServerConfiguration.Instance.AnnounceText);
|
||||
|
||||
announceText.Replace("%user", username);
|
||||
announceText.Replace("%user", user.Username);
|
||||
announceText.Replace("%id", token.UserId.ToString());
|
||||
|
||||
if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode)
|
||||
{
|
||||
announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n");
|
||||
announceText.Append(BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n");
|
||||
}
|
||||
|
||||
if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailEnforcement)
|
||||
{
|
||||
announceText.Append("\n\n" + BaseLayoutStrings.EmailEnforcementWarnMain.Translate(LocalizationManager.DefaultLang) + "\n\n");
|
||||
|
||||
if (user.EmailAddress == null)
|
||||
{
|
||||
announceText.Append(BaseLayoutStrings.EmailEnforcementWarnNoEmail.Translate(LocalizationManager.DefaultLang) + "\n\n");
|
||||
}
|
||||
else if (!user.EmailAddressVerified)
|
||||
{
|
||||
announceText.Append(BaseLayoutStrings.EmailEnforcementWarnVerifyEmail.Translate(LocalizationManager.DefaultLang) + "\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
@ -129,12 +144,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.";
|
|||
if (message.StartsWith("/setemail ") && ServerConfiguration.Instance.Mail.MailEnabled)
|
||||
{
|
||||
string email = message[(message.IndexOf(" ", StringComparison.Ordinal)+1)..];
|
||||
if (!SanitizationHelper.IsValidEmail(email)) return this.Ok();
|
||||
|
||||
if (await this.database.Users.AnyAsync(u => u.EmailAddress == email)) return this.Ok();
|
||||
// Return a bad request on invalid email address
|
||||
if (!SMTPHelper.IsValidEmail(this.database, email)) return this.BadRequest();
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null || user.EmailAddressVerified) return this.Ok();
|
||||
if (user == null || user.EmailAddressVerified) return this.BadRequest();
|
||||
|
||||
user.EmailAddress = email;
|
||||
await SMTPHelper.SendVerificationEmail(this.database, mailService, user);
|
||||
|
|
|
@ -174,7 +174,6 @@ public class PhotosController : ControllerBase
|
|||
[HttpGet("photos/{slotType}/{id:int}")]
|
||||
public async Task<IActionResult> SlotPhotos(string slotType, int id, [FromQuery] string? by)
|
||||
{
|
||||
|
||||
if (SlotHelper.IsTypeInvalid(slotType)) return this.BadRequest();
|
||||
|
||||
if (slotType == "developer") id = await SlotHelper.GetPlaceholderSlotId(this.database, id, SlotType.Developer);
|
||||
|
@ -202,7 +201,6 @@ public class PhotosController : ControllerBase
|
|||
[HttpGet("photos/by")]
|
||||
public async Task<IActionResult> UserPhotosBy(string user)
|
||||
{
|
||||
|
||||
int targetUserId = await this.database.UserIdFromUsername(user);
|
||||
if (targetUserId == 0) return this.NotFound();
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers.Resources;
|
|||
[Route("LITTLEBIGPLANETPS3_XML")]
|
||||
public class ResourcesController : ControllerBase
|
||||
{
|
||||
|
||||
[HttpPost("showModerated")]
|
||||
public IActionResult ShowModerated() => this.Ok(new ResourceList());
|
||||
|
||||
|
|
|
@ -38,9 +38,6 @@ public class CategoryController : ControllerBase
|
|||
{
|
||||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.Forbid();
|
||||
|
||||
PaginationData pageData = this.Request.GetPaginationData();
|
||||
|
||||
pageData.TotalElements = CategoryHelper.Categories.Count(c => !string.IsNullOrWhiteSpace(c.Name));
|
||||
|
@ -72,9 +69,6 @@ public class CategoryController : ControllerBase
|
|||
{
|
||||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.Forbid();
|
||||
|
||||
Category? category = CategoryHelper.Categories.FirstOrDefault(c => c.Endpoint == endpointName);
|
||||
if (category == null) return this.NotFound();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class PublishController : ControllerBase
|
|||
public async Task<IActionResult> StartPublish()
|
||||
{
|
||||
GameTokenEntity token = this.GetToken();
|
||||
|
||||
|
||||
UserEntity? user = await this.database.UserFromGameToken(token);
|
||||
if (user == null) return this.Forbid();
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public class UserController : ControllerBase
|
|||
|
||||
[HttpGet("user/{username}")]
|
||||
public async Task<IActionResult> GetUser(string username)
|
||||
{
|
||||
{
|
||||
UserEntity? user = await this.database.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
if (user == null) return this.NotFound();
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Database;
|
||||
using LBPUnion.ProjectLighthouse.Middlewares;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
|
||||
|
||||
public class EmailEnforcementMiddleware : MiddlewareDBContext
|
||||
{
|
||||
private static readonly HashSet<string> enforcedPaths = ServerConfiguration.Instance.EmailEnforcement.BlockedEndpoints;
|
||||
|
||||
public EmailEnforcementMiddleware(RequestDelegate next) : base(next)
|
||||
{ }
|
||||
|
||||
public override async Task InvokeAsync(HttpContext context, DatabaseContext database)
|
||||
{
|
||||
if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailEnforcement)
|
||||
{
|
||||
// Split path into segments
|
||||
string[] pathSegments = context.Request.Path.ToString().Split("/", StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (pathSegments[0] == "LITTLEBIGPLANETPS3_XML")
|
||||
{
|
||||
// Get user via GameToken
|
||||
GameTokenEntity? token = await database.GameTokenFromRequest(context.Request);
|
||||
UserEntity? user = await database.UserFromGameToken(token);
|
||||
|
||||
// Check second part of path to see if client is within an enforced path
|
||||
// This could probably be reworked, seeing as you may want to check for a deeper sub-path
|
||||
// But it should be perfectly fine for now
|
||||
if (enforcedPaths.Contains(pathSegments[1]))
|
||||
{
|
||||
// Check if user is valid, don't want any exceptions
|
||||
if (user == null)
|
||||
{
|
||||
// Send bad request status
|
||||
context.Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
await context.Response.WriteAsync("Not a valid user");
|
||||
|
||||
// Don't go to next in pipeline
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if email is there and verified
|
||||
if (!user.EmailAddressVerified || user.EmailAddress == null)
|
||||
{
|
||||
// Send bad request status
|
||||
context.Response.StatusCode = StatusCodes.Status400BadRequest;
|
||||
await context.Response.WriteAsync("Invalid user email address");
|
||||
|
||||
// Don't go to next in pipeline
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go to next in pipeline
|
||||
await this.next(context);
|
||||
}
|
||||
}
|
|
@ -107,6 +107,7 @@ public class GameServerStartup
|
|||
app.UseMiddleware<RateLimitMiddleware>();
|
||||
app.UseMiddleware<DigestMiddleware>(computeDigests);
|
||||
app.UseMiddleware<SetLastContactMiddleware>();
|
||||
app.UseMiddleware<EmailEnforcementMiddleware>();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public class SetEmailForm : BaseLayout
|
|||
UserEntity? user = await this.Database.Users.FirstOrDefaultAsync(u => u.UserId == token.UserId);
|
||||
if (user == null) return this.Redirect("~/login");
|
||||
|
||||
if (!SanitizationHelper.IsValidEmail(emailAddress))
|
||||
if (!SMTPHelper.IsValidEmail(this.Database, emailAddress))
|
||||
{
|
||||
this.Error = this.Translate(ErrorStrings.EmailInvalid);
|
||||
return this.Page();
|
||||
|
|
|
@ -38,9 +38,9 @@ public class PasswordResetRequestForm : BaseLayout
|
|||
return this.Page();
|
||||
}
|
||||
|
||||
if (!SanitizationHelper.IsValidEmail(email))
|
||||
if (!SMTPHelper.IsValidEmail(this.Database, email))
|
||||
{
|
||||
this.Error = "This email is in an invalid format";
|
||||
this.Error = "This email is invalid";
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,18 +64,14 @@ public class UserSettingsPage : BaseLayout
|
|||
}
|
||||
}
|
||||
|
||||
if (ServerConfiguration.Instance.Mail.MailEnabled &&
|
||||
SanitizationHelper.IsValidEmail(email) &&
|
||||
if (ServerConfiguration.Instance.Mail.MailEnabled &&
|
||||
email != null && SMTPHelper.IsValidEmail(this.Database, email) &&
|
||||
(this.User == this.ProfileUser || this.User.IsAdmin))
|
||||
{
|
||||
// if email hasn't already been used
|
||||
if (!await this.Database.Users.AnyAsync(u => u.EmailAddress != null && u.EmailAddress.ToLower() == email!.ToLower()))
|
||||
if (this.ProfileUser.EmailAddress != email)
|
||||
{
|
||||
if (this.ProfileUser.EmailAddress != email)
|
||||
{
|
||||
this.ProfileUser.EmailAddress = email;
|
||||
this.ProfileUser.EmailAddressVerified = false;
|
||||
}
|
||||
this.ProfileUser.EmailAddress = email;
|
||||
this.ProfileUser.EmailAddressVerified = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>." + "\nuni
|
|||
|
||||
IActionResult result = await messageController.Filter(mailMock.Object);
|
||||
|
||||
Assert.IsType<OkResult>(result);
|
||||
Assert.IsType<BadRequestResult>(result);
|
||||
mailMock.Verify(x => x.SendEmailAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>." + "\nuni
|
|||
|
||||
IActionResult result = await messageController.Filter(mailMock.Object);
|
||||
|
||||
Assert.IsType<OkResult>(result);
|
||||
Assert.IsType<BadRequestResult>(result);
|
||||
mailMock.Verify(x => x.SendEmailAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>." + "\nuni
|
|||
|
||||
IActionResult result = await messageController.Filter(mailMock.Object);
|
||||
|
||||
Assert.IsType<OkResult>(result);
|
||||
Assert.IsType<BadRequestResult>(result);
|
||||
mailMock.Verify(x => x.SendEmailAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Configuration;
|
||||
|
||||
public class EmailEnforcementConfiguration : ConfigurationBase<EmailEnforcementConfiguration>
|
||||
{
|
||||
public override int ConfigVersion { get; set; } = 1;
|
||||
|
||||
public override string ConfigName { get; set; } = "enforce-email.yml";
|
||||
|
||||
public override bool NeedsConfiguration { get; set; } = false;
|
||||
|
||||
public bool EnableEmailEnforcement { get; set; } = false;
|
||||
public bool EnableEmailBlacklist { get; set; } = false;
|
||||
|
||||
// No blacklist by default, add path to blacklist
|
||||
public string BlacklistFilePath { get; set; } = "";
|
||||
|
||||
// Endpoints to be blocked
|
||||
// This is kind of a random list so some may need to be added or removed
|
||||
public HashSet<string> BlockedEndpoints { get; set; } = new()
|
||||
{
|
||||
// Comments
|
||||
"rateUserComment",
|
||||
"rateComment",
|
||||
"comments",
|
||||
"userComments",
|
||||
"postUserComment",
|
||||
"postComment",
|
||||
"deleteUserComment",
|
||||
"deleteComment",
|
||||
|
||||
// Slots
|
||||
"showModerated",
|
||||
"startPublish",
|
||||
"slots",
|
||||
"s",
|
||||
"tags",
|
||||
"tag",
|
||||
"searches",
|
||||
"genres",
|
||||
"publish",
|
||||
"unpublish",
|
||||
|
||||
// Misc Resources
|
||||
"upload",
|
||||
"r",
|
||||
|
||||
// Photos
|
||||
"uploadPhoto",
|
||||
"photos",
|
||||
"deletePhoto",
|
||||
|
||||
// Gameplay
|
||||
"match",
|
||||
"play",
|
||||
"enterLevel",
|
||||
"playlists",
|
||||
|
||||
// Users
|
||||
"user",
|
||||
"users",
|
||||
"updateUser",
|
||||
"update_my_pins",
|
||||
};
|
||||
|
||||
public override ConfigurationBase<EmailEnforcementConfiguration> Deserialize
|
||||
(IDeserializer deserializer, string text) =>
|
||||
deserializer.Deserialize<EmailEnforcementConfiguration>(text);
|
||||
}
|
|
@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase<ServerConfiguration>
|
|||
// This is so Lighthouse can properly identify outdated configurations and update them with newer settings accordingly.
|
||||
// If you are modifying anything here, this value MUST be incremented.
|
||||
// Thanks for listening~
|
||||
public override int ConfigVersion { get; set; } = 27;
|
||||
public override int ConfigVersion { get; set; } = 28;
|
||||
|
||||
public override string ConfigName { get; set; } = "lighthouse.yml";
|
||||
public string WebsiteListenUrl { get; set; } = "http://localhost:10060";
|
||||
|
@ -46,5 +46,7 @@ public class ServerConfiguration : ConfigurationBase<ServerConfiguration>
|
|||
public RichPresenceConfiguration RichPresenceConfiguration { get; set; } = new();
|
||||
public NotificationConfiguration NotificationConfiguration { get; set; } = new();
|
||||
|
||||
public EmailEnforcementConfiguration EmailEnforcement { get; set; } = new();
|
||||
|
||||
public override ConfigurationBase<ServerConfiguration> Deserialize(IDeserializer deserializer, string text) => deserializer.Deserialize<ServerConfiguration>(text);
|
||||
}
|
|
@ -2,13 +2,17 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Database;
|
||||
using LBPUnion.ProjectLighthouse.Extensions;
|
||||
using LBPUnion.ProjectLighthouse.Logging;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
|
||||
using LBPUnion.ProjectLighthouse.Types.Logging;
|
||||
using LBPUnion.ProjectLighthouse.Types.Mail;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
|
@ -16,11 +20,19 @@ namespace LBPUnion.ProjectLighthouse.Helpers;
|
|||
|
||||
public static class SMTPHelper
|
||||
{
|
||||
private static readonly string blacklistFilePath = ServerConfiguration.Instance.EmailEnforcement.BlacklistFilePath;
|
||||
|
||||
// Null check blacklistFilePath and read into array
|
||||
private static readonly string[] blacklistFile =
|
||||
!string.IsNullOrWhiteSpace(blacklistFilePath) ? File.ReadAllLines(blacklistFilePath) : [];
|
||||
|
||||
// (User id, timestamp of last request + 30 seconds)
|
||||
private static readonly ConcurrentDictionary<int, long> recentlySentMail = new();
|
||||
|
||||
private const long emailCooldown = 1000 * 30;
|
||||
|
||||
private static readonly HashSet<string> blacklistedDomains = new(blacklistFile);
|
||||
|
||||
private static bool CanSendMail(UserEntity user)
|
||||
{
|
||||
// Remove expired entries
|
||||
|
@ -68,6 +80,39 @@ public static class SMTPHelper
|
|||
|
||||
recentlySentMail.TryAdd(user.UserId, TimeHelper.TimestampMillis + emailCooldown);
|
||||
}
|
||||
|
||||
// Accumulate checks to determine email validity
|
||||
public static bool IsValidEmail(DatabaseContext database, string email)
|
||||
{
|
||||
// Email should not be empty, should be an actual email, and shouldn't already be used by an account
|
||||
if (string.IsNullOrWhiteSpace(email) || !emailValidator.IsValid(email) || EmailIsUsed(database, email).Result)
|
||||
return false;
|
||||
|
||||
// Don't even bother if there are no domains in blacklist (AKA file path is empty/invalid, or file itself is empty)
|
||||
if (!ServerConfiguration.Instance.EmailEnforcement.EnableEmailBlacklist || blacklistedDomains.Count <= 0)
|
||||
return true;
|
||||
|
||||
// Get domain by splitting at '@' character
|
||||
string domain = email.Split('@')[1];
|
||||
|
||||
// Return false if domain is found in blacklist
|
||||
if (blacklistedDomains.Contains(domain))
|
||||
{
|
||||
Logger.Info($"Invalid email address {email} submitted by user.", LogArea.Email);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't want to allocate every single time we call EmailAddressAttribute.IsValidEmail()
|
||||
private static readonly EmailAddressAttribute emailValidator = new();
|
||||
|
||||
// Check if email is already in use by an account
|
||||
private static async Task<bool> EmailIsUsed(DatabaseContext database, string email)
|
||||
{
|
||||
return await database.Users.AnyAsync(u => u.EmailAddress != null && u.EmailAddress.ToLower() == email.ToLower());
|
||||
}
|
||||
|
||||
public static void SendRegistrationEmail(IMailService mail, UserEntity user)
|
||||
{
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#nullable enable
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Helpers;
|
||||
|
||||
public static class SanitizationHelper
|
||||
{
|
||||
public static bool IsValidEmail(string? email) => !string.IsNullOrWhiteSpace(email) && new EmailAddressAttribute().IsValid(email);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue