R6 moderation in decePub: users and personas, accounts, report actions, deletions, suspended personas
Administration's Users & personas (administrators): logins searched and opened into their personas and groups; roles, bans, two-factor reset and deletion of a login; silence, suspension and deletion of a persona; a group deleted. Accounts (moderators): local personas and remote accounts searched or listed as moderated, silenced and suspended with a staff note and a warning. Reports resolve with an action. ActDialog asks for the note, the warning or the password and is the act's confirmation. A login deletes its own persona and the groups it owns with its password. Suspended personas can't be chosen; one refused a token mid-session moves the session to another, or to none, once. Warnings show in notifications, limited accounts on their profile, and moderators remove a post from its card. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
This commit is contained in:
1 parent
4c88980374
commit
c572471b88
30 files changed
+2604
-67
No files matched your search
@@ -23,6 +23,12 @@ namespace decePubClient.Services
|
||||
|
||||
AuthData authData;
|
||||
bool loaded;
|
||||
/// <summary>The personas PrivaPub refused a token to while the JWT was good (suspended, or gone): no request acts as
|
||||
/// them again until the reader picks one anew or the session is read again.</summary>
|
||||
readonly HashSet<string> refusedPersonas = [];
|
||||
|
||||
/// <summary>Raised once for a persona PrivaPub refused a token to (Refuse); CascadingState moves the session on.</summary>
|
||||
public event Action<string> PersonaRefused;
|
||||
|
||||
/// <summary>The stored session, or an empty one.</summary>
|
||||
public async Task<AuthData> GetAuthData(CancellationToken cancellationToken = default)
|
||||
@@ -89,6 +95,25 @@ namespace decePubClient.Services
|
||||
await Save(session, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>Whether PrivaPub refused the persona a token in this session (Refuse).</summary>
|
||||
public bool IsRefused(string personaId) => personaId is not null && refusedPersonas.Contains(personaId);
|
||||
|
||||
/// <summary>PrivaPub refused the persona a token while the JWT was good: no request acts as it from now on, and
|
||||
/// PersonaRefused tells the session, once.</summary>
|
||||
public void Refuse(string personaId)
|
||||
{
|
||||
if (personaId is null || !refusedPersonas.Add(personaId))
|
||||
return;
|
||||
PersonaRefused?.Invoke(personaId);
|
||||
}
|
||||
|
||||
/// <summary>The persona may be tried again: the reader picked it, or PrivaPub lists it as usable again.</summary>
|
||||
public void Unrefuse(string personaId)
|
||||
{
|
||||
if (personaId is not null)
|
||||
refusedPersonas.Remove(personaId);
|
||||
}
|
||||
|
||||
/// <summary>Drops every persona's token: PrivaPub revoked them all (a password change), and each is exchanged anew when used.</summary>
|
||||
public async Task ForgetPersonaTokens(CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -104,6 +129,7 @@ namespace decePubClient.Services
|
||||
logger.LogInformation($"set null({nameof(LogoutAsync)})");
|
||||
authData = null;
|
||||
loaded = true;
|
||||
refusedPersonas.Clear();
|
||||
await storage.RemoveItemAsync(nameof(AuthData), cancellationToken);
|
||||
|
||||
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
|
||||
|
||||
Reference in new issue
Block a user