Email verification with attribute

This commit is contained in:
Zaprit 2025-08-13 21:13:17 +01:00
commit 456f51f0b7
19 changed files with 65 additions and 39 deletions

View file

@ -21,4 +21,7 @@
<data name="username_notice" xml:space="preserve"> <data name="username_notice" xml:space="preserve">
<value>Caution: Your username MUST match your PSN/RPCN username in order to be able to sign in from in-game.</value> <value>Caution: Your username MUST match your PSN/RPCN username in order to be able to sign in from in-game.</value>
</data> </data>
<data name="email_verify_notice" xml:space="preserve">
<value>The game will be read-only until you verify your email</value>
</data>
</root> </root>

View file

@ -3,6 +3,7 @@ using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Filter; using LBPUnion.ProjectLighthouse.Types.Filter;
@ -29,6 +30,7 @@ public class CommentController : ControllerBase
[HttpPost("rateUserComment/{username}")] [HttpPost("rateUserComment/{username}")]
[HttpPost("rateComment/{slotType}/{slotId:int}")] [HttpPost("rateComment/{slotType}/{slotId:int}")]
[EmailVerification]
public async Task<IActionResult> RateComment([FromQuery] int commentId, [FromQuery] int rating, string? username, string? slotType, int slotId) public async Task<IActionResult> RateComment([FromQuery] int commentId, [FromQuery] int rating, string? username, string? slotType, int slotId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -113,6 +115,7 @@ public class CommentController : ControllerBase
[HttpPost("postUserComment/{username}")] [HttpPost("postUserComment/{username}")]
[HttpPost("postComment/{slotType}/{slotId:int}")] [HttpPost("postComment/{slotType}/{slotId:int}")]
[EmailVerification]
public async Task<IActionResult> PostComment(string? username, string? slotType, int slotId) public async Task<IActionResult> PostComment(string? username, string? slotType, int slotId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -152,6 +155,7 @@ public class CommentController : ControllerBase
[HttpPost("deleteUserComment/{username}")] [HttpPost("deleteUserComment/{username}")]
[HttpPost("deleteComment/{slotType}/{slotId:int}")] [HttpPost("deleteComment/{slotType}/{slotId:int}")]
[EmailVerification]
public async Task<IActionResult> DeleteComment([FromQuery] int commentId, string? username, string? slotType, int slotId) public async Task<IActionResult> DeleteComment([FromQuery] int commentId, string? username, string? slotType, int slotId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();

View file

@ -1,6 +1,7 @@
#nullable enable #nullable enable
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Users; using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Users;
using LBPUnion.ProjectLighthouse.StorableLists.Stores; using LBPUnion.ProjectLighthouse.StorableLists.Stores;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
@ -17,6 +18,7 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers;
[Authorize] [Authorize]
[Route("LITTLEBIGPLANETPS3_XML/")] [Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")] [Produces("text/xml")]
[EmailVerification]
public class FriendsController : ControllerBase public class FriendsController : ControllerBase
{ {
private readonly DatabaseContext database; private readonly DatabaseContext database;

View file

@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Users; using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Users;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Serialization; using LBPUnion.ProjectLighthouse.Types.Serialization;
@ -70,6 +71,7 @@ public class ClientConfigurationController : ControllerBase
[HttpPost("privacySettings")] [HttpPost("privacySettings")]
[Produces("text/xml")] [Produces("text/xml")]
[EmailVerification]
public async Task<IActionResult> SetPrivacySetting() public async Task<IActionResult> SetPrivacySetting()
{ {
UserEntity? user = await this.database.UserFromGameToken(this.GetToken()); UserEntity? user = await this.database.UserFromGameToken(this.GetToken());

View file

@ -2,6 +2,7 @@
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Interaction; using LBPUnion.ProjectLighthouse.Types.Entities.Interaction;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -16,6 +17,7 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers.Matching;
[Authorize] [Authorize]
[Route("LITTLEBIGPLANETPS3_XML/")] [Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")] [Produces("text/xml")]
[EmailVerification]
public class EnterLevelController : ControllerBase public class EnterLevelController : ControllerBase
{ {
private readonly DatabaseContext database; private readonly DatabaseContext database;

View file

@ -5,6 +5,7 @@ using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Logging; using LBPUnion.ProjectLighthouse.Types.Logging;
@ -21,6 +22,7 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers.Matching;
[Authorize] [Authorize]
[Route("LITTLEBIGPLANETPS3_XML/")] [Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")] [Produces("text/xml")]
[EmailVerification]
public class MatchController : ControllerBase public class MatchController : ControllerBase
{ {
private readonly DatabaseContext database; private readonly DatabaseContext database;

View file

@ -13,6 +13,7 @@ using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Filter; using LBPUnion.ProjectLighthouse.Types.Filter;
using LBPUnion.ProjectLighthouse.Types.Logging; using LBPUnion.ProjectLighthouse.Types.Logging;
using LBPUnion.ProjectLighthouse.Types.Mail; using LBPUnion.ProjectLighthouse.Types.Mail;
using LBPUnion.ProjectLighthouse.Types.Notifications;
using LBPUnion.ProjectLighthouse.Types.Serialization; using LBPUnion.ProjectLighthouse.Types.Serialization;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -96,6 +97,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.";
StringBuilder builder = new(); StringBuilder builder = new();
UserEntity? user = await this.database.UserFromGameToken(token);
if (user?.EmailAddressVerified == false)
{
GameNotification verifyEmailNotification = new();
verifyEmailNotification.Type = NotificationType.ModerationNotification;
verifyEmailNotification.Text = LocalizationManager.GetLocalizedString(TranslationAreas.Register, user.Language, "email_verify_notice");
builder.AppendLine(LighthouseSerializer.Serialize(this.HttpContext.RequestServices, verifyEmailNotification));
}
foreach (NotificationEntity notification in notifications) foreach (NotificationEntity notification in notifications)
{ {
builder.AppendLine(LighthouseSerializer.Serialize(this.HttpContext.RequestServices, builder.AppendLine(LighthouseSerializer.Serialize(this.HttpContext.RequestServices,

View file

@ -5,6 +5,7 @@ using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Moderation; using LBPUnion.ProjectLighthouse.Types.Entities.Moderation;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Moderation.Reports; using LBPUnion.ProjectLighthouse.Types.Moderation.Reports;
@ -18,6 +19,7 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers;
[Authorize] [Authorize]
[Route("LITTLEBIGPLANETPS3_XML/")] [Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")] [Produces("text/xml")]
[EmailVerification]
public class ReportController : ControllerBase public class ReportController : ControllerBase
{ {
private readonly DatabaseContext database; private readonly DatabaseContext database;

View file

@ -6,6 +6,7 @@ using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -33,6 +34,7 @@ public class PhotosController : ControllerBase
} }
[HttpPost("uploadPhoto")] [HttpPost("uploadPhoto")]
[EmailVerification]
public async Task<IActionResult> UploadPhoto() public async Task<IActionResult> UploadPhoto()
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -234,6 +236,7 @@ public class PhotosController : ControllerBase
} }
[HttpPost("deletePhoto/{id:int}")] [HttpPost("deletePhoto/{id:int}")]
[EmailVerification]
public async Task<IActionResult> DeletePhoto(int id) public async Task<IActionResult> DeletePhoto(int id)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();

View file

@ -1,9 +1,9 @@
#nullable enable
using System.Text; using System.Text;
using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Files; using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Misc; using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Misc;
using LBPUnion.ProjectLighthouse.Types.Logging; using LBPUnion.ProjectLighthouse.Types.Logging;
using LBPUnion.ProjectLighthouse.Types.Resources; using LBPUnion.ProjectLighthouse.Types.Resources;
@ -52,6 +52,7 @@ public class ResourcesController : ControllerBase
[HttpPost("upload/{hash}/unattributed")] [HttpPost("upload/{hash}/unattributed")]
[HttpPost("upload/{hash}")] [HttpPost("upload/{hash}")]
[EmailVerification]
public async Task<IActionResult> UploadResource(string hash) public async Task<IActionResult> UploadResource(string hash)
{ {
string assetsDirectory = FileHelper.ResourcePath; string assetsDirectory = FileHelper.ResourcePath;

View file

@ -1,6 +1,7 @@
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Interaction; using LBPUnion.ProjectLighthouse.Types.Entities.Interaction;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -41,6 +42,7 @@ public class LevelTagsController : ControllerBase
} }
[HttpPost("tag/{slotType}/{id:int}")] [HttpPost("tag/{slotType}/{id:int}")]
[EmailVerification]
public async Task<IActionResult> PostTag([FromForm(Name = "t")] string tagName, [FromRoute] string slotType, [FromRoute] int id) public async Task<IActionResult> PostTag([FromForm(Name = "t")] string tagName, [FromRoute] string slotType, [FromRoute] int id)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();

View file

@ -2,6 +2,7 @@
using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Serialization; using LBPUnion.ProjectLighthouse.Types.Serialization;
@ -41,6 +42,7 @@ public class PlaylistController : ControllerBase
} }
[HttpPost("playlists/{playlistId:int}/delete")] [HttpPost("playlists/{playlistId:int}/delete")]
[EmailVerification]
public async Task<IActionResult> DeletePlaylist(int playlistId) public async Task<IActionResult> DeletePlaylist(int playlistId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -60,6 +62,7 @@ public class PlaylistController : ControllerBase
[HttpPost("playlists/{playlistId:int}/slots")] [HttpPost("playlists/{playlistId:int}/slots")]
[HttpPost("playlists/{playlistId:int}/slots/{slotId:int}/delete")] [HttpPost("playlists/{playlistId:int}/slots/{slotId:int}/delete")]
[HttpPost("playlists/{playlistId:int}/order_slots")] [HttpPost("playlists/{playlistId:int}/order_slots")]
[EmailVerification]
public async Task<IActionResult> UpdatePlaylist(int playlistId, int slotId) public async Task<IActionResult> UpdatePlaylist(int playlistId, int slotId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -124,6 +127,7 @@ public class PlaylistController : ControllerBase
} }
[HttpPost("playlists")] [HttpPost("playlists")]
[EmailVerification]
public async Task<IActionResult> CreatePlaylist() public async Task<IActionResult> CreatePlaylist()
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();

View file

@ -6,6 +6,7 @@ using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers; using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -24,6 +25,7 @@ namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Controllers.Slots;
[Authorize] [Authorize]
[Route("LITTLEBIGPLANETPS3_XML/")] [Route("LITTLEBIGPLANETPS3_XML/")]
[Produces("text/xml")] [Produces("text/xml")]
[EmailVerification]
public class PublishController : ControllerBase public class PublishController : ControllerBase
{ {
private readonly DatabaseContext database; private readonly DatabaseContext database;

View file

@ -3,6 +3,7 @@ using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Interaction; using LBPUnion.ProjectLighthouse.Types.Entities.Interaction;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
@ -29,6 +30,7 @@ public class ReviewController : ControllerBase
// LBP1 rating // LBP1 rating
[HttpPost("rate/user/{slotId:int}")] [HttpPost("rate/user/{slotId:int}")]
[EmailVerification]
public async Task<IActionResult> Rate(int slotId, int rating) public async Task<IActionResult> Rate(int slotId, int rating)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -58,6 +60,7 @@ public class ReviewController : ControllerBase
// LBP2 and beyond rating // LBP2 and beyond rating
[HttpPost("dpadrate/user/{slotId:int}")] [HttpPost("dpadrate/user/{slotId:int}")]
[EmailVerification]
public async Task<IActionResult> DPadRate(int slotId, int rating) public async Task<IActionResult> DPadRate(int slotId, int rating)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -89,6 +92,7 @@ public class ReviewController : ControllerBase
} }
[HttpPost("postReview/user/{slotId:int}")] [HttpPost("postReview/user/{slotId:int}")]
[EmailVerification]
public async Task<IActionResult> PostReview(int slotId) public async Task<IActionResult> PostReview(int slotId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -202,6 +206,7 @@ public class ReviewController : ControllerBase
} }
[HttpPost("rateReview/user/{slotId:int}/{username}")] [HttpPost("rateReview/user/{slotId:int}/{username}")]
[EmailVerification]
public async Task<IActionResult> RateReview(int slotId, string username, int rating = 0) public async Task<IActionResult> RateReview(int slotId, string username, int rating = 0)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -255,6 +260,7 @@ public class ReviewController : ControllerBase
} }
[HttpPost("deleteReview/user/{slotId:int}/{username}")] [HttpPost("deleteReview/user/{slotId:int}/{username}")]
[EmailVerification]
public async Task<IActionResult> DeleteReview(int slotId, string username) public async Task<IActionResult> DeleteReview(int slotId, string username)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();

View file

@ -3,6 +3,7 @@ using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.StorableLists.Stores; using LBPUnion.ProjectLighthouse.StorableLists.Stores;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
@ -42,6 +43,7 @@ public class ScoreController : ControllerBase
[HttpPost("scoreboard/{slotType}/{id:int}")] [HttpPost("scoreboard/{slotType}/{id:int}")]
[HttpPost("scoreboard/{slotType}/{id:int}/{childId:int}")] [HttpPost("scoreboard/{slotType}/{id:int}/{childId:int}")]
[EmailVerification]
public async Task<IActionResult> SubmitScore(string slotType, int id, int childId) public async Task<IActionResult> SubmitScore(string slotType, int id, int childId)
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();

View file

@ -6,6 +6,7 @@ using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers; using LBPUnion.ProjectLighthouse.Servers.GameServer.Helpers;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Users; using LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Users;
using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Entities.Level;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
@ -63,6 +64,7 @@ public class UserController : ControllerBase
} }
[HttpPost("updateUser")] [HttpPost("updateUser")]
[EmailVerification]
public async Task<IActionResult> UpdateUser() public async Task<IActionResult> UpdateUser()
{ {
GameTokenEntity token = this.GetToken(); GameTokenEntity token = this.GetToken();
@ -171,6 +173,7 @@ public class UserController : ControllerBase
[HttpPost("update_my_pins")] [HttpPost("update_my_pins")]
[Produces("text/json")] [Produces("text/json")]
[EmailVerification]
public async Task<IActionResult> UpdateMyPins() public async Task<IActionResult> UpdateMyPins()
{ {
UserEntity? user = await this.database.UserFromGameToken(this.GetToken()); UserEntity? user = await this.database.UserFromGameToken(this.GetToken());

View file

@ -1,57 +1,30 @@
using System.Diagnostics; using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Middlewares; using LBPUnion.ProjectLighthouse.Middlewares;
using LBPUnion.ProjectLighthouse.Types.Entities.Profile; using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token; using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using Microsoft.AspNetCore.Http.Features;
namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares; namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Middlewares;
public class EmailVerificationAttribute : Attribute;
public class EmailVerificationMiddleware: MiddlewareDBContext public class EmailVerificationMiddleware: MiddlewareDBContext
{ {
private readonly bool requireVerification;
private static readonly HashSet<string> verifyPathList = public EmailVerificationMiddleware(RequestDelegate next) : base(next)
[
"uploadPhoto",
"deletePhoto",
"upload",
"publish",
"rateUserComment",
"rateComment",
"postUserComment",
"postComment",
"deleteUserComment",
"deleteComment",
"npdata",
"grief",
"updateUser",
"update_my_pins",
"match",
"play",
"enterLevel",
"startPublish",
];
public EmailVerificationMiddleware(RequestDelegate next, bool requireVerification) : base(next)
{ {
this.requireVerification = requireVerification;
} }
public override async Task InvokeAsync(HttpContext context, DatabaseContext database) public override async Task InvokeAsync(HttpContext context, DatabaseContext database)
{ {
if (requireVerification) if (ServerConfiguration.Instance.Mail.RequireEmailVerification)
{ {
if (context.Request.Path.Value == null) Endpoint? endpoint = context.Features.Get<IEndpointFeature>()?.Endpoint;
{ EmailVerificationAttribute? attribute = endpoint?.Metadata.GetMetadata<EmailVerificationAttribute>();
await this.next(context);
return;
}
const string url = "/LITTLEBIGPLANETPS3_XML"; if (attribute != null)
string verifyPath = context.Request.Path;
string strippedPath = verifyPath.Contains(url) ? verifyPath[url.Length..].Split("/")[0] : "";
if (verifyPathList.Contains(strippedPath))
{ {
GameTokenEntity? gameToken = await database.GameTokenFromRequest(context.Request); GameTokenEntity? gameToken = await database.GameTokenFromRequest(context.Request);
if (gameToken == null) if (gameToken == null)
@ -63,7 +36,7 @@ public class EmailVerificationMiddleware: MiddlewareDBContext
UserEntity? user = await database.UserFromGameToken(gameToken); UserEntity? user = await database.UserFromGameToken(gameToken);
if (!user!.EmailAddressVerified) if (!user!.EmailAddressVerified)
{ {
context.Response.StatusCode = 403; context.Response.StatusCode = 401; // 403 will cause a re-auth
context.Abort(); context.Abort();
return; return;
} }

View file

@ -106,6 +106,7 @@ public class GameServerStartup
app.UseMiddleware<RequestLogMiddleware>(); app.UseMiddleware<RequestLogMiddleware>();
app.UseMiddleware<RateLimitMiddleware>(); app.UseMiddleware<RateLimitMiddleware>();
app.UseMiddleware<DigestMiddleware>(computeDigests); app.UseMiddleware<DigestMiddleware>(computeDigests);
app.UseMiddleware<EmailVerificationMiddleware>();
app.UseMiddleware<SetLastContactMiddleware>(); app.UseMiddleware<SetLastContactMiddleware>();
app.UseRouting(); app.UseRouting();

View file

@ -17,4 +17,6 @@ public class MailConfiguration
public string Password { get; set; } = ""; public string Password { get; set; } = "";
public bool UseSSL { get; set; } = true; public bool UseSSL { get; set; } = true;
public bool RequireEmailVerification { get; set; } = true;
} }