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>
4.0 KiB
4.0 KiB
Changelog
Alle nennenswerten Änderungen an Laufzettel werden in dieser Datei dokumentiert.
Das Format basiert auf Keep a Changelog, und dieses Projekt folgt Semantic Versioning.
[Unveröffentlicht]
Hinzugefügt
- Projektgerüst: Next 16 mit App Router und TypeScript strict, Tailwind 4, Vitest 5, Playwright 1.63, ESLint flat config, Prettier, husky mit lint-staged und commitlint (#005)
- Gestaltung: Design-Token als CSS-Variablen, selbst gehostete Schriften, Wortmarke und
Bildmarke
[ ✓ ], Versionsanzeige unten links (#005) - Betriebsstand mit Docker Compose: die Datenbank ist von außen nicht erreichbar — kein veröffentlichter Port und ein Netz ohne Gateway; Migrationen laufen beim Start in einem eigenen Einmal-Dienst, der Seed bleibt ein bewusster Handgriff (#005)
- Healthcheck
GET /api/gesundheitund Sicherheitskopfzeilen samt CSP-Nonce je Anfrage (#005) - shadcn/ui eingerichtet: sein Variablen-Vertrag wird aus den Laufzettel-Token gespeist, damit kopierte Bauteile ohne Nacharbeit passen (#005)
pnpm pruefe:dokuhält Dokumentation und Code zusammen: Version im Changelog, Issue-Dateien gegen ihre Übersicht, keine Verweise auf fehlende Dateien, keine fehlenden Bilder (#005)pnpm docs:screenshotserzeugt Screenshots reproduzierbar und prüft dabei gleich, dass am Handy nicht horizontal gescrollt wird (#005)- Issues, Labels und Meilensteine für alle vier Phasen im Gitea-Tracker (#001–#019)
- Vollständiges Datenmodell in deutscher Benennung: 20 Tabellen, 9 Aufzählungen, erste Migration, idempotenter Seed für Betriebsmodus, eigene Organisation und Administrator (#006)
- Erzeugung der
tagCodes für die QR-Aufkleber, mit Vergabebuch, aus dem nie gelöscht wird — 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,
stateundnonce; 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
- Der Compose-Stand bricht ab, wenn
APP_SECRET,POSTGRES_PASSWORDoderAPP_URLfehlen, statt mit Standardwerten zu starten (#005) - Die Mandantengrenze steht als zusammengesetzter Fremdschlüssel in der Datenbank: ein Lauf kann strukturell kein Gerät, keine Person und keine Abteilung eines fremden Kunden wählen (#006)
- Ein Bind-Passwort ohne Versionspräfix wird von der Datenbank abgewiesen, ein versehentlich im 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.examplewäre sonst eine offene Weiterleitung gewesen (#007) - Alle Umleitungen gehen über
APP_URLstatt ü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 aufLESERherabzustufen (#007) - Der letzte aktive Administrator kann sich weder herabstufen noch abschalten (#007)
- Beim Abschalten eines Kontos werden laufende Sitzungen sofort ungültig (#007)