# 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