leistungsbilanz-ts/docs/authentication.md
Grovy311 c56cfb30ad Add login-required user management (admin/user roles, Config->Benutzer)
No self-signup: admins create every account in Config -> Benutzer with a
typed start password; a forced password change gates first use. Session-
cookie auth protects all /api/* routes; /api/users additionally requires
the admin role. See docs/authentication.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 19:51:47 +02:00

2.9 KiB
Raw Blame History

Anmeldung und Benutzerverwaltung

Die Leistungsbilanz verlangt eine Anmeldung. Es gibt kein Self-Signup: jeder Zugang wird von einem Administrator über Config → Benutzer angelegt.

Rollen

Es gibt genau zwei Rollen (src/shared/constants/user-roles.ts):

  • admin – wie user, zusätzlich Zugriff auf den Config-Bereich (Benutzerverwaltung, eigenes Konto)
  • user – volle Nutzung der Leistungsbilanz (Projekte, Stromkreislisten, Grobbilanz, …), kein Zugriff auf Config

Es gibt (bewusst, siehe unten) keine konfigurierbare Rechte-Matrix und keine Verknüpfung mit einer Mitarbeiter-/Personen-Stammdatentabelle.

Ablauf beim Anlegen eines Zugangs

  1. Ein Administrator öffnet Config → Benutzer und legt einen neuen Zugang mit Anmeldename, Name, Rolle und einem Startpasswort an, das er selbst eintippt.
  2. Der Zugang startet mit mustChangePassword = true.
  3. Beim ersten Anmelden zeigt die Oberfläche statt der App ein Formular, das ein eigenes Passwort verlangt, bevor es weitergeht.
  4. "Passwort zurücksetzen" (ebenfalls in Config → Benutzer) setzt ein neues Startpasswort und mustChangePassword wieder auf true – z. B. wenn jemand sein Passwort vergessen hat.

Technischer Aufbau

  • Datenmodell: Tabelle users (src/db/schema/users.ts) – username, passwordHash (scrypt, src/server/auth/password.ts), name, role, active, mustChangePassword.
  • Sessions: In-Memory-Store (src/server/auth/sessions.ts), Cookie lb_session, sliding expiry (AUTH_SESSION_HOURS, Standard 12h). Ein Neustart der API beendet alle Sessions – für einen Single-Container-Dienst ein akzeptabler Kompromiss gegenüber einer persistierten Session-Tabelle.
  • Middleware: src/server/auth/auth.middleware.ts schützt /api/* (außer /api/auth/login, /api/auth/status, /api/auth/logout) und erzwingt den Passwortwechsel, solange mustChangePassword gesetzt ist. /api/users/* verlangt zusätzlich die Rolle admin.
  • Frontend: AuthProvider lädt /api/auth/me; LoginGate (src/app/layout.tsx) zeigt Login- bzw. Passwortformular, solange nicht angemeldet bzw. mustChangePassword gesetzt ist, sonst die App.

Bootstrap-Admin

AUTH_BOOTSTRAP_USERNAME / AUTH_BOOTSTRAP_PASSWORT (Env-Variablen, siehe compose.yaml) legen beim ersten Start einen Admin an – nur falls die users-Tabelle noch komplett leer ist. Danach werden diese Variablen ignoriert; jeder weitere Zugang entsteht über Config → Benutzer. Die Werte gehören in eine lokale, nicht versionierte .env auf dem Deploy-Host, nicht in compose.yaml selbst.

Bewusst nicht umgesetzt (Stand jetzt)

  • Konfigurierbare Rechte-Matrix statt fixer admin/user-Rollen
  • Konten-Sperre nach Fehlversuchen
  • E-Mail-/Einmal-Link-Passwortvergabe, OIDC/Entra-Anmeldung
  • Verknüpfung von Zugängen mit einer Mitarbeiter-Stammdatentabelle