# HausPilot: Authentifizierungs- und Benutzerintegration ## Ergebnis der Boilerplate-Analyse HausPilot verwendet unveraendert die vorhandene Backend-for-Frontend- Authentifizierung. Das Boilerplate spricht keinen bestimmten Hersteller fest, sondern einen ueber `OIDC_ISSUER` konfigurierten OpenID-Connect-Provider. Der Login ist ein OIDC Authorization Code Flow mit PKCE, `state` und `nonce`. Der Browser startet den Login ueber `GET /api/auth/login`. Der Callback liegt fest unter `/api/auth/callback`. Der Backend-Callback validiert Issuer, Audience, Signaturalgorithmus, Nonce und Subject, laedt gegebenenfalls UserInfo und legt den lokalen Benutzer an oder aktualisiert ihn. Die stabile Identitaet beim Provider ist `(issuer, subject)`; fachliche Beziehungen verwenden ausschliesslich die interne UUID `users.id`. OIDC Access-, Refresh- und ID-Tokens werden verschluesselt in der MySQL-Tabelle `sessions` gespeichert. Der Browser erhaelt nur eine signierte, HttpOnly Session-ID und ein lesbares CSRF-Cookie. Schreibende Requests senden dieses Cookie ueber den vorhandenen `csrfInterceptor` als `X-CSRF-Token`. Idle- und Absolute-Timeout werden beim serverseitigen Session-Resolve geprueft. Es gibt keinen zweiten Token-Refresh im Browser. Der globale `PermissionsGuard` loest die Session auf, prueft den globalen Benutzerstatus und setzt `AuthenticatedRequest.user` mit interner UUID, Session-ID und effektiven Permissions. Controller verwenden weiterhin `@RequirePermissions(...)`. Deaktivierte Benutzer werden beim Login und bei jeder Session-Aufloesung abgewiesen; ihre historischen fachlichen Beziehungen werden nicht geloescht. Angular ermittelt den aktuellen Benutzer ueber `AuthService.ensureLoaded()` und `GET /api/me`. Der Auth-State liegt ausschliesslich in dessen Signals. Der vorhandene `permissionGuard` steuert nur Navigation und Darstellung; das Backend bleibt verbindlich. Logout erfolgt ausschliesslich ueber `/api/auth/logout`, widerruft die lokale Session, loescht Session- und CSRF-Cookie und verwendet danach den OIDC `end_session_endpoint` beziehungsweise `OIDC_LOGOUT_URL`. ## Registrierung und Benutzerprofil Das Boilerplate besitzt keinen lokalen Registrierungs- oder Passwortdialog und keine lokale Passwort-Entity. Konten werden durch den vorhandenen Identity Provider registriert oder bereitgestellt und beim ersten erfolgreichen OIDC- Login lokal synchronisiert. HausPilot fuehrt daher keine zweite Registrierung ein. Nach dem ersten Login werden offene Einladungen nur angezeigt, niemals automatisch angenommen. Die lokale `UserEntity` speichert UUID, Issuer, Subject, Anzeigename, E-Mail, Aktivstatus, globale Rollen und Einstellungen. Name und E-Mail werden bei jedem Login aus dem OIDC-Profil aktualisiert. Aktive Mitgliedschaften bleiben auch bei einer E-Mail-Aenderung ueber `users.id` stabil. Offene Einladungen bleiben an die normalisierte urspruengliche Zieladresse gebunden. Die Integration uebernimmt ausserdem den standardisierten OIDC-Claim `email_verified`. Eine Einladung kann nur angenommen werden, wenn der Provider die aktuelle Zieladresse als verifiziert bestaetigt. Fehlt diese Bestaetigung, wird die Annahme sicher abgewiesen. ## Globale und projektbezogene Autorisierung Globale Rollen (`admin`, `user` und verwaltete globale Rollen) bleiben von den HausPilot-Projektrollen getrennt. Eine globale Basis-Permission erlaubt nur die Verwendung der Projekt-API. Sie erzeugt weder eine Mitgliedschaft noch einen Zugriff auf ein privates Projekt. Insbesondere erhaelt ein globaler Administrator keinen impliziten Projektzugriff. Projektrollen sind `owner`, `administrator`, `editor` und `reader`. Jede Projektabfrage prueft serverseitig eine aktive Mitgliedschaft und die fuer die Aktion erforderliche Rolle. Unterentitaeten werden immer zusammen mit der Projekt-ID geladen beziehungsweise geprueft. Eigentuermer-, Autor- und Einladender-IDs sind keine DTO-Felder, sondern stammen aus dem vorhandenen serverseitigen Current-User-Kontext. Projektanlage, Eigentuemermitgliedschaft und Erstellungsaktivitaet werden in einer Datenbanktransaktion gespeichert. Projektrollen entstehen nur durch diese Projektanlage, explizite Einladungsannahme oder eine berechtigte Aenderung im Projekt; OIDC-Gruppen und globale Rollen werden nicht abgebildet. ## Einladungen und sicherer Rueckkehrpfad Einladungen speichern die normalisierte E-Mail-Adresse und optional die bekannte interne Benutzer-ID. Der zufaellige Einladungstoken wird nur im Link ausgegeben; in MySQL liegt ausschliesslich sein SHA-256-Hash. Annahme und Ablehnung verlangen eine gueltige bestehende Session. Das Backend prueft Status, Ablauf, Widerruf, Zieladresse, `email_verified`, aktiven Benutzer und eine noch nicht bestehende aktive Mitgliedschaft. Fehlermeldungen geben nur eine maskierte Adresse aus. Ist ein Besucher nicht angemeldet, verweist Angular auf den bestehenden `/api/auth/login`-Flow. Der gewuenschte Rueckweg wird serverseitig im kurzlebigen OIDC-Login-State gehalten. Erlaubt sind nur interne Pfade; Schemes, Protokoll-relative URLs und Backslashes werden verworfen. Nach dem Callback baut das Backend das Ziel relativ zu `FRONTEND_BASE_URL` auf. Tokens oder OIDC-Daten werden nie in Rueckkehrparametern gespeichert. ## Benachrichtigungen, Mail und Cleanup Das vorhandene `NotificationsService` erzeugt fuer bereits bekannte aktive Benutzer eine persoenliche In-App-Benachrichtigung. Normale Endpunkte bleiben auf den Session-Benutzer beschraenkt. Das Boilerplate hat keinen Mail-Service, keine Templates, Queue oder Retry-Jobs. HausPilot fuehrt keine parallele Mail-Infrastruktur ein; der Versandstatus einer Einladung wird daher explizit als `not_configured` gespeichert. Der Einladungsdatensatz bleibt konsistent und kann spaeter an eine architektonisch beschlossene Mail-Komponente angebunden werden. Projektseiten halten Daten nur komponentenlokal. Bei 401 setzt der vorhandene globale Auth-State den Benutzer zurueck; dadurch werden geschuetzte Seiten entfernt und das bestehende Notification-Polling samt personenbezogenem Cache gestoppt. Ein regulaerer Logout verlaesst die SPA und startet sie ohne alten In-Memory-State neu. HausPilot fuehrt keine Live-Verbindungen ein. ## Relevante Konfiguration - OIDC: `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_SCOPES`, `OIDC_ALLOWED_ALGORITHMS`, optional `OIDC_LOGOUT_URL` - Redirects: `APP_BASE_URL`, `FRONTEND_BASE_URL` - Session: `SESSION_COOKIE_NAME`, Idle-/Absolute-Timeout, `SESSION_SECRET`, `SESSION_ENCRYPTION_KEY` - Browser-Schutz: `CORS_ORIGINS`, `CSRF_HEADER_NAME`, Secure/SameSite-Cookies, Helmet, Rate Limits und Logging-Redaction Es wurde keine parallele Authentifizierungs-, Benutzer-, Passwort-, Token-, Registrierungs-, Mail-, Queue- oder Live-Connection-Infrastruktur eingefuehrt.