feat(auth): Anmeldung, Rollen und Benutzerverwaltung (#21)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

OIDC mit Discovery, PKCE, state und nonce; lokaler Login mit argon2 als
Notfallzugang; Rechte in einer Tabelle, Prüfung ausschließlich serverseitig,
Rolle und Aktiv-Status pro Anfrage aus der Datenbank.

Ein unabhängiger Review fand eine offene Weiterleitung: die Präfix-Prüfung des
Rücksprungziels ließ /<TAB>/fremd.example durch, woraus der Browser
//fremd.example macht. Das Ziel wird jetzt aufgelöst und die Herkunft
verglichen. Dazu acht weitere Befunde, alle behoben.

274 Tests.

Closes #7

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #21.
This commit is contained in:
2026-09-25 01:35:02 +00:00
co-authored by Claude Opus 5
parent 7a0f875f55
commit 40e95dbe5f
43 changed files with 3426 additions and 56 deletions
+21
View File
@@ -30,6 +30,16 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
ein Code kommt auch nach dem Löschen eines Geräts nicht zurück (#006)
- Verschlüsselung von Geheimnissen mit AES-256-GCM aus `APP_SECRET`, für das LDAP-Bind-Passwort
und später die Zugangsdaten der Connectoren (#006)
- Anmeldung über einen generischen OIDC-Anbieter mit Discovery, PKCE, `state` und `nonce`;
unbekannte Benutzer entstehen beim ersten Login, die Rolle kommt bei jeder Anmeldung neu aus
den Gruppen (#007)
- Lokale Anmeldung mit E-Mail und Passwort als Notfallzugang, nur bei `AUTH_LOCAL_ENABLED=true`
(#007)
- Rechte in einer Tabelle mit vier Rollen; geprüft ausschließlich serverseitig, Rolle und
Aktiv-Status pro Anfrage aus der Datenbank (#007)
- Benutzerverwaltung für Administratoren: Rolle setzen, Konto abschalten, lokales Konto
anlegen (#007)
- Navigation zeigt nur, was die eigene Rolle darf (#007)
### Sicherheit
@@ -41,3 +51,14 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
Klartext geschriebenes fällt damit sofort auf (#006)
- Ein Lauf nimmt seine Schrittergebnisse und Kommentare beim Löschen nicht mehr mit, und ein
Protokolleintrag kann seinen Urheber nicht mehr verlieren (#006)
- Das Rücksprungziel nach der Anmeldung wird aufgelöst und gegen die eigene Herkunft geprüft,
statt nur Präfixe zu vergleichen — `/<TAB>/fremd.example` wäre sonst eine offene Weiterleitung
gewesen (#007)
- Alle Umleitungen gehen über `APP_URL` statt über die Herkunft der Anfrage; hinter einem Reverse
Proxy zeigten sie sonst auf den internen Host (#007)
- Eine Anmeldung über den Anbieter verknüpft nur mit einem bestehenden Konto, wenn die Adresse
bestätigt ist (#007)
- Ohne eingerichtete `OIDC_GROUP_*`-Zuordnung bleibt die Rolle unangetastet, statt jeden auf
`LESER` herabzustufen (#007)
- Der letzte aktive Administrator kann sich weder herabstufen noch abschalten (#007)
- Beim Abschalten eines Kontos werden laufende Sitzungen sofort ungültig (#007)