From 1b4ea8889eb438b7f2f65d51b151d48252945863 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:37:11 -0500 Subject: [PATCH 01/37] Bump SixLabors.ImageSharp from 3.1.2 to 3.1.3 in /ProjectLighthouse (#991) Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/SixLabors/ImageSharp/releases) - [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.2...v3.1.3) --- updated-dependencies: - dependency-name: SixLabors.ImageSharp dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ProjectLighthouse/ProjectLighthouse.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index e56b134a..9512d717 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From b4d67d40168dec0df57327a6b641a7767b66f2ef Mon Sep 17 00:00:00 2001 From: Slendy Date: Mon, 11 Mar 2024 22:48:03 -0500 Subject: [PATCH 02/37] Add .gitattributes file for script line endings --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..5f14b721 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize shell scripts to have LF line endings +*.sh text eol=lf \ No newline at end of file From 5035dbb63daabe28a282e0918ba83003ab9502d4 Mon Sep 17 00:00:00 2001 From: sudokoko Date: Sun, 17 Mar 2024 18:51:43 -0400 Subject: [PATCH 03/37] Add the ability to disable matchmaking in configuration --- .../Controllers/Matching/MatchController.cs | 4 ++++ .../ConfigurationCategories/MatchmakingConfiguration.cs | 6 ++++++ ProjectLighthouse/Configuration/ServerConfiguration.cs | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 ProjectLighthouse/Configuration/ConfigurationCategories/MatchmakingConfiguration.cs diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs index 4059d37a..627cf21e 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs @@ -1,5 +1,6 @@ #nullable enable using System.Text.Json; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Helpers; @@ -42,6 +43,9 @@ public class MatchController : ControllerBase UserEntity? user = await this.database.UserFromGameToken(token); if (user == null) return this.Forbid(); + // Do not allow matchmaking if it has been disabled + if (!ServerConfiguration.Instance.Matchmaking.MatchmakingEnabled) return this.Forbid(); + #region Parse match data // Example POST /match: [UpdateMyPlayerData,["Player":"FireGamer9872"]] diff --git a/ProjectLighthouse/Configuration/ConfigurationCategories/MatchmakingConfiguration.cs b/ProjectLighthouse/Configuration/ConfigurationCategories/MatchmakingConfiguration.cs new file mode 100644 index 00000000..4e9debac --- /dev/null +++ b/ProjectLighthouse/Configuration/ConfigurationCategories/MatchmakingConfiguration.cs @@ -0,0 +1,6 @@ +namespace LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories; + +public class MatchmakingConfiguration +{ + public bool MatchmakingEnabled { get; set; } = true; +} \ No newline at end of file diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index d51d4ca2..7258804e 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; } = 24; + public override int ConfigVersion { get; set; } = 25; public override string ConfigName { get; set; } = "lighthouse.yml"; public string WebsiteListenUrl { get; set; } = "http://localhost:10060"; @@ -35,6 +35,7 @@ public class ServerConfiguration : ConfigurationBase public AuthenticationConfiguration Authentication { get; set; } = new(); public CaptchaConfiguration Captcha { get; set; } = new(); public DigestKeyConfiguration DigestKey { get; set; } = new(); + public MatchmakingConfiguration Matchmaking { get; set; } = new(); public GoogleAnalyticsConfiguration GoogleAnalytics { get; set; } = new(); public MailConfiguration Mail { get; set; } = new(); public UserGeneratedContentLimitConfiguration UserGeneratedContentLimits { get; set; } = new(); From be452270e3f8f17c47217b917b8ed692f3a36137 Mon Sep 17 00:00:00 2001 From: sudokoko Date: Sun, 17 Mar 2024 19:02:06 -0400 Subject: [PATCH 04/37] Return bad request instead of forbid when matchmaking is disabled Prevents the game client from reauthenticating every time it requests /match --- .../Controllers/Matching/MatchController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs index 627cf21e..ab18505e 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs @@ -44,7 +44,7 @@ public class MatchController : ControllerBase if (user == null) return this.Forbid(); // Do not allow matchmaking if it has been disabled - if (!ServerConfiguration.Instance.Matchmaking.MatchmakingEnabled) return this.Forbid(); + if (!ServerConfiguration.Instance.Matchmaking.MatchmakingEnabled) return this.BadRequest(); #region Parse match data From a9944ec74d9d3ed3bedd6da6808db096442202ef Mon Sep 17 00:00:00 2001 From: sudokoko Date: Sun, 17 Mar 2024 19:58:14 -0400 Subject: [PATCH 05/37] Fix issue where last contact isn't sent if matchmaking is disabled --- .../Controllers/Matching/MatchController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs index ab18505e..326ce3b9 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs @@ -43,6 +43,8 @@ public class MatchController : ControllerBase UserEntity? user = await this.database.UserFromGameToken(token); if (user == null) return this.Forbid(); + await LastContactHelper.SetLastContact(this.database, user, token.GameVersion, token.Platform); + // Do not allow matchmaking if it has been disabled if (!ServerConfiguration.Instance.Matchmaking.MatchmakingEnabled) return this.BadRequest(); @@ -79,8 +81,6 @@ public class MatchController : ControllerBase #endregion - await LastContactHelper.SetLastContact(this.database, user, token.GameVersion, token.Platform); - #region Process match data switch (matchData) From 52830015114431ffd34b6829c861b23993438b41 Mon Sep 17 00:00:00 2001 From: sudokoko Date: Sun, 17 Mar 2024 21:41:10 -0400 Subject: [PATCH 06/37] Remove IP addresses from game tokens and matchmaking --- .../Controllers/Login/LoginController.cs | 6 ++-- .../Controllers/Matching/MatchController.cs | 11 ++----- .../Controllers/MessageController.cs | 1 - .../Debug/RoomVisualizerController.cs | 7 ---- .../Pages/Debug/RoomVisualizerPage.cshtml | 8 ++--- ProjectLighthouse.Tests/Helpers/MockHelper.cs | 1 - .../Database/DatabaseContext.Utils.cs | 1 - ProjectLighthouse/Helpers/MatchHelper.cs | 7 ---- ProjectLighthouse/Helpers/RoomHelper.cs | 33 +++---------------- ...231145_RemoveUserLocationFromGameTokens.cs | 30 +++++++++++++++++ .../DatabaseContextModelSnapshot.cs | 5 +-- .../Types/Entities/Token/GameTokenEntity.cs | 2 -- .../Matchmaking/Rooms/FindBestRoomResponse.cs | 5 --- 13 files changed, 44 insertions(+), 73 deletions(-) create mode 100644 ProjectLighthouse/Migrations/20240317231145_RemoveUserLocationFromGameTokens.cs diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs index 8e3886a5..7a483463 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Login/LoginController.cs @@ -72,7 +72,7 @@ public class LoginController : ControllerBase switch (npTicket.Platform) { case Platform.RPCS3: - user = await this.database.Users.FirstOrDefaultAsync(u => u.LinkedRpcnId == npTicket.UserId); + user = await this.database.Users.FirstOrDefaultAsync(u => u.LinkedRpcnId == npTicket.UserId); break; case Platform.PS3: case Platform.Vita: @@ -88,7 +88,7 @@ public class LoginController : ControllerBase // If this user id hasn't been linked to any accounts if (user == null) { - // Check if there is an account with that username already + // Check if there is an account with that username already UserEntity? targetUsername = await this.database.Users.FirstOrDefaultAsync(u => u.Username == npTicket.Username); if (targetUsername != null) { @@ -175,7 +175,7 @@ public class LoginController : ControllerBase } GameTokenEntity? token = await this.database.GameTokens.Include(t => t.User) - .FirstOrDefaultAsync(t => t.UserLocation == ipAddress && t.User.Username == npTicket.Username && t.TicketHash == npTicket.TicketHash); + .FirstOrDefaultAsync(t => t.User.Username == npTicket.Username && t.TicketHash == npTicket.TicketHash); if (token != null) { diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs index 326ce3b9..2b3b295b 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Matching/MatchController.cs @@ -87,7 +87,6 @@ public class MatchController : ControllerBase { case UpdateMyPlayerData playerData: { - MatchHelper.SetUserLocation(user.UserId, token.UserLocation); Room? room = RoomHelper.FindRoomByUser(user.UserId, token.GameVersion, token.Platform, true); if (playerData.RoomState != null) @@ -95,19 +94,13 @@ public class MatchController : ControllerBase room.State = (RoomState)playerData.RoomState; break; } - // Check how many people are online in release builds, disabled for debug for ..well debugging. - #if DEBUG case FindBestRoom diveInData: - #else - case FindBestRoom diveInData when MatchHelper.UserLocations.Count > 1: - #endif { FindBestRoomResponse? response = RoomHelper.FindBestRoom(this.database, user, token.GameVersion, diveInData.RoomSlot, - token.Platform, - token.UserLocation); + token.Platform); if (response == null) return this.NotFound(); @@ -117,7 +110,7 @@ public class MatchController : ControllerBase return this.Ok($"[{{\"StatusCode\":200}},{serialized}]"); } - case CreateRoom createRoom when !MatchHelper.UserLocations.IsEmpty: + case CreateRoom createRoom: { List users = new(); foreach (string playerUsername in createRoom.Players) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs index df11efdd..3d3f16be 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs @@ -62,7 +62,6 @@ along with this program. If not, see ."; #if DEBUG announceText.Append("\n\n---DEBUG INFO---\n" + $"user.UserId: {token.UserId}\n" + - $"token.UserLocation: {token.UserLocation}\n" + $"token.GameVersion: {token.GameVersion}\n" + $"token.TicketHash: {token.TicketHash}\n" + $"token.ExpiresAt: {token.ExpiresAt.ToString()}\n" + diff --git a/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs b/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs index 547e38ca..20858b88 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/Debug/RoomVisualizerController.cs @@ -1,8 +1,5 @@ using LBPUnion.ProjectLighthouse.Database; -using LBPUnion.ProjectLighthouse.Helpers; -using LBPUnion.ProjectLighthouse.Types.Users; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; namespace LBPUnion.ProjectLighthouse.Servers.Website.Controllers.Debug; @@ -27,10 +24,6 @@ public class RoomVisualizerController : ControllerBase List users = await this.database.Users.OrderByDescending(_ => EF.Functions.Random()).Take(2).Select(u => u.UserId).ToListAsync(); RoomHelper.CreateRoom(users, GameVersion.LittleBigPlanet2, Platform.PS3); - foreach (int user in users) - { - MatchHelper.SetUserLocation(user, "127.0.0.1"); - } return this.Redirect("/debug/roomVisualizer"); #endif } diff --git a/ProjectLighthouse.Servers.Website/Pages/Debug/RoomVisualizerPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/Debug/RoomVisualizerPage.cshtml index af71ec13..f922d3e8 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Debug/RoomVisualizerPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Debug/RoomVisualizerPage.cshtml @@ -17,15 +17,15 @@ diff --git a/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs index 310386e7..b461d982 100644 --- a/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/SlotSettingsPage.cshtml.cs @@ -1,4 +1,5 @@ #nullable enable +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Helpers; @@ -25,6 +26,10 @@ public class SlotSettingsPage : BaseLayout if (!this.User.IsModerator && this.User != this.Slot.Creator) return this.Redirect("~/slot/" + slotId); + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + return this.Redirect($"~/slot/{slotId}"); + string? avatarHash = await FileHelper.ParseBase64Image(avatar); if (avatarHash != null) this.Slot.IconHash = avatarHash; @@ -46,7 +51,7 @@ public class SlotSettingsPage : BaseLayout if (labels != null) { labels = LabelHelper.RemoveInvalidLabels(labels); - if (this.Slot.AuthorLabels != labels) + if (this.Slot.AuthorLabels != labels) this.Slot.AuthorLabels = labels; } diff --git a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs index 066ca973..85b0c242 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/UserSettingsPage.cshtml.cs @@ -39,6 +39,10 @@ public class UserSettingsPage : BaseLayout if (!this.User.IsModerator && this.User != this.ProfileUser) return this.Redirect("~/user/" + userId); + // Deny request if in read-only mode + if (avatar != null && ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + return this.Redirect($"~/user/{userId}"); + string? avatarHash = await FileHelper.ParseBase64Image(avatar); if (avatarHash != null) this.ProfileUser.IconHash = avatarHash; @@ -47,6 +51,10 @@ public class UserSettingsPage : BaseLayout if (biography != null) { + // Deny request if in read-only mode + if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) + return this.Redirect($"~/user/{userId}"); + biography = CensorHelper.FilterMessage(biography); if (this.ProfileUser.Biography != biography && biography.Length <= 512) this.ProfileUser.Biography = biography; diff --git a/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs b/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs index 6430b754..f725c278 100644 --- a/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs +++ b/ProjectLighthouse/Configuration/ConfigurationCategories/UserGeneratedContentLimitConfiguration.cs @@ -11,6 +11,12 @@ public class UserGeneratedContentLimitConfiguration public int PhotosQuota { get; set; } = 500; + /// + /// When enabled, all UGC uploads are disabled. This includes levels, photos, reviews, + /// comments, and certain profile settings. + /// + public bool ReadOnlyMode { get; set; } = false; + public bool ProfileCommentsEnabled { get; set; } = true; public bool LevelCommentsEnabled { get; set; } = true; diff --git a/ProjectLighthouse/Configuration/ServerConfiguration.cs b/ProjectLighthouse/Configuration/ServerConfiguration.cs index 7258804e..30c7c89b 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; } = 25; + public override int ConfigVersion { get; set; } = 26; public override string ConfigName { get; set; } = "lighthouse.yml"; public string WebsiteListenUrl { get; set; } = "http://localhost:10060"; From da8322e01a3aa5b9533cbbdd8cd72c2cc0e56a8a Mon Sep 17 00:00:00 2001 From: sudokoko Date: Fri, 29 Mar 2024 23:17:01 -0400 Subject: [PATCH 18/37] Fix errant line breaks in landing page announcement view --- .../Pages/LandingPage.cshtml | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml index 9f9ba991..1414c642 100644 --- a/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/LandingPage.cshtml @@ -66,19 +66,14 @@

@Model.LatestAnnouncement.Title

- @if (Model.LatestAnnouncement.Content.Length > 250) - { - - @Model.LatestAnnouncement.Content[..250]... - read more - - } - else - { - - @Model.LatestAnnouncement.Content - - } + @if (Model.LatestAnnouncement.Content.Length > 250) + { + @Model.LatestAnnouncement.Content[..250]...read more + } + else + { + @Model.LatestAnnouncement.Content + }
@if (Model.LatestAnnouncement.Publisher != null) { From 81ec09041c410e50dcaa6f7272a74849e0fbdc12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 23:23:39 -0400 Subject: [PATCH 19/37] Update the localization files (#1006) [skip ci] Update the localization files Co-authored-by: Crowdin Bot --- ProjectLighthouse.Localization/BaseLayout.lang-ar-SA.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-da-DK.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-de-DE.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-en-PT.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-eo-UY.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-es-ES.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-es-MX.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-et-EE.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-fi-FI.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-fil-PH.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-fr-FR.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-ga-IE.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-he-IL.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-hi-IN.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-id-ID.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-it-IT.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-ja-JP.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-nl-NL.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-no-NO.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-pl-PL.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-pt-PT.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-ru-RU.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-sv-SE.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-th-TH.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-tr-TR.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-uk-UA.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-zh-CN.resx | 6 ++++++ ProjectLighthouse.Localization/BaseLayout.lang-zh-TW.resx | 6 ++++++ 28 files changed, 168 insertions(+) diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-ar-SA.resx b/ProjectLighthouse.Localization/BaseLayout.lang-ar-SA.resx index 93d2af66..840e788a 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-ar-SA.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-ar-SA.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-da-DK.resx b/ProjectLighthouse.Localization/BaseLayout.lang-da-DK.resx index e09dd9af..288b7fb7 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-da-DK.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-da-DK.resx @@ -80,4 +80,10 @@ Hvis ikke, bedes du publicere kildekoden et eller andet sted, der er tilgængeligt for dine brugere. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-de-DE.resx b/ProjectLighthouse.Localization/BaseLayout.lang-de-DE.resx index 23a346fc..c440b48b 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-de-DE.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-de-DE.resx @@ -80,4 +80,10 @@ Falls nicht, veröffentliche den Quellcode irgendwo, wo die Nutzer deiner Instanz darauf zugreifen können. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-en-PT.resx b/ProjectLighthouse.Localization/BaseLayout.lang-en-PT.resx index 5e95e70d..4b1ed6f2 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-en-PT.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-en-PT.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to yer users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-eo-UY.resx b/ProjectLighthouse.Localization/BaseLayout.lang-eo-UY.resx index 7f915877..33a44d35 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-eo-UY.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-eo-UY.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-es-ES.resx b/ProjectLighthouse.Localization/BaseLayout.lang-es-ES.resx index 605e6c1c..9e8054d3 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-es-ES.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-es-ES.resx @@ -80,4 +80,10 @@ Si no es así, por favor publique el código fuente en algún lugar accesible para sus usuarios. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-es-MX.resx b/ProjectLighthouse.Localization/BaseLayout.lang-es-MX.resx index 4a9f0504..e7ab8b50 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-es-MX.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-es-MX.resx @@ -80,4 +80,10 @@ De lo contrario, publique el código fuente en algún lugar accesible para sus usuarios. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-et-EE.resx b/ProjectLighthouse.Localization/BaseLayout.lang-et-EE.resx index e8afb535..018d7688 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-et-EE.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-et-EE.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-fi-FI.resx b/ProjectLighthouse.Localization/BaseLayout.lang-fi-FI.resx index 3f0769c7..010bee82 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-fi-FI.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-fi-FI.resx @@ -80,4 +80,10 @@ Jos ei, julkaise lähdekoodisi jonnekin, jossa se on käyttäjillesi saatavissa. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-fil-PH.resx b/ProjectLighthouse.Localization/BaseLayout.lang-fil-PH.resx index eeca3734..1f6d2f80 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-fil-PH.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-fil-PH.resx @@ -80,4 +80,10 @@ Kung hindi, mangyaring ilathala ang source code sa isang lugar na maaring ma-access ng iyong mga user. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-fr-FR.resx b/ProjectLighthouse.Localization/BaseLayout.lang-fr-FR.resx index 5799bbab..b6a13ce4 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-fr-FR.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-fr-FR.resx @@ -80,4 +80,10 @@ Dans le cas contraire, veuillez publier le code source dans un endroit accessible à vos utilisateurs. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-ga-IE.resx b/ProjectLighthouse.Localization/BaseLayout.lang-ga-IE.resx index e9c979f1..8d3faadf 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-ga-IE.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-ga-IE.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-he-IL.resx b/ProjectLighthouse.Localization/BaseLayout.lang-he-IL.resx index b8181267..4f227b17 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-he-IL.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-he-IL.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-hi-IN.resx b/ProjectLighthouse.Localization/BaseLayout.lang-hi-IN.resx index e8afb535..018d7688 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-hi-IN.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-hi-IN.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-id-ID.resx b/ProjectLighthouse.Localization/BaseLayout.lang-id-ID.resx index e8afb535..018d7688 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-id-ID.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-id-ID.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-it-IT.resx b/ProjectLighthouse.Localization/BaseLayout.lang-it-IT.resx index d0e7dc78..1bf4d272 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-it-IT.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-it-IT.resx @@ -80,4 +80,10 @@ In caso contrario, si prega di pubblicare il codice sorgente da qualche parte accessibile ai propri utenti. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-ja-JP.resx b/ProjectLighthouse.Localization/BaseLayout.lang-ja-JP.resx index 87a8f042..bd34f75a 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-ja-JP.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-ja-JP.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-nl-NL.resx b/ProjectLighthouse.Localization/BaseLayout.lang-nl-NL.resx index e8afb535..018d7688 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-nl-NL.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-nl-NL.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-no-NO.resx b/ProjectLighthouse.Localization/BaseLayout.lang-no-NO.resx index 2667ba27..7498eea4 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-no-NO.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-no-NO.resx @@ -80,4 +80,10 @@ Hvis ikke, vennligst publiser kildekoden et sted som er tilgjengelig for brukerne dine + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-pl-PL.resx b/ProjectLighthouse.Localization/BaseLayout.lang-pl-PL.resx index 3f3c3967..165ad1ea 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-pl-PL.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-pl-PL.resx @@ -80,4 +80,10 @@ Jeśli nie, proszę opublikować kod źródłowy dostępny dla użytkowników. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-pt-PT.resx b/ProjectLighthouse.Localization/BaseLayout.lang-pt-PT.resx index 542aaefe..acd98ae6 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-pt-PT.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-pt-PT.resx @@ -80,4 +80,10 @@ Se não for o caso, publique o código-fonte em um local acessível aos seus utilizadores. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-ru-RU.resx b/ProjectLighthouse.Localization/BaseLayout.lang-ru-RU.resx index 6885eef7..af911178 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-ru-RU.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-ru-RU.resx @@ -80,4 +80,10 @@ Если нет, пожалуйста, опубликуйте исходный код в доступном для ваших пользователей месте. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-sv-SE.resx b/ProjectLighthouse.Localization/BaseLayout.lang-sv-SE.resx index 5ea5b420..335728b0 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-sv-SE.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-sv-SE.resx @@ -80,4 +80,10 @@ Om inte, vänligen publicera källkoden någonstans tillgängligt för dina användare. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-th-TH.resx b/ProjectLighthouse.Localization/BaseLayout.lang-th-TH.resx index e8afb535..018d7688 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-th-TH.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-th-TH.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-tr-TR.resx b/ProjectLighthouse.Localization/BaseLayout.lang-tr-TR.resx index dad9985b..6fcea799 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-tr-TR.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-tr-TR.resx @@ -80,4 +80,10 @@ Eğer değilse, lütfen kaynak kodunu kullanıcılarınızın erişebileceği bir yerde yayınlayın. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-uk-UA.resx b/ProjectLighthouse.Localization/BaseLayout.lang-uk-UA.resx index 393240d3..02d46642 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-uk-UA.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-uk-UA.resx @@ -80,4 +80,10 @@ Якщо ні, будь ласка, опублікуйте вихідний код у місці, доступному для ваших користувачів. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-zh-CN.resx b/ProjectLighthouse.Localization/BaseLayout.lang-zh-CN.resx index b93490ef..5911daf5 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-zh-CN.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-zh-CN.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file diff --git a/ProjectLighthouse.Localization/BaseLayout.lang-zh-TW.resx b/ProjectLighthouse.Localization/BaseLayout.lang-zh-TW.resx index 39f48810..865dd50a 100644 --- a/ProjectLighthouse.Localization/BaseLayout.lang-zh-TW.resx +++ b/ProjectLighthouse.Localization/BaseLayout.lang-zh-TW.resx @@ -80,4 +80,10 @@ If not, please publish the source code somewhere accessible to your users. + + Read-Only Mode + + + 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. + \ No newline at end of file From e8441c134bb890162997ceb2fe8d47224a4d2a51 Mon Sep 17 00:00:00 2001 From: Ren <96893300+ren-makes-things@users.noreply.github.com> Date: Fri, 29 Mar 2024 21:36:19 -0700 Subject: [PATCH 20/37] Use Actions to build and publish Docker images to Github Container Registry (#1004) * Create docker-publish.yml * Update docker-publish.yml * Now this should work GitHub's own template is a little out of date, had to accommodate for this https://github.com/actions/starter-workflows/issues/2357 * updating to actions/checkout@v4 * Update docker-publish.yml * Update do Co-authored-by: sudokoko * Update docker-publish.yml Co-authored-by: sudokoko * testing arm building Co-authored-by: Zaprit * an attempt to get this docker workflow to play nice with arm * Revert "testing arm building" This reverts commit a030b62f73cf219d78e83000b7e58b5aa69d7f76. * Revert "an attempt to get this docker workflow to play nice with arm" This reverts commit 8faf3f4a5a6b3b1cf0981d5501856f2cafdb68e5. * Minor nitpicky things before merge Committing these directly as to not bother you with another code review. Adds a nice-name to the job and renames "build" to "build-publish". --------- Co-authored-by: sudokoko Co-authored-by: Zaprit --- .github/workflows/docker-publish.yml | 89 ++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/docker-publish.yml diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 00000000..f0536400 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,89 @@ +name: Build Docker Image + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build-publish: + name: Build and Publish + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Install the cosign tool except on PR + # https://github.com/sigstore/cosign-installer + - name: Install cosign + if: github.event_name != 'pull_request' + uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 #v3.4.0 + with: + cosign-release: 'v2.2.3' + + # Set up BuildKit Docker container builder to be able to build + # multi-platform images and export cache + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # Sign the resulting Docker image digest except on PRs. + # This will only write to the public Rekor transparency log when the Docker + # repository is public to avoid leaking data. If you would like to publish + # transparency data even for private images, pass --force to cosign below. + # https://github.com/sigstore/cosign + - name: Sign the published Docker image + if: ${{ github.event_name != 'pull_request' }} + env: + # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable + TAGS: ${{ steps.meta.outputs.tags }} + DIGEST: ${{ steps.build-and-push.outputs.digest }} + # This step uses the identity token to provision an ephemeral certificate + # against the sigstore community Fulcio instance. + run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} From 931f0792657214d81b7bf7cf3496613d3e1a74bb Mon Sep 17 00:00:00 2001 From: sudokoko Date: Sat, 30 Mar 2024 15:04:48 -0400 Subject: [PATCH 21/37] Append line breaks after read only mode warning in announce text --- .../Controllers/MessageController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs index 4666366f..26ae10ac 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/MessageController.cs @@ -63,7 +63,7 @@ along with this program. If not, see ."; if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) { - announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang)); + announceText.Insert(0, BaseLayoutStrings.ReadOnlyWarn.Translate(LocalizationManager.DefaultLang) + "\n\n"); } #if DEBUG From 67d0d3d7b149eb0fecd1db0f3e1e098c9c95ae0f Mon Sep 17 00:00:00 2001 From: sudokoko Date: Fri, 5 Apr 2024 09:54:03 -0400 Subject: [PATCH 22/37] Prevent duplicate profile pins --- .../Controllers/UserController.cs | 2 +- .../Unit/Controllers/UserControllerTests.cs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs index cbed989b..7019cdd7 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/UserController.cs @@ -180,7 +180,7 @@ public class UserController : ControllerBase // Sometimes the update gets called periodically as pin progress updates via playing, // may not affect equipped profile pins however, so check before setting it. string currentPins = user.Pins; - string newPins = string.Join(",", pinJson.ProfilePins); + string newPins = string.Join(",", pinJson.ProfilePins.Distinct()); if (string.Equals(currentPins, newPins)) return this.Ok("[{\"StatusCode\":200}]"); diff --git a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/UserControllerTests.cs b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/UserControllerTests.cs index e7228b2c..3347db1e 100644 --- a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/UserControllerTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/UserControllerTests.cs @@ -177,4 +177,29 @@ public class UserControllerTests Assert.Equal(expectedPins, dbMock.Users.First().Pins); Assert.Equal(expectedResponse, pinsResponse); } + + [Fact] + public async Task UpdateMyPins_ShouldRemove_DuplicatePins() + { + UserEntity entity = MockHelper.GetUnitTestUser(); + entity.Pins = "1234"; + List users = new() + { + entity, + }; + await using DatabaseContext dbMock = await MockHelper.GetTestDatabase(users); + + UserController userController = new(dbMock); + userController.SetupTestController("{\"profile_pins\": [1234, 1234]}"); + + const string expectedPins = "1234"; + const string expectedResponse = "[{\"StatusCode\":200}]"; + + IActionResult result = await userController.UpdateMyPins(); + + string pinsResponse = result.CastTo(); + + Assert.Equal(expectedPins, dbMock.Users.First().Pins); + Assert.Equal(expectedResponse, pinsResponse); + } } \ No newline at end of file From 9348d581584206924b9c24915f4fe0a0fe643192 Mon Sep 17 00:00:00 2001 From: Slendy Date: Mon, 15 Apr 2024 14:11:47 -0500 Subject: [PATCH 23/37] Fix infinite redirect for users with empty usernames --- ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml.cs index 64bfb501..05cb5671 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml.cs +++ b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml.cs @@ -45,7 +45,8 @@ public class UserPage : BaseLayout if (this.ProfileUser == null) return this.NotFound(); string userSlug = this.ProfileUser.GenerateSlug(); - if (slug == null || userSlug != slug) + // Only redirect if there is a valid slug for this user and the current slug doesn't match + if (!string.IsNullOrWhiteSpace(userSlug) && (slug == null || userSlug != slug)) { return this.Redirect($"~/user/{userId}/{userSlug}"); } From 0ce748de8f6efb9f88cf8f846a0dad36f20db300 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 23:30:25 -0500 Subject: [PATCH 24/37] Bump SixLabors.ImageSharp from 3.1.3 to 3.1.4 in /ProjectLighthouse (#1012) Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/SixLabors/ImageSharp/releases) - [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.3...v3.1.4) --- updated-dependencies: - dependency-name: SixLabors.ImageSharp dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ProjectLighthouse/ProjectLighthouse.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index 44c92348..bc92bc90 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From ed5bb5d76954d0fe88625b5f5b8e8ed73602191a Mon Sep 17 00:00:00 2001 From: Josh Date: Sun, 28 Apr 2024 20:44:41 -0500 Subject: [PATCH 25/37] Prevent LBP3 reviews from showing up in LBP2 (#1015) --- .../Controllers/Slots/ReviewController.cs | 14 +++ .../Unit/Controllers/ReviewControllerTests.cs | 99 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs index 7feae4bf..0dd54c07 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ReviewController.cs @@ -157,6 +157,13 @@ public class ReviewController : ControllerBase List reviews = (await this.database.Reviews .Where(r => r.SlotId == slotId) + .Select(r => new + { + Review = r, + SlotVersion = r.Slot!.GameVersion, + }) + .Where(a => a.SlotVersion <= token.GameVersion) + .Select(a => a.Review) .OrderByDescending(r => r.ThumbsUp - r.ThumbsDown) .ThenByDescending(r => r.Timestamp) .ApplyPagination(pageData) @@ -178,6 +185,13 @@ public class ReviewController : ControllerBase List reviews = (await this.database.Reviews .Where(r => r.ReviewerId == targetUserId) + .Select(r => new + { + Review = r, + SlotVersion = r.Slot!.GameVersion, + }) + .Where(a => a.SlotVersion <= token.GameVersion) + .Select(a => a.Review) .OrderByDescending(r => r.Timestamp) .ApplyPagination(pageData) .ToListAsync()).ToSerializableList(r => GameReview.CreateFromEntity(r, token)); diff --git a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs new file mode 100644 index 00000000..303b4f85 --- /dev/null +++ b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Database; +using LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers.Slots; +using LBPUnion.ProjectLighthouse.Tests.Helpers; +using LBPUnion.ProjectLighthouse.Types.Entities.Level; +using LBPUnion.ProjectLighthouse.Types.Entities.Token; +using LBPUnion.ProjectLighthouse.Types.Serialization; +using LBPUnion.ProjectLighthouse.Types.Users; +using Microsoft.AspNetCore.Mvc; +using Xunit; + +namespace ProjectLighthouse.Tests.GameApiTests.Unit.Controllers; + +public class ReviewControllerTests +{ + private static async Task InsertTestData(DatabaseContext database) + { + database.Slots.Add(new SlotEntity + { + SlotId = 1, + CreatorId = 1, + GameVersion = GameVersion.LittleBigPlanet3, + }); + + database.Slots.Add(new SlotEntity + { + SlotId = 2, + CreatorId = 1, + GameVersion = GameVersion.LittleBigPlanet2, + }); + + database.Reviews.Add(new ReviewEntity + { + ReviewId = 1, + ReviewerId = 1, + SlotId = 1, + }); + + database.Reviews.Add(new ReviewEntity + { + ReviewId = 2, + ReviewerId = 1, + SlotId = 2, + }); + await database.SaveChangesAsync(); + } + + [Theory] + [InlineData(GameVersion.LittleBigPlanet2, 1)] + [InlineData(GameVersion.LittleBigPlanet3, 2)] + public async Task ReviewsBy_ShouldNotList_HigherGameVersions(GameVersion version, int expected) + { + GameTokenEntity token = MockHelper.GetUnitTestToken(); + token.GameVersion = version; + DatabaseContext database = await MockHelper.GetTestDatabase(new List + { + token, + }); + + await InsertTestData(database); + + ReviewController controller = new(database); + controller.SetupTestController(token); + + IActionResult response = await controller.ReviewsBy("unittest"); + ReviewResponse review = response.CastTo(); + + Assert.Equal(expected, review.Reviews.Count); + Assert.True(review.Reviews.All(r => database.Slots.FirstOrDefault(s => s.SlotId == r.Slot.SlotId)?.GameVersion <= version)); + } + + [Theory] + [InlineData(GameVersion.LittleBigPlanet2, 2, 1)] + [InlineData(GameVersion.LittleBigPlanet2, 1, 0)] + [InlineData(GameVersion.LittleBigPlanet3, 2, 1)] + [InlineData(GameVersion.LittleBigPlanet3, 1, 1)] + public async Task ReviewsFor_ShouldNotList_HigherGameVersions(GameVersion version, int slotId, int expected) + { + GameTokenEntity token = MockHelper.GetUnitTestToken(); + token.GameVersion = version; + DatabaseContext database = await MockHelper.GetTestDatabase(new List + { + token, + }); + + await InsertTestData(database); + + ReviewController controller = new(database); + controller.SetupTestController(token); + + IActionResult response = await controller.ReviewsFor(slotId); + ReviewResponse review = response.CastTo(); + + Assert.Equal(expected, review.Reviews.Count); + Assert.True(review.Reviews.All(r => database.Slots.FirstOrDefault(s => s.SlotId == r.Slot.SlotId)?.GameVersion <= version)); + } +} \ No newline at end of file From 9e84e468442f4522cd173b0f8b261384fb37a442 Mon Sep 17 00:00:00 2001 From: Slendy Date: Sat, 11 May 2024 17:58:48 -0500 Subject: [PATCH 26/37] Add custom ToString method for NPTicket section header --- ProjectLighthouse/Tickets/TicketReader.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ProjectLighthouse/Tickets/TicketReader.cs b/ProjectLighthouse/Tickets/TicketReader.cs index ee6b1a70..697a72a1 100644 --- a/ProjectLighthouse/Tickets/TicketReader.cs +++ b/ProjectLighthouse/Tickets/TicketReader.cs @@ -33,6 +33,9 @@ public struct SectionHeader public SectionType Type; public ushort Length; public int Position; + + public override string ToString() => + $"SectionHeader(Type='{this.Type}', Length='{this.Length}', Position='{this.Position}')"; } public class TicketReader : BinaryReader From 262ada37aed61d49944fb26fb0e227712a909524 Mon Sep 17 00:00:00 2001 From: sudokoko Date: Fri, 31 May 2024 13:53:41 -0400 Subject: [PATCH 27/37] Bump dependencies --- .config/dotnet-tools.json | 2 +- .../ProjectLighthouse.Servers.Website.csproj | 2 +- ...rojectLighthouse.Tests.GameApiTests.csproj | 10 +++++----- ...rojectLighthouse.Tests.WebsiteTests.csproj | 14 ++++++------- .../ProjectLighthouse.Tests.csproj | 12 +++++------ ProjectLighthouse.sln.DotSettings | 8 +++++++- ProjectLighthouse/ProjectLighthouse.csproj | 20 +++++++++---------- 7 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index a1b89d98..7217a983 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "8.0.3", + "version": "8.0.6", "commands": [ "dotnet-ef" ] diff --git a/ProjectLighthouse.Servers.Website/ProjectLighthouse.Servers.Website.csproj b/ProjectLighthouse.Servers.Website/ProjectLighthouse.Servers.Website.csproj index 9749d85c..7768663f 100644 --- a/ProjectLighthouse.Servers.Website/ProjectLighthouse.Servers.Website.csproj +++ b/ProjectLighthouse.Servers.Website/ProjectLighthouse.Servers.Website.csproj @@ -11,6 +11,6 @@ - + diff --git a/ProjectLighthouse.Tests.GameApiTests/ProjectLighthouse.Tests.GameApiTests.csproj b/ProjectLighthouse.Tests.GameApiTests/ProjectLighthouse.Tests.GameApiTests.csproj index db0ead10..ef720919 100644 --- a/ProjectLighthouse.Tests.GameApiTests/ProjectLighthouse.Tests.GameApiTests.csproj +++ b/ProjectLighthouse.Tests.GameApiTests/ProjectLighthouse.Tests.GameApiTests.csproj @@ -9,14 +9,14 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj b/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj index 0686a1d3..c5b336f5 100644 --- a/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj +++ b/ProjectLighthouse.Tests.WebsiteTests/ProjectLighthouse.Tests.WebsiteTests.csproj @@ -9,16 +9,16 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj b/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj index 4eb6d411..4c4199a9 100644 --- a/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj +++ b/ProjectLighthouse.Tests/ProjectLighthouse.Tests.csproj @@ -14,14 +14,14 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -30,7 +30,7 @@ all - + diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index d3818928..174ff7a3 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -1,4 +1,6 @@ - + True False False @@ -96,10 +98,14 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Methods"><ElementKinds><Kind Name="METHOD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy></Policy> True True True True + True True True True diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index bc92bc90..c538b220 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -10,31 +10,31 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - + + + - + From 643cb8e816b33a959c4cd2778e5caf2ae03109ee Mon Sep 17 00:00:00 2001 From: sudokoko Date: Fri, 31 May 2024 18:10:05 -0400 Subject: [PATCH 28/37] Implement the ability to forcibly verify a user's email (#1022) * Implement the ability to forcibly verify a user's email * Apply suggestions from code review --- .../Controllers/Admin/AdminUserController.cs | 26 +++++++++++++++++++ .../Pages/UserPage.cshtml | 8 ++++++ 2 files changed, 34 insertions(+) diff --git a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs index 84b024ff..42626944 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs @@ -3,6 +3,7 @@ using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Files; 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.Moderation.Cases; using LBPUnion.ProjectLighthouse.Types.Users; @@ -91,6 +92,31 @@ public class AdminUserController : ControllerBase return this.Redirect($"/user/{targetedUser.UserId}"); } + /// + /// Forces the email verification of a user. + /// + [HttpGet("forceVerifyEmail")] + public async Task ForceVerifyEmail([FromRoute] int id) + { + UserEntity? user = this.database.UserFromWebRequest(this.Request); + if (user == null || !user.IsModerator) return this.NotFound(); + + UserEntity? targetedUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); + if (targetedUser == null) return this.NotFound(); + if (user.EmailAddressVerified) return this.NotFound(); + + List tokens = await this.database.EmailVerificationTokens + .Where(t => t.UserId == targetedUser.UserId) + .ToListAsync(); + this.database.EmailVerificationTokens.RemoveRange(tokens); + + targetedUser.EmailAddressVerified = true; + + await this.database.SaveChangesAsync(); + + return this.Redirect($"/user/{targetedUser.UserId}"); + } + [HttpPost("/admin/user/{id:int}/setPermissionLevel")] public async Task SetUserPermissionLevel([FromRoute] int id, [FromForm] PermissionLevel role) { diff --git a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml index d675e8c1..e1b6fe78 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml @@ -333,6 +333,14 @@ else } + @if (!Model.ProfileUser.EmailAddressVerified) + { + + + Force Verify Email + + } + @if (Model.User.IsAdmin) {
From 3546f60f4f9bc7abc031bd4e5809e862b0ee7025 Mon Sep 17 00:00:00 2001 From: sudokoko Date: Fri, 31 May 2024 18:26:08 -0400 Subject: [PATCH 29/37] Disallow forced email verification of users with no email --- .../Controllers/Admin/AdminUserController.cs | 2 +- ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs index 42626944..0aada8fc 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs @@ -103,7 +103,7 @@ public class AdminUserController : ControllerBase UserEntity? targetedUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); if (targetedUser == null) return this.NotFound(); - if (user.EmailAddressVerified) return this.NotFound(); + if (user.EmailAddress == null || user.EmailAddressVerified) return this.NotFound(); List tokens = await this.database.EmailVerificationTokens .Where(t => t.UserId == targetedUser.UserId) diff --git a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml index e1b6fe78..33a07af1 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml @@ -333,11 +333,11 @@ else } - @if (!Model.ProfileUser.EmailAddressVerified) + @if (Model.ProfileUser.EmailAddress != null && !Model.ProfileUser.EmailAddressVerified) { - Force Verify Email + Forcibly Verify Email } From e89a4c27fad0ec9015173e59fc957197a08c76c5 Mon Sep 17 00:00:00 2001 From: sudokoko Date: Fri, 31 May 2024 18:40:39 -0400 Subject: [PATCH 30/37] Fix mismatch between user/targetedUser in force verify endpoint --- .../Controllers/Admin/AdminUserController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs index 0aada8fc..d4fdfaf8 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs @@ -103,7 +103,7 @@ public class AdminUserController : ControllerBase UserEntity? targetedUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); if (targetedUser == null) return this.NotFound(); - if (user.EmailAddress == null || user.EmailAddressVerified) return this.NotFound(); + if (targetedUser.EmailAddress == null || targetedUser.EmailAddressVerified) return this.NotFound(); List tokens = await this.database.EmailVerificationTokens .Where(t => t.UserId == targetedUser.UserId) From be11e138f032ec306f9c732b4a3a3cee47740edc Mon Sep 17 00:00:00 2001 From: Kat <30480654+Metraberryy@users.noreply.github.com> Date: Fri, 14 Jun 2024 19:27:18 -0700 Subject: [PATCH 31/37] Implement the ability for moderators to delete all scores/comments by a user (#1027) * Implement delete all scores/comments * Fix formatting in AdminUserController.cs * Move logging out of loop * Batch delete scores based on UserId * Batch update comments instead of using a foreach * Use html entity instead of apostrophe character * Confirm before deleting all comments/scores * Remove unnecessary database.SaveChanges --- .../Controllers/Admin/AdminUserController.cs | 52 ++++++++++++++++++- .../Pages/UserPage.cshtml | 12 +++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs index d4fdfaf8..55db420c 100644 --- a/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs +++ b/ProjectLighthouse.Servers.Website/Controllers/Admin/AdminUserController.cs @@ -1,7 +1,9 @@ #nullable enable using LBPUnion.ProjectLighthouse.Database; +using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Logging; +using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Logging; @@ -27,7 +29,8 @@ public class AdminUserController : ControllerBase /// Resets the user's earth decorations to a blank state. Useful for users who abuse audio for example. /// [HttpGet("wipePlanets")] - public async Task WipePlanets([FromRoute] int id) { + public async Task WipePlanets([FromRoute] int id) + { UserEntity? user = this.database.UserFromWebRequest(this.Request); if (user == null || !user.IsModerator) return this.NotFound(); @@ -91,6 +94,53 @@ public class AdminUserController : ControllerBase return this.Redirect($"/user/{targetedUser.UserId}"); } + + /// + /// Deletes every comment by the user. Useful in case of mass spam + /// + [HttpGet("wipeComments")] + public async Task WipeComments([FromRoute] int id) + { + UserEntity? user = this.database.UserFromWebRequest(this.Request); + if (user == null || !user.IsModerator) return this.NotFound(); + + UserEntity? targetedUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); + if (targetedUser == null) return this.NotFound(); + + // Find every comment by the user, then set the deletion info on them + await this.database.Comments.Where(c => c.PosterUserId == targetedUser.UserId) + .ExecuteUpdateAsync(s => + s.SetProperty(c => c.Deleted, true) + .SetProperty(c => c.DeletedBy, user.Username) + .SetProperty(c => c.DeletedType, "moderator")); + Logger.Success($"Deleted comments for {targetedUser.Username} (id:{targetedUser.UserId})", LogArea.Admin); + + await this.database.SendNotification(targetedUser.UserId, + "Your comments have been deleted by a moderator."); + + return this.Redirect($"/user/{targetedUser.UserId}"); + } + + /// + /// Deletes every score from the user. Useful in the case where a user cheated a ton of scores + /// + [HttpGet("wipeScores")] + public async Task WipeScores([FromRoute] int id) + { + UserEntity? user = this.database.UserFromWebRequest(this.Request); + if (user == null || !user.IsModerator) return this.NotFound(); + + UserEntity? targetedUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); + if (targetedUser == null) return this.NotFound(); + + // Find and delete every score uploaded by the target user + await this.database.Scores.Where(c => c.UserId == targetedUser.UserId).ExecuteDeleteAsync(); + Logger.Success($"Deleted scores for {targetedUser.Username} (id:{targetedUser.UserId})", LogArea.Admin); + + await this.database.SendNotification(targetedUser.UserId, "Your scores have been deleted by a moderator."); + + return this.Redirect($"/user/{targetedUser.UserId}"); + } /// /// Forces the email verification of a user. diff --git a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml index 33a07af1..98c23fcd 100644 --- a/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/UserPage.cshtml @@ -324,6 +324,18 @@ else Wipe Earth Decorations + + + + Wipe User's Comments + + + + + Wipe User's Scores + @if (!Model.CommentsDisabledByModerator) { From 0fd76f16621929da947de3dce0316351b0045fa2 Mon Sep 17 00:00:00 2001 From: jackcaver <50882080+jackcaver@users.noreply.github.com> Date: Sun, 23 Jun 2024 07:38:59 +0600 Subject: [PATCH 32/37] Remove license check (#1035) * remove license check * removed IsDirty --------- Co-authored-by: jackcaver --- .../Pages/Debug/VersionInfoPage.cshtml | 1 - .../Pages/Layouts/BaseLayout.cshtml | 24 ------------------- ProjectLighthouse/Helpers/VersionHelper.cs | 1 - ProjectLighthouse/StartupTasks.cs | 6 ----- 4 files changed, 32 deletions(-) diff --git a/ProjectLighthouse.Servers.Website/Pages/Debug/VersionInfoPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/Debug/VersionInfoPage.cshtml index d8eff2a4..f5bec53d 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Debug/VersionInfoPage.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Debug/VersionInfoPage.cshtml @@ -14,5 +14,4 @@

Branch: @VersionHelper.Branch

Build: @VersionHelper.Build

CommitHash: @VersionHelper.CommitHash

-

IsDirty: @VersionHelper.IsDirty

RepositoryUrl: @VersionHelper.RepositoryUrl

\ No newline at end of file diff --git a/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml b/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml index 14f14782..725b5945 100644 --- a/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml +++ b/ProjectLighthouse.Servers.Website/Pages/Layouts/BaseLayout.cshtml @@ -158,26 +158,6 @@
- @if (!ServerStatics.IsDebug() && VersionHelper.IsDirty) - { -
-
- - @Model.Translate(BaseLayoutStrings.LicenseWarnTitle) -

- @Html.Raw(Model.Translate(BaseLayoutStrings.LicenseWarn1, - "GNU Affero General Public License v3.0")) -

-

- @Html.Raw(Model.Translate(BaseLayoutStrings.LicenseWarn2, - "git status", "", "")) -

-

- @Html.Raw(Model.Translate(BaseLayoutStrings.LicenseWarn3)) -

-
-
- } @if (ServerConfiguration.Instance.UserGeneratedContentLimits.ReadOnlyMode) {
@@ -234,10 +214,6 @@ Cannot Detect Source Code } - @if (VersionHelper.IsDirty) - { -

@Model.Translate(BaseLayoutStrings.GeneratedModified)

- }
@if (ServerStatics.IsDebug()) diff --git a/ProjectLighthouse/Helpers/VersionHelper.cs b/ProjectLighthouse/Helpers/VersionHelper.cs index 895c36f7..f6c07003 100644 --- a/ProjectLighthouse/Helpers/VersionHelper.cs +++ b/ProjectLighthouse/Helpers/VersionHelper.cs @@ -19,7 +19,6 @@ public static class VersionHelper public static string EnvVer => $"{ServerConfiguration.Instance.Customization.EnvironmentName} {FullRevision}"; public static string FullVersion => $"Project Lighthouse {ServerConfiguration.Instance.Customization.EnvironmentName} {Branch}@{CommitHash} {Build}"; - public static bool IsDirty => ThisAssembly.Git.IsDirty; public static string RepositoryUrl => ThisAssembly.Git.RepositoryUrl; public const string Build = diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs index 6777b510..ec1730eb 100644 --- a/ProjectLighthouse/StartupTasks.cs +++ b/ProjectLighthouse/StartupTasks.cs @@ -53,12 +53,6 @@ public static class StartupTasks // Version info depends on ServerConfig Logger.Info($"You are running version {VersionHelper.FullVersion}", LogArea.Startup); - if (VersionHelper.IsDirty) - { - Logger.Warn("This is a modified version of Project Lighthouse. " + - "Please make sure you are properly disclosing the source code to any users who may be using this instance.", - LogArea.Startup); - } Logger.Info("Connecting to the database...", LogArea.Startup); From 7fbfd618be0ec629e1e474263bb1e3d35f9ed7f6 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 25 Jun 2024 04:18:43 -0500 Subject: [PATCH 33/37] Merge pull request from GHSA-8q42-63xx-75pf --- .../Startup/TokenAuthHandler.cs | 17 +- .../Database/DatabaseContext.Utils.cs | 1 + ...240625004457_AddLocationHashToGameToken.cs | 598 ++++++++++++++++++ .../DatabaseContextModelSnapshot.cs | 72 ++- ProjectLighthouse/Tickets/NPTicket.cs | 2 +- .../Types/Entities/Token/GameTokenEntity.cs | 4 + 6 files changed, 687 insertions(+), 7 deletions(-) create mode 100644 ProjectLighthouse/Migrations/20240625004457_AddLocationHashToGameToken.cs diff --git a/ProjectLighthouse.Servers.GameServer/Startup/TokenAuthHandler.cs b/ProjectLighthouse.Servers.GameServer/Startup/TokenAuthHandler.cs index 02760bce..cc97b80f 100644 --- a/ProjectLighthouse.Servers.GameServer/Startup/TokenAuthHandler.cs +++ b/ProjectLighthouse.Servers.GameServer/Startup/TokenAuthHandler.cs @@ -1,6 +1,8 @@ -using System.Security.Claims; +using System.Net; +using System.Security.Claims; using System.Text.Encodings.Web; using LBPUnion.ProjectLighthouse.Database; +using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Types.Entities.Token; using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging.Abstractions; @@ -36,10 +38,17 @@ public class TokenAuthHandler : AuthenticationHandler + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "TokenId", + table: "WebTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "AnnouncementId", + table: "WebsiteAnnouncements", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "VisitedLevelId", + table: "VisitedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "Users", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "SlotId", + table: "Slots", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "ScoreId", + table: "Scores", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "ReviewId", + table: "Reviews", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "ReportId", + table: "Reports", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "RegistrationTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "RatedReviewId", + table: "RatedReviews", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "RatedLevelId", + table: "RatedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "RatingId", + table: "RatedComments", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "QueuedLevelId", + table: "QueuedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PlaylistId", + table: "Playlists", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PlatformLinkAttemptId", + table: "PlatformLinkAttempts", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PhotoSubjectId", + table: "PhotoSubjects", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PhotoId", + table: "Photos", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "PasswordResetTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Notifications", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "HeartedProfileId", + table: "HeartedProfiles", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "HeartedPlaylistId", + table: "HeartedPlaylists", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "HeartedLevelId", + table: "HeartedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "TicketHash", + table: "GameTokens", + type: "varchar(64)", + maxLength: 64, + nullable: true, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "GameTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AddColumn( + name: "LocationHash", + table: "GameTokens", + type: "varchar(64)", + maxLength: 64, + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "EmailVerificationTokenId", + table: "EmailVerificationTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "EmailSetTokenId", + table: "EmailSetTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "CategoryId", + table: "CustomCategories", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "CommentId", + table: "Comments", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "CaseId", + table: "Cases", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "BlockedProfileId", + table: "BlockedProfiles", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "Id", + table: "APIKeys", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "LocationHash", + table: "GameTokens"); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "WebTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "AnnouncementId", + table: "WebsiteAnnouncements", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "VisitedLevelId", + table: "VisitedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "Users", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "SlotId", + table: "Slots", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "ScoreId", + table: "Scores", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "ReviewId", + table: "Reviews", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "ReportId", + table: "Reports", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "RegistrationTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "RatedReviewId", + table: "RatedReviews", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "RatedLevelId", + table: "RatedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "RatingId", + table: "RatedComments", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "QueuedLevelId", + table: "QueuedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PlaylistId", + table: "Playlists", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PlatformLinkAttemptId", + table: "PlatformLinkAttempts", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PhotoSubjectId", + table: "PhotoSubjects", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "PhotoId", + table: "Photos", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "PasswordResetTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Notifications", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "HeartedProfileId", + table: "HeartedProfiles", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "HeartedPlaylistId", + table: "HeartedPlaylists", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "HeartedLevelId", + table: "HeartedLevels", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "TicketHash", + table: "GameTokens", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "varchar(64)", + oldMaxLength: 64, + oldNullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "TokenId", + table: "GameTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "EmailVerificationTokenId", + table: "EmailVerificationTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "EmailSetTokenId", + table: "EmailSetTokens", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "CategoryId", + table: "CustomCategories", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "CommentId", + table: "Comments", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "CaseId", + table: "Cases", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "BlockedProfileId", + table: "BlockedProfiles", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + + migrationBuilder.AlterColumn( + name: "Id", + table: "APIKeys", + type: "int", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseContextModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseContextModelSnapshot.cs index 34e58686..6c801706 100644 --- a/ProjectLighthouse/Migrations/DatabaseContextModelSnapshot.cs +++ b/ProjectLighthouse/Migrations/DatabaseContextModelSnapshot.cs @@ -3,6 +3,7 @@ using System; using LBPUnion.ProjectLighthouse.Database; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; #nullable disable @@ -16,15 +17,19 @@ namespace ProjectLighthouse.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("ProductVersion", "8.0.6") .HasAnnotation("Relational:MaxIdentifierLength", 64); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Entities.Interaction.HeartedLevelEntity", b => { b.Property("HeartedLevelId") .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("HeartedLevelId")); + b.Property("SlotId") .HasColumnType("int"); @@ -46,6 +51,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("HeartedPlaylistId")); + b.Property("PlaylistId") .HasColumnType("int"); @@ -67,6 +74,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("HeartedProfileId")); + b.Property("HeartedUserId") .HasColumnType("int"); @@ -88,6 +97,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("QueuedLevelId")); + b.Property("SlotId") .HasColumnType("int"); @@ -109,6 +120,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("RatingId")); + b.Property("CommentId") .HasColumnType("int"); @@ -133,6 +146,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("RatedLevelId")); + b.Property("Rating") .HasColumnType("int"); @@ -163,6 +178,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("RatedReviewId")); + b.Property("ReviewId") .HasColumnType("int"); @@ -187,6 +204,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("VisitedLevelId")); + b.Property("PlaysLBP1") .HasColumnType("int"); @@ -217,6 +236,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("CategoryId")); + b.Property("Description") .HasColumnType("longtext"); @@ -243,6 +264,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PlaylistId")); + b.Property("CreatorId") .HasColumnType("int"); @@ -271,6 +294,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReviewId")); + b.Property("Deleted") .HasColumnType("tinyint(1)"); @@ -318,6 +343,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ScoreId")); + b.Property("ChildSlotId") .HasColumnType("int"); @@ -351,6 +378,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("SlotId")); + b.Property("AuthorLabels") .IsRequired() .HasColumnType("longtext"); @@ -504,6 +533,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("ReportId")); + b.Property("Bounds") .HasColumnType("longtext"); @@ -550,6 +581,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("CaseId")); + b.Property("AffectedId") .HasColumnType("int"); @@ -604,6 +637,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("IsDismissed") .HasColumnType("tinyint(1)"); @@ -629,6 +664,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("BlockedProfileId")); + b.Property("BlockedUserId") .HasColumnType("int"); @@ -650,6 +687,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("CommentId")); + b.Property("Deleted") .HasColumnType("tinyint(1)"); @@ -719,6 +758,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PhotoId")); + b.Property("CreatorId") .HasColumnType("int"); @@ -759,6 +800,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PhotoSubjectId")); + b.Property("Bounds") .HasColumnType("longtext"); @@ -783,6 +826,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("PlatformLinkAttemptId")); + b.Property("IPAddress") .HasColumnType("longtext"); @@ -811,6 +856,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("UserId")); + b.Property("AdminGrantedSlots") .HasColumnType("int"); @@ -916,6 +963,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Created") .HasColumnType("datetime(6)"); @@ -936,6 +985,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("EmailSetTokenId")); + b.Property("EmailToken") .HasColumnType("longtext"); @@ -958,6 +1009,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("EmailVerificationTokenId")); + b.Property("EmailToken") .HasColumnType("longtext"); @@ -980,17 +1033,24 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("TokenId")); + b.Property("ExpiresAt") .HasColumnType("datetime(6)"); b.Property("GameVersion") .HasColumnType("int"); + b.Property("LocationHash") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + b.Property("Platform") .HasColumnType("int"); b.Property("TicketHash") - .HasColumnType("longtext"); + .HasMaxLength(64) + .HasColumnType("varchar(64)"); b.Property("UserId") .HasColumnType("int"); @@ -1011,6 +1071,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("TokenId")); + b.Property("Created") .HasColumnType("datetime(6)"); @@ -1031,6 +1093,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("TokenId")); + b.Property("Created") .HasColumnType("datetime(6)"); @@ -1051,6 +1115,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("TokenId")); + b.Property("ExpiresAt") .HasColumnType("datetime(6)"); @@ -1074,6 +1140,8 @@ namespace ProjectLighthouse.Migrations .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("AnnouncementId")); + b.Property("Content") .HasColumnType("longtext"); diff --git a/ProjectLighthouse/Tickets/NPTicket.cs b/ProjectLighthouse/Tickets/NPTicket.cs index bb11a93e..69173d7c 100644 --- a/ProjectLighthouse/Tickets/NPTicket.cs +++ b/ProjectLighthouse/Tickets/NPTicket.cs @@ -185,7 +185,7 @@ public class NPTicket } // Used to identify duplicate tickets - npTicket.TicketHash = CryptoHelper.Sha1Hash(data); + npTicket.TicketHash = CryptoHelper.Sha256Hash(data); #if DEBUG Logger.Debug("npTicket data:", LogArea.Login); diff --git a/ProjectLighthouse/Types/Entities/Token/GameTokenEntity.cs b/ProjectLighthouse/Types/Entities/Token/GameTokenEntity.cs index c1bb1625..ab7d3a16 100644 --- a/ProjectLighthouse/Types/Entities/Token/GameTokenEntity.cs +++ b/ProjectLighthouse/Types/Entities/Token/GameTokenEntity.cs @@ -23,7 +23,11 @@ public class GameTokenEntity public Platform Platform { get; set; } + [StringLength(64)] public string TicketHash { get; set; } + [StringLength(64)] + public string LocationHash { get; set; } + public DateTime ExpiresAt { get; set; } } \ No newline at end of file From 573e7c4f1f565c168e0427f0cbb76319d5a9851f Mon Sep 17 00:00:00 2001 From: Slendy Date: Tue, 25 Jun 2024 04:20:18 -0500 Subject: [PATCH 34/37] Categorize review tests as unit tests --- .../Unit/Controllers/ReviewControllerTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs index 303b4f85..d6eb94f8 100644 --- a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ReviewControllerTests.cs @@ -13,6 +13,7 @@ using Xunit; namespace ProjectLighthouse.Tests.GameApiTests.Unit.Controllers; +[Trait("Category", "Unit")] public class ReviewControllerTests { private static async Task InsertTestData(DatabaseContext database) From 541172b001802e01573fe3b6e1fdfe30cfea968f Mon Sep 17 00:00:00 2001 From: Slendy Date: Tue, 25 Jun 2024 04:38:21 -0500 Subject: [PATCH 35/37] Don't reuse instances of SHA256 when hashing. --- ProjectLighthouse/Helpers/CryptoHelper.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ProjectLighthouse/Helpers/CryptoHelper.cs b/ProjectLighthouse/Helpers/CryptoHelper.cs index cfa896a2..58a5282c 100644 --- a/ProjectLighthouse/Helpers/CryptoHelper.cs +++ b/ProjectLighthouse/Helpers/CryptoHelper.cs @@ -9,9 +9,6 @@ namespace LBPUnion.ProjectLighthouse.Helpers; public static class CryptoHelper { - - private static readonly SHA256 sha256 = SHA256.Create(); - /// /// Generates a random SHA256 and BCrypted token /// @@ -156,7 +153,7 @@ public static class CryptoHelper public static string Sha256Hash(string str) => Sha256Hash(Encoding.UTF8.GetBytes(str)); - public static string Sha256Hash(byte[] bytes) => BitConverter.ToString(sha256.ComputeHash(bytes)).Replace("-", "").ToLower(); + public static string Sha256Hash(byte[] bytes) => BitConverter.ToString(SHA256.HashData(bytes)).Replace("-", "").ToLower(); public static string Sha1Hash(byte[] bytes) => BitConverter.ToString(SHA1.HashData(bytes)).Replace("-", ""); From 98a7f95e6522fa877180fb82d678238d58d44bd4 Mon Sep 17 00:00:00 2001 From: Slendy Date: Tue, 25 Jun 2024 04:44:03 -0500 Subject: [PATCH 36/37] Disable comments on story levels if comments are turned off in config. --- .../Types/Serialization/GameDeveloperSlot.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ProjectLighthouse/Types/Serialization/GameDeveloperSlot.cs b/ProjectLighthouse/Types/Serialization/GameDeveloperSlot.cs index 3de55ee4..93f8436c 100644 --- a/ProjectLighthouse/Types/Serialization/GameDeveloperSlot.cs +++ b/ProjectLighthouse/Types/Serialization/GameDeveloperSlot.cs @@ -1,6 +1,8 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using System.Xml.Serialization; +using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Types.Entities.Profile; @@ -30,6 +32,13 @@ public class GameDeveloperSlot : SlotBase, INeedsPreparationForSerialization [XmlElement("photoCount")] public int PhotoCount { get; set; } + [XmlElement("commentsEnabled")] + public bool CommentsEnabled + { + get => ServerConfiguration.Instance.UserGeneratedContentLimits.LevelCommentsEnabled; + set => throw new NotSupportedException(); + } + public async Task PrepareSerialization(DatabaseContext database) { if (this.SlotId == 0 || this.InternalSlotId == 0) return; From e060f55896f20b09b16c228de2db8d46a3c68975 Mon Sep 17 00:00:00 2001 From: Henry Asbridge Date: Sat, 29 Jun 2024 19:14:16 +0100 Subject: [PATCH 37/37] Base64 encode auth tokens (#1029) * Base64 encode auth tokens to prevent issues in emails This fixes #1023, which should in turn solve some issues people were having with emails. * Make test bcrypt hash things as the auth token isn't one by default * Update ProjectLighthouse/Helpers/CryptoHelper.cs Co-authored-by: Josh * Make only email tokens base64 encoded --------- Co-authored-by: Zaprit Co-authored-by: Josh --- .../Integration/DatabaseTests.cs | 4 ++-- ProjectLighthouse/Helpers/CryptoHelper.cs | 7 ++++++- ProjectLighthouse/Helpers/EmailHelper.cs | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ProjectLighthouse.Tests.GameApiTests/Integration/DatabaseTests.cs b/ProjectLighthouse.Tests.GameApiTests/Integration/DatabaseTests.cs index cc8ddc27..fb87b618 100644 --- a/ProjectLighthouse.Tests.GameApiTests/Integration/DatabaseTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/Integration/DatabaseTests.cs @@ -20,8 +20,8 @@ public class DatabaseTests : LighthouseServerTest int rand = new Random().Next(); - UserEntity userA = await database.CreateUser("unitTestUser" + rand, CryptoHelper.GenerateAuthToken()); - UserEntity userB = await database.CreateUser("unitTestUser" + rand, CryptoHelper.GenerateAuthToken()); + UserEntity userA = await database.CreateUser("unitTestUser" + rand, CryptoHelper.BCryptHash(CryptoHelper.GenerateAuthToken())); + UserEntity userB = await database.CreateUser("unitTestUser" + rand, CryptoHelper.BCryptHash(CryptoHelper.GenerateAuthToken())); Assert.NotNull(userA); Assert.NotNull(userB); diff --git a/ProjectLighthouse/Helpers/CryptoHelper.cs b/ProjectLighthouse/Helpers/CryptoHelper.cs index 58a5282c..dc719bf4 100644 --- a/ProjectLighthouse/Helpers/CryptoHelper.cs +++ b/ProjectLighthouse/Helpers/CryptoHelper.cs @@ -16,10 +16,15 @@ public static class CryptoHelper public static string GenerateAuthToken() { byte[] bytes = (byte[])GenerateRandomBytes(256); - return BCryptHash(Sha256Hash(bytes)); } + public static string GenerateUrlToken() + { + byte[] bytes = (byte[])GenerateRandomBytes(256); + return Convert.ToBase64String(Encoding.UTF8.GetBytes(BCryptHash(Sha256Hash(bytes)))); + } + public static string ComputeDigest(string path, string authCookie, byte[] body, string digestKey, bool excludeBody = false) { diff --git a/ProjectLighthouse/Helpers/EmailHelper.cs b/ProjectLighthouse/Helpers/EmailHelper.cs index 3750f41c..52c69f9d 100644 --- a/ProjectLighthouse/Helpers/EmailHelper.cs +++ b/ProjectLighthouse/Helpers/EmailHelper.cs @@ -52,7 +52,7 @@ public static class SMTPHelper { Created = DateTime.UtcNow, UserId = user.UserId, - ResetToken = CryptoHelper.GenerateAuthToken(), + ResetToken = CryptoHelper.GenerateUrlToken(), }; database.PasswordResetTokens.Add(token); @@ -92,7 +92,7 @@ public static class SMTPHelper { UserId = user.UserId, User = user, - EmailToken = CryptoHelper.GenerateAuthToken(), + EmailToken = CryptoHelper.GenerateUrlToken(), ExpiresAt = DateTime.UtcNow.AddHours(6), };