feat(auth): Client-Secret in den Einstellungen pflegen, Warnung vor Ablauf

Das Secret der App-Registrierung laeuft in Entra ab. Bisher hiess das: jemand
mit SSH-Zugang aendert die .env und startet den Dienst neu - und niemand sieht
vorher, wann es soweit ist. Laeuft es aus, stehen Anmeldung UND
Postfachabgleich still, denn beide haengen an derselben Registrierung.

Neu unter Einstellungen > Anmeldung: Secret eintragen, Ablaufdatum hinterlegen,
Restlaufzeit ablesen. Ab 30 Tagen vor dem Ablauf bekommen Administratoren ueber
jeder Ansicht ein Hinweisband, das direkt dorthin fuehrt; nach dem Ablauf wird
es rot. Der Hinweis reist mit /api/badges mit, das die App ohnehin bei jedem
Laden abruft.

Bewusst so entschieden:
  - Das Secret muss dafuer in die Datenbank, entgegen der bisherigen Regel
    "keine Geheimnisse in crm_settings". Es liegt deshalb AES-256-GCM-
    verschluesselt dort; der Schluessel kommt aus CRM_ENCRYPTION_KEY, ersatz-
    weise JWT_SECRET, und steht damit nie im selben Dump.
  - Vor dem Speichern holt das CRM mit dem eingegebenen Wert ein Token bei
    Microsoft. Ein Tippfehler wird gar nicht erst uebernommen.
  - Gelesen wird Datenbank vor .env; der .env-Wert bleibt Rueckfallebene, und
    "Hinterlegtes Secret verwerfen" schaltet dorthin zurueck.
  - Passt der Schluessel nicht mehr, meldet die Oberflaeche das ausdruecklich,
    statt still auf die .env zurueckzufallen - sonst sucht man den Fehler an
    der falschen Stelle.
  - Das Ablaufdatum wird von Hand eingetragen. Aus Entra lesen braeuchte
    Application.Read.All, die die App bewusst nicht hat.

MAIL_CONFIGURED und SSO_CONFIGURED sind dadurch von Konstanten zu den
Funktionen mailConfigured() und ssoConfigured() geworden - die Pruefung muss
jetzt in die Datenbank sehen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-09-21 08:38:28 +02:00
co-authored by Claude Opus 5
parent e271f5c1e8
commit c8eaaa1947
22 changed files with 937 additions and 64 deletions
+6
View File
@@ -66,6 +66,7 @@ mitten im Scrapen beenden.
| `MS_SSO_ENABLED` | Anmeldung über Microsoft, Standard aus, nur `true` schaltet ein |
| `MS_SSO_REDIRECT_URI` | Umleitungsadresse, zeichengenau wie in Entra eingetragen |
| `MS_SSO_ALLOWED_DOMAINS` | Positivliste von E-Mail-Domains, leer = keine zusätzliche Prüfung |
| `CRM_ENCRYPTION_KEY` | verschlüsselt das in der Oberfläche hinterlegte Client-Secret; fehlt er, dient `JWT_SECRET` als Schlüssel |
Die Scanner-Datenbank wird beim Start automatisch angelegt
(`CREATE DATABASE IF NOT EXISTS`), Tabellen kommen aus `sequelize.sync()`, Portale
@@ -84,6 +85,11 @@ Die `MS_SSO_*`-Werte gehören zur Anmeldung über Microsoft und nutzen dieselbe
App-Registrierung wie das Postfach. Ohne sie bleibt es bei Benutzername und
Passwort. Einrichtung: [13 Anmeldung über Microsoft](13-anmeldung-sso.md).
`MS_CLIENT_SECRET` ist seit dem 21.09.2026 nur noch die Rückfallebene: Vorrang
hat das Secret, das Administratoren unter *Einstellungen → Anmeldung* eintragen.
Es liegt verschlüsselt in `crm_settings`, wird bei jedem Bedarf frisch gelesen
und braucht deshalb **keinen** Neustart.
## Playwright
`playwright` ist auf **exakt 1.60.0** gepinnt. Der passende Chromium-Build