diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs
index d1886d7f..8f550acf 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/CommentController.cs
@@ -97,7 +97,8 @@ 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
{
CommentId = 0,
diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs
index 7a82deca..b6948dfd 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs
@@ -56,6 +56,7 @@ along with this program. If not, see .";
GameTokenEntity token = this.GetToken();
UserEntity? user = await this.database.UserFromGameToken(token);
+ if (user == null) return this.BadRequest();
StringBuilder announceText = new(ServerConfiguration.Instance.AnnounceText);
@@ -67,7 +68,7 @@ along with this program. If not, see .";
announceText.Append(BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n");
}
- if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement)
+ if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailEnforcement)
{
announceText.Append("\n\n" + BaseLayoutStrings.EmailEnforcementWarnMain.Translate(LocalizationManager.DefaultLang) + "\n\n");
diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs
index 4b13f252..80798067 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/PhotosController.cs
@@ -216,7 +216,7 @@ public class PhotosController : ControllerBase
[HttpGet("photos/with")]
public async Task UserPhotosWith(string user)
- {
+ {
int targetUserId = await this.database.UserIdFromUsername(user);
if (targetUserId == 0) return this.NotFound();
diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs
index 630be2c9..f48c7e7d 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/Resources/ResourcesController.cs
@@ -35,18 +35,18 @@ public class ResourcesController : ControllerBase
}
[HttpGet("r/{hash}")]
- public async Task GetResource(string hash)
+ public Task GetResource(string hash)
{
string path = FileHelper.GetResourcePath(hash);
string fullPath = Path.GetFullPath(path);
// Prevent directory traversal attacks
- if (!fullPath.StartsWith(FileHelper.FullResourcePath)) return this.BadRequest();
+ if (!fullPath.StartsWith(FileHelper.FullResourcePath)) return Task.FromResult(this.BadRequest());
- if (FileHelper.ResourceExists(hash)) return this.File(IOFile.OpenRead(path), "application/octet-stream");
+ if (FileHelper.ResourceExists(hash)) return Task.FromResult(this.File(IOFile.OpenRead(path), "application/octet-stream"));
- return this.NotFound();
+ return Task.FromResult(this.NotFound());
}
[HttpPost("upload/{hash}/unattributed")]
diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs
index 2b32dc32..ed0dbe12 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs
@@ -29,8 +29,6 @@ public class UserController : ControllerBase
{
private readonly DatabaseContext database;
- private static readonly bool emailEnforcementEnabled = EmailEnforcementConfiguration.Instance.EnableEmailEnforcement;
-
public UserController(DatabaseContext database)
{
this.database = database;
diff --git a/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs b/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs
index b269c97a..7482439c 100644
--- a/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs
+++ b/ProjectLighthouse.Servers.GameServer/Middlewares/EmailEnforcementMiddleware.cs
@@ -8,14 +8,14 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
public class EmailEnforcementMiddleware : MiddlewareDBContext
{
- private static readonly HashSet enforcedPaths = EmailEnforcementConfiguration.Instance.BlockedEndpoints;
+ private static readonly HashSet enforcedPaths = ServerConfiguration.Instance.EmailEnforcement.BlockedEndpoints;
public EmailEnforcementMiddleware(RequestDelegate next) : base(next)
{ }
public override async Task InvokeAsync(HttpContext context, DatabaseContext database)
{
- if (EmailEnforcementConfiguration.Instance.EnableEmailEnforcement)
+ if (ServerConfiguration.Instance.EmailEnforcement.EnableEmailEnforcement)
{
// Split path into segments
string[] pathSegments = context.Request.Path.ToString().Split("/", StringSplitOptions.RemoveEmptyEntries);
diff --git a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs
index d1a9c0a8..8904e294 100644
--- a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs
+++ b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs
@@ -64,8 +64,8 @@ public class UserSettingsPage : BaseLayout
}
}
- if (ServerConfiguration.Instance.Mail.MailEnabled &&
- SMTPHelper.IsValidEmail(this.Database, email) &&
+ if (ServerConfiguration.Instance.Mail.MailEnabled &&
+ email != null && SMTPHelper.IsValidEmail(this.Database, email) &&
(this.User == this.ProfileUser || this.User.IsAdmin))
{
if (this.ProfileUser.EmailAddress != email)
diff --git a/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs b/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs
index c6697df1..56179d91 100644
--- a/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs
+++ b/ProjectLighthouse/Configuration/EmailEnforcementConfiguration.cs
@@ -1,6 +1,5 @@
#nullable enable
using System.Collections.Generic;
-using System.IO;
using YamlDotNet.Serialization;
namespace LBPUnion.ProjectLighthouse.Configuration;
@@ -13,15 +12,15 @@ public class EmailEnforcementConfiguration : ConfigurationBase false;
+ public bool EnableEmailBlacklist => false;
// No blacklist by default, add path to blacklist
- public string BlacklistFilePath { get; set; } = "";
+ public string BlacklistFilePath => "";
// Endpoints to be blocked
// This is kind of a random list so some may need to be added or removed
- public HashSet BlockedEndpoints { get; set; } = new()
+ public HashSet BlockedEndpoints => new()
{
// Comments
"rateUserComment",
diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs
index ba9f7f4a..584c1a0e 100644
--- a/ProjectLighthouse/Configuration/ServerConfiguration.cs
+++ b/ProjectLighthouse/Configuration/ServerConfiguration.cs
@@ -11,7 +11,7 @@ public class ServerConfiguration : ConfigurationBase
// 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
public RichPresenceConfiguration RichPresenceConfiguration { get; set; } = new();
public NotificationConfiguration NotificationConfiguration { get; set; } = new();
+ public EmailEnforcementConfiguration EmailEnforcement { get; set; } = new();
+
public override ConfigurationBase Deserialize(IDeserializer deserializer, string text) => deserializer.Deserialize(text);
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/EmailHelper.cs b/ProjectLighthouse/Helpers/EmailHelper.cs
index 606b682b..65124f96 100644
--- a/ProjectLighthouse/Helpers/EmailHelper.cs
+++ b/ProjectLighthouse/Helpers/EmailHelper.cs
@@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using LBPUnion.ProjectLighthouse.Configuration;
+using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Logging;
@@ -20,15 +20,16 @@ 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 recentlySentMail = new();
private const long emailCooldown = 1000 * 30;
-
- // To prevent ReadAllLines() exception when BlacklistFilePath is empty
- private static readonly string[] blacklistFile =
- !string.IsNullOrWhiteSpace(EmailEnforcementConfiguration.Instance.BlacklistFilePath)
- ? File.ReadAllLines(EmailEnforcementConfiguration.Instance.BlacklistFilePath) : [];
private static readonly HashSet blacklistedDomains = new(blacklistFile);
@@ -84,28 +85,24 @@ public static class SMTPHelper
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)
+ 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)
{
- // Don't even bother if there are no domains in blacklist (AKA file path is empty/invalid, or file itself is empty)
- if (EmailEnforcementConfiguration.Instance.EnableEmailBlacklist && blacklistedDomains.Count > 0)
+ // Get domain by splitting at '@' character
+ string domain = email.Split('@')[1];
+
+ // Return false if domain is found in blacklist
+ if (blacklistedDomains.Contains(domain))
{
- // 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;
+ Logger.Info($"Invalid email address {email} submitted by user.", LogArea.Email);
+ return false;
}
-
- return true;
}
- return false;
+ return true;
}
// Don't want to allocate every single time we call EmailAddressAttribute.IsValidEmail()