Phase 1: Anmeldung, Rechte und Rollenverwaltung
Auth.js übernimmt nur den OAuth-Ablauf mit state und PKCE, Scope identify. Das Zugangstoken des Nutzers wird danach verworfen: die Rollen holt der Bot mit seinem eigenen Token. Die Sitzung steht in der Datenbank, im Cookie liegt nur userId und sessionId. Ohne die Zeile in Session ist das Cookie wertlos, und nur so lässt sich eine Sitzung zurückziehen. Wer sich anmelden darf, steckt in lib/auth/signInPolicy.ts statt im Callback: das ist die Regel, an der alles hängt, und sie gehört einzeln prüfbar. Kein Guild-Mitglied, kein Zugang. Keine Rolle mit grantsMembership, kein Zugang. Notfall-Admins umgehen die Rolle, aber nicht die Guild-Mitgliedschaft. RoleMapping trägt jetzt grantsMembership, category und isPresent. Der Worker spiegelt jede Rolle der Guild hierher, damit im Adminbereich nichts von Hand eingetragen werden muss. Gelöschte Rollen werden nicht entfernt, sondern auf isPresent = false gesetzt: beim Umzug auf den echten Server bleiben sie als Vorlage stehen. Der Worker gleicht über Gateway-Ereignisse und zusätzlich alle fünf Minuten voll ab. Verliert jemand seine AfiS-Rolle, beendet er dessen Sitzungen sofort und setzt isActive auf false — der Datensatz bleibt, damit Autorenangaben in alten Akten gültig bleiben. Das passiert im Worker und nicht in der Web-App, weil es dort erst beim nächsten Request des Betroffenen griffe. Zwei Widersprüche der Dokumente aufgelöst, festgehalten in docs/13-entscheidungen.md: der Ausschluss schlägt auch den Admin (das Codebeispiel in 03-auth-und-rechte.md übergeht ihn, die Reihenfolge eine Zeile darüber nicht), und versiegelte Akten fallen im Where-Fragment heraus statt in einer Prüfung danach. 45 Tests, davon die Negativfälle aus docs/03 gegen eine echte Datenbank: Stufe 2 sieht die Stufe-4-Akte nicht und findet sie auch nicht in der Trefferzahl, ein Ausgeschlossener mit Stufe 5 kommt nicht heran, ein Rollenentzug beendet die Sitzungen, und ein Ausfall der Discord-API sieht nicht aus wie eine verweigerte Mitgliedschaft.
This commit is contained in:
+69
-4
@@ -29,10 +29,22 @@ export const de = {
|
||||
signIn: 'Mit Discord anmelden',
|
||||
signOut: 'Abmelden',
|
||||
signedInAs: 'Angemeldet als',
|
||||
notInGuild: {
|
||||
title: 'Du bist nicht auf dem AfiS-Discord',
|
||||
body: 'Die Anmeldung setzt eine Mitgliedschaft auf dem Discord-Server voraus. Wende dich an die Abteilungsleitung.',
|
||||
},
|
||||
intro:
|
||||
'Die Anmeldung läuft über Discord. Zugriff haben Mitglieder der Abteilung für innere Sicherheit.',
|
||||
reasons: {
|
||||
'keine-mitgliedschaft': {
|
||||
title: 'Du bist nicht auf dem AfiS-Discord',
|
||||
body: 'Die Anmeldung setzt eine Mitgliedschaft auf dem Discord-Server voraus. Wende dich an die Abteilungsleitung.',
|
||||
},
|
||||
'keine-afis-rolle': {
|
||||
title: 'Keine Berechtigung für das Aktensystem',
|
||||
body: 'Du bist auf dem Server, trägst aber keine Rolle der Abteilung. Wende dich an die Abteilungsleitung.',
|
||||
},
|
||||
'discord-nicht-erreichbar': {
|
||||
title: 'Discord antwortet nicht',
|
||||
body: 'Die Mitgliedschaft war nicht prüfbar. In einigen Minuten erneut versuchen.',
|
||||
},
|
||||
} as Record<string, { title: string; body: string }>,
|
||||
sessionEnded: {
|
||||
title: 'Sitzung beendet',
|
||||
body: 'Deine Rollen haben sich geändert. Melde dich neu an.',
|
||||
@@ -41,6 +53,59 @@ export const de = {
|
||||
title: 'Anmeldung nicht möglich',
|
||||
body: 'Der Anmeldevorgang wurde abgebrochen. Erneut versuchen.',
|
||||
},
|
||||
backToSignIn: 'Zurück zur Anmeldung',
|
||||
},
|
||||
|
||||
overview: {
|
||||
heading: 'Dein Zugang',
|
||||
intro: 'Was das System über dich weiss und was daraus folgt.',
|
||||
person: 'Person',
|
||||
discordId: 'Discord-Kennung',
|
||||
roles: 'Rollen auf dem Discord',
|
||||
clearance: 'Errechnete Freigabestufe',
|
||||
permissions: 'Rechte',
|
||||
noPermissions: 'Keine Rechte. Die Abteilungsleitung vergibt sie in der Rollenverwaltung.',
|
||||
noRoles: 'Keine Rollen.',
|
||||
bootstrapAdmin: 'Notfallzugang aus der Konfiguration, unabhängig vom Rollen-Mapping',
|
||||
unmapped: 'nicht zugeordnet',
|
||||
},
|
||||
|
||||
roleAdmin: {
|
||||
heading: 'Rollenverwaltung',
|
||||
intro:
|
||||
'Jede Rolle des Discord-Servers steht hier. Zugangsrollen bestimmen die Freigabestufe, Rangrollen die Rechte, und eine Zugehörigkeitsrolle entscheidet, wer sich überhaupt anmelden darf.',
|
||||
empty:
|
||||
'Noch keine Rollen eingelesen. Der Worker spiegelt sie, sobald er am Discord-Gateway hängt.',
|
||||
role: 'Rolle',
|
||||
category: 'Sorte',
|
||||
clearance: 'Freigabestufe',
|
||||
grantsMembership: 'Darf sich anmelden',
|
||||
permissions: 'Rechte',
|
||||
missingFromGuild: 'Auf dem Server nicht mehr vorhanden',
|
||||
save: 'Zuordnung speichern',
|
||||
invalidInput: 'Eingabe nicht gültig',
|
||||
roleGone: 'Rolle nicht gefunden, sie wurde zwischenzeitlich gelöscht',
|
||||
saving: 'Wird gespeichert',
|
||||
saved: 'Zuordnung gespeichert',
|
||||
confirm: 'Rollen-Mapping ändern? Das wirkt sofort für alle angemeldeten Personen.',
|
||||
categories: {
|
||||
MEMBERSHIP: 'Zugehörigkeit',
|
||||
RANK: 'Rang',
|
||||
CLEARANCE: 'Zugang',
|
||||
UNSORTED: 'Nicht eingeordnet',
|
||||
} as Record<string, string>,
|
||||
optIn:
|
||||
'Dieses Recht ist im Auslieferungszustand keiner Rolle zugeordnet. Vergib es bewusst.',
|
||||
preview: {
|
||||
heading: 'Vorschau',
|
||||
intro: 'Was jemand mit dieser Stufe sieht, wenn er keine weiteren Rollen hat.',
|
||||
level: 'Stufe',
|
||||
sees: 'Sieht Akten bis einschliesslich',
|
||||
hidden: 'Höhere Akten sind unsichtbar',
|
||||
lockedOnly: 'Höhere Akten sind sichtbar, aber gesperrt',
|
||||
nobody: 'Keine Rolle führt zu dieser Stufe',
|
||||
viaRoles: 'Erreichbar über',
|
||||
},
|
||||
},
|
||||
|
||||
clearance: {
|
||||
|
||||
Reference in New Issue
Block a user