Phase B1: Anmeldung, Benutzer, Gruppen und Rollen
Umschaltbar ueber AUTH_ENABLED in der .env. Steht sie auf false, verhaelt
sich alles wie bisher - geprueft mit den 200 bestehenden Pruefungen.
Kern ist eine Actor- und Policy-Schicht: getActor() liefert bei
ausgeschalteter Anmeldung einen system-Actor mit Vollzugriff, sonst den
angemeldeten Benutzer. Dadurch braucht keine einzige Route ein
'if (anmeldungAktiv)' - sie fragen alle nur can() bzw. requirePermission().
- Datenmodell: User, Session, Group, Membership; Codes bekommen Gruppe und
Ersteller. Die Migration legt eine Standardgruppe an und ordnet ihr
bestehende Codes zu, bevor die Spalte verpflichtend wird - sonst
scheiterte sie auf jeder bereits benutzten Installation.
- Passwoerter mit scrypt aus der Node-Standardbibliothek. Bewusst kein
Argon2: das braeuchte ein natives Modul passend zur Container-Plattform.
- Sitzungen in der Datenbank, im Cookie nur ein Zufallstoken; gespeichert
wird dessen SHA-256. Deaktivieren oder ein neues Passwort beendet alle
offenen Sitzungen sofort.
- Aussperrschutz: der letzte aktive Administrator kann sich nicht selbst
entmachten, deaktivieren oder loeschen. Der Schalter liegt in der .env,
nicht in der Oberflaeche - so bleibt der Weg zurueck immer offen.
- Ersteinrichtung legt den ersten Administrator an und schliesst sich danach.
- Die Weiterleitung /r/{slug} bleibt oeffentlich, sonst liesse sich kein
gedruckter Code mehr scannen.
Zwei Fehler dabei gefunden und behoben:
- 'return handleLogin(...)' innerhalb eines try-Blocks gibt das Promise
zurueck, bevor es sich aufloest. Die Ablehnung kam nie im catch an und
wurde zu einem nackten 500er statt einer 401. Jetzt mit await.
- Die Fehlerklassen wurden ueber instanceof erkannt. type-module.ts landet
aber sowohl im Server- als auch im Client-Buendel, es gibt also zwei
Klassenidentitaeten - saubere 400er wurden dadurch still zu 500ern. Die
Erkennung laeuft jetzt ueber eine Eigenschaft.
Geprueft: 51 neue Pruefungen fuer Anmeldung und die vollstaendige
Rollenmatrix, dazu die 200 bestehenden bei ausgeschalteter Anmeldung.
This commit is contained in:
+12
-1
@@ -26,7 +26,13 @@ function asRecord(value: unknown): Record<string, unknown> {
|
||||
: {};
|
||||
}
|
||||
|
||||
export function toQrCodeDto(code: QrCode): QrCodeDto {
|
||||
/** Ein Code samt der Beziehungen, die für die Anzeige gebraucht werden. */
|
||||
export type QrCodeWithRelations = QrCode & {
|
||||
group?: { name: string } | null;
|
||||
createdBy?: { name: string | null; email: string } | null;
|
||||
};
|
||||
|
||||
export function toQrCodeDto(code: QrCodeWithRelations): QrCodeDto {
|
||||
const data = asRecord(code.data);
|
||||
const qrType = getQrType(code.type);
|
||||
|
||||
@@ -65,5 +71,10 @@ export function toQrCodeDto(code: QrCode): QrCodeDto {
|
||||
lastScanAt: code.lastScanAt?.toISOString() ?? null,
|
||||
createdAt: code.createdAt.toISOString(),
|
||||
updatedAt: code.updatedAt.toISOString(),
|
||||
groupId: code.groupId,
|
||||
groupName: code.group?.name ?? null,
|
||||
createdByName: code.createdBy
|
||||
? (code.createdBy.name?.trim() || code.createdBy.email)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user