mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-04-19 19:14:51 +00:00
Add proper ban page when logging in (#773)
* Add proper ban page upon logging in * Remove two extra line break tags that don't need to be there * Fix timestamp formatting * Properly display timestamps in correct timezone * Fix formatting issues with ban page * Remove extra parenthesis which would be rendered on-page * Add to redirect middleware to prevent navigating to other pages * Small nitpick, renaming UserBannedPage to BannedUserPage * Resolve nitpicks from reviewers * Remove un-necessary log message in LoginForm * Fix ban reason translatable string argument * Word choice nitpick ("Ban Created" -> "Ban Issued") * Final adjustments and nitpicks, visual and grammatical * Resolve requested changes from reviewers
This commit is contained in:
parent
c8c54d78de
commit
21dbdff20a
11 changed files with 203 additions and 23 deletions
51
ProjectLighthouse.Localization/Moderation.resx
Normal file
51
ProjectLighthouse.Localization/Moderation.resx
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="suspension_heading" xml:space="preserve">
|
||||
<value>Account Suspended</value>
|
||||
</data>
|
||||
<data name="suspension_explanation" xml:space="preserve">
|
||||
<value>Your {0} account has been suspended due to code of conduct violations.</value>
|
||||
</data>
|
||||
<data name="suspension_expiration" xml:space="preserve">
|
||||
<value>During this suspension, the following features will be limited until {0}:</value>
|
||||
</data>
|
||||
<data name="suspension_reason" xml:space="preserve">
|
||||
<value>Reason for suspension: "{0}"</value>
|
||||
</data>
|
||||
<data name="suspension_circumvent_warning" xml:space="preserve">
|
||||
<value>Attempts to circumvent this suspension will result in an extended suspension period.</value>
|
||||
</data>
|
||||
<data name="lbp_online_multiplayer" xml:space="preserve">
|
||||
<value>LittleBigPlanet™ Online multiplayer</value>
|
||||
</data>
|
||||
<data name="does_not_expire" xml:space="preserve">
|
||||
<value>Does not expire</value>
|
||||
</data>
|
||||
<data name="profile_visibility" xml:space="preserve">
|
||||
<value>Profile visibility</value>
|
||||
</data>
|
||||
<data name="website_interactions" xml:space="preserve">
|
||||
<value>Browsing levels, photos, and profiles</value>
|
||||
</data>
|
||||
<data name="account_profile_management" xml:space="preserve">
|
||||
<value>Account and profile management</value>
|
||||
</data>
|
||||
</root>
|
|
@ -44,6 +44,10 @@
|
|||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>TwoFactor.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Moderation.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Moderation.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
namespace LBPUnion.ProjectLighthouse.Localization.StringLists;
|
||||
|
||||
public static class ModerationStrings
|
||||
{
|
||||
// Main page strings
|
||||
public static readonly TranslatableString SuspensionHeading = create("suspension_heading");
|
||||
public static readonly TranslatableString SuspensionExplanation = create("suspension_explanation");
|
||||
public static readonly TranslatableString SuspensionExpiration = create("suspension_expiration");
|
||||
public static readonly TranslatableString SuspensionReason = create("suspension_reason");
|
||||
public static readonly TranslatableString SuspensionCircumventWarning = create("suspension_circumvent_warning");
|
||||
|
||||
// Translatable string in case a ban doesn't expire
|
||||
public static readonly TranslatableString DoesNotExpire = create("does_not_expire");
|
||||
|
||||
// Restricted features strings
|
||||
public static readonly TranslatableString LbpOnlineMultiplayer = create("lbp_online_multiplayer");
|
||||
public static readonly TranslatableString WebsiteInteractions = create("website_interactions");
|
||||
public static readonly TranslatableString ProfileVisibility = create("profile_visibility");
|
||||
public static readonly TranslatableString AccountProfileManagement = create("account_profile_management");
|
||||
|
||||
private static TranslatableString create(string key) => new(TranslationAreas.Moderation, key);
|
||||
}
|
|
@ -12,4 +12,5 @@ public enum TranslationAreas
|
|||
Profile,
|
||||
ModPanel,
|
||||
TwoFactor,
|
||||
Moderation,
|
||||
}
|
|
@ -59,6 +59,18 @@ public class UserRequiredRedirectMiddleware : MiddlewareDBContext
|
|||
return;
|
||||
}
|
||||
|
||||
if (user.IsBanned)
|
||||
{
|
||||
if (!pathContains(ctx, "/banned"))
|
||||
{
|
||||
ctx.Response.Redirect("/banned");
|
||||
return;
|
||||
}
|
||||
|
||||
await this.next(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.EmailAddress == null && ServerConfiguration.Instance.Mail.MailEnabled)
|
||||
{
|
||||
if (!pathContains(ctx, "/login/setEmail"))
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
@{
|
||||
Layout = "Layouts/BaseLayout";
|
||||
Model.ShowTitleInPage = false;
|
||||
|
||||
|
||||
bool isMobile = Request.IsMobile();
|
||||
string language = Model.GetLanguage();
|
||||
string timeZone = Model.GetTimeZone();
|
||||
|
@ -25,7 +25,9 @@
|
|||
if (Model.PendingAuthAttempts > 0)
|
||||
{
|
||||
<p>
|
||||
<b><a href="/authentication">@Model.Translate(LandingPageStrings.AuthAttemptsPending, Model.PendingAuthAttempts)</a></b>
|
||||
<b>
|
||||
<a href="/authentication">@Model.Translate(LandingPageStrings.AuthAttemptsPending, Model.PendingAuthAttempts)</a>
|
||||
</b>
|
||||
</p>
|
||||
}
|
||||
}
|
||||
|
@ -48,13 +50,13 @@
|
|||
int i = 0;
|
||||
foreach (UserEntity user in Model.PlayersOnline)
|
||||
{
|
||||
i++;
|
||||
i++;
|
||||
@await user.ToLink(Html, ViewData, language, timeZone, true)
|
||||
@* whitespace has forced my hand *@
|
||||
if (i != Model.PlayersOnline.Count)
|
||||
{
|
||||
<span>,</span>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +65,9 @@
|
|||
<div class="@(isMobile ? "" : "ui center aligned grid")">
|
||||
<div class="eight wide column">
|
||||
<div class="ui inverted pink segment">
|
||||
<h1><i class="star icon"></i>@Model.Translate(LandingPageStrings.LatestTeamPicks)</h1>
|
||||
<h1>
|
||||
<i class="star icon"></i>@Model.Translate(LandingPageStrings.LatestTeamPicks)
|
||||
</h1>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui left aligned segment">
|
||||
@foreach (SlotEntity slot in Model.LatestTeamPicks!) @* Can't reach a point where this is null *@
|
||||
|
@ -80,7 +84,9 @@
|
|||
}
|
||||
<div class="eight wide column">
|
||||
<div class="ui inverted blue segment">
|
||||
<h1><i class="globe americas icon"></i>@Model.Translate(LandingPageStrings.NewestLevels)</h1>
|
||||
<h1>
|
||||
<i class="globe americas icon"></i>@Model.Translate(LandingPageStrings.NewestLevels)
|
||||
</h1>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui left aligned segment">
|
||||
@foreach (SlotEntity slot in Model.NewestLevels!) @* Can't reach a point where this is null *@
|
||||
|
|
|
@ -13,14 +13,14 @@ namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages;
|
|||
|
||||
public class LandingPage : BaseLayout
|
||||
{
|
||||
public LandingPage(DatabaseContext database) : base(database)
|
||||
{}
|
||||
public List<SlotEntity>? LatestTeamPicks;
|
||||
public List<SlotEntity>? NewestLevels;
|
||||
|
||||
public int PendingAuthAttempts;
|
||||
public List<UserEntity> PlayersOnline = new();
|
||||
|
||||
public List<SlotEntity>? LatestTeamPicks;
|
||||
public List<SlotEntity>? NewestLevels;
|
||||
public LandingPage(DatabaseContext database) : base(database)
|
||||
{ }
|
||||
|
||||
[UsedImplicitly]
|
||||
public async Task<IActionResult> OnGet()
|
||||
|
@ -29,10 +29,12 @@ public class LandingPage : BaseLayout
|
|||
if (user != null && user.PasswordResetRequired) return this.Redirect("~/passwordResetRequired");
|
||||
|
||||
if (user != null)
|
||||
this.PendingAuthAttempts = await this.Database.PlatformLinkAttempts
|
||||
.CountAsync(l => l.UserId == user.UserId);
|
||||
this.PendingAuthAttempts =
|
||||
await this.Database.PlatformLinkAttempts.CountAsync(l => l.UserId == user.UserId);
|
||||
|
||||
List<int> userIds = await this.Database.LastContacts.Where(l => TimeHelper.Timestamp - l.Timestamp < 300).Select(l => l.UserId).ToListAsync();
|
||||
List<int> userIds = await this.Database.LastContacts.Where(l => TimeHelper.Timestamp - l.Timestamp < 300)
|
||||
.Select(l => l.UserId)
|
||||
.ToListAsync();
|
||||
|
||||
this.PlayersOnline = await this.Database.Users.Where(u => userIds.Contains(u.UserId)).ToListAsync();
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
@page "/banned"
|
||||
@using LBPUnion.ProjectLighthouse.Configuration
|
||||
@using LBPUnion.ProjectLighthouse.Localization.StringLists
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.Login.BannedUserPage
|
||||
|
||||
@{
|
||||
Layout = "Layouts/BaseLayout";
|
||||
Model.Title = Model.Translate(ModerationStrings.SuspensionHeading);
|
||||
|
||||
string timeZone = (string?)ViewData["TimeZone"] ?? TimeZoneInfo.Local.Id;
|
||||
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
|
||||
}
|
||||
|
||||
<div class="ui middle aligned left aligned">
|
||||
<h1>@Model.Translate(ModerationStrings.SuspensionHeading)</h1>
|
||||
|
||||
<p>
|
||||
@Model.Translate(ModerationStrings.SuspensionExplanation, ServerConfiguration.Instance.Customization.ServerName)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span>
|
||||
@if (Model.ModCase.ExpiresAt != null)
|
||||
{
|
||||
@Model.Translate(ModerationStrings.SuspensionExpiration, TimeZoneInfo.ConvertTime(Model.ModCase.ExpiresAt.Value, timeZoneInfo).ToString("M/d/yyyy @ h:mm tt"))
|
||||
}
|
||||
else
|
||||
{
|
||||
@Model.Translate(ModerationStrings.SuspensionExpiration, Model.Translate(ModerationStrings.DoesNotExpire))
|
||||
}
|
||||
</span>
|
||||
|
||||
<ul>
|
||||
<li>@Model.Translate(ModerationStrings.LbpOnlineMultiplayer)</li>
|
||||
<li>@Model.Translate(ModerationStrings.WebsiteInteractions)</li>
|
||||
<li>@Model.Translate(ModerationStrings.ProfileVisibility)</li>
|
||||
<li>@Model.Translate(ModerationStrings.AccountProfileManagement)</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@Model.Translate(ModerationStrings.SuspensionReason, Model.ModCase.Reason)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@Model.Translate(ModerationStrings.SuspensionCircumventWarning)
|
||||
</p>
|
||||
</div>
|
|
@ -0,0 +1,36 @@
|
|||
using JetBrains.Annotations;
|
||||
using LBPUnion.ProjectLighthouse.Database;
|
||||
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Moderation;
|
||||
using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
|
||||
using LBPUnion.ProjectLighthouse.Types.Moderation.Cases;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages.Login;
|
||||
|
||||
public class BannedUserPage : BaseLayout
|
||||
{
|
||||
public BannedUserPage(DatabaseContext database) : base(database)
|
||||
{ }
|
||||
|
||||
public ModerationCaseEntity ModCase = null!;
|
||||
|
||||
[UsedImplicitly]
|
||||
public async Task<IActionResult> OnGet()
|
||||
{
|
||||
UserEntity? user = this.Database.UserFromWebRequest(this.Request);
|
||||
|
||||
if (user == null) return this.Redirect("~/login");
|
||||
if (!user.IsBanned) return this.Redirect("~/");
|
||||
|
||||
ModerationCaseEntity? modCase = await this.Database.Cases
|
||||
.FirstOrDefaultAsync(c => c.AffectedId == user.UserId && c.Type == CaseType.UserBan);
|
||||
|
||||
if (modCase == null) return this.Redirect("~/");
|
||||
|
||||
this.ModCase = modCase;
|
||||
|
||||
return this.Page();
|
||||
}
|
||||
}
|
|
@ -83,13 +83,6 @@ public class LoginForm : BaseLayout
|
|||
return this.Page();
|
||||
}
|
||||
|
||||
if (user.IsBanned)
|
||||
{
|
||||
Logger.Warn($"User {user.Username} (id: {user.UserId}) failed to login on web due to being banned", LogArea.Login);
|
||||
this.Error = this.Translate(ErrorStrings.UserIsBanned, user.BannedReason);
|
||||
return this.Page();
|
||||
}
|
||||
|
||||
WebTokenEntity webToken = new()
|
||||
{
|
||||
UserId = user.UserId,
|
||||
|
@ -120,6 +113,11 @@ public class LoginForm : BaseLayout
|
|||
: this.Redirect("~/2fa" + "?redirect=" + HttpUtility.UrlEncode(redirect));
|
||||
}
|
||||
|
||||
if (user.IsBanned)
|
||||
{
|
||||
return this.Redirect("~/banned");
|
||||
}
|
||||
|
||||
if (user.PasswordResetRequired) return this.Redirect("~/passwordResetRequired");
|
||||
|
||||
return ServerConfiguration.Instance.Mail.MailEnabled switch
|
||||
|
|
|
@ -23,18 +23,18 @@
|
|||
@if (Model.ProfileUser.IsBanned)
|
||||
{
|
||||
<div class="ui inverted red segment">
|
||||
<h3 style="margin-bottom:3px;"><i class="ban icon"></i> This user is currently banned.</h3>
|
||||
<h3 style="margin-bottom:5px;"><i class="ban icon"></i> This user is currently banned.</h3>
|
||||
@if (Model.User != null && Model.User.IsModerator)
|
||||
{
|
||||
<b>Reason:</b>
|
||||
<span>"@Model.ProfileUser.BannedReason"</span>
|
||||
<span>"@Model.ProfileUser.BannedReason"</span> <br />
|
||||
<p>
|
||||
<i>Only you and other moderators may view the ban reason.</i>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>Users who engage in inappropriate, offensive, or violent actions will be moderated. Be sure to follow the rules!</p>
|
||||
<p>This user has been banned for violating the Terms of Service. Remember to follow the rules!</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue