V 2.2.1 Anmeldung per Passkey (WebAuthn)

Passkey-Login analog zu werte-next: auf der Login-Seite "Mit Passkey
anmelden", Verwaltung der eigenen Passkeys im neuen Tab Einstellungen.
Das Passwort bleibt als Alternative bestehen.

- lib/webauthn.ts, lib/passkeys.ts sowie API-Routen unter /api/passkey
- proxy.ts: /api/passkey/authenticate ohne Session erreichbar
- TabLayout: dritter Tab Einstellungen (Index-Tabs statt Route wie werte)
- RP-Konfiguration ueber AUSGABEN_RP_*, da sich die .env auf dem Server
  mit anderen Apps teilt, die RP_ID/RP_ORIGIN bereits belegen
- Eigene Tabelle ausgaben_passkeys aus demselben Grund: werte-next nutzt
  in der gemeinsamen Datenbank RXF bereits die Tabelle passkeys
- eslint.config.mjs auf die Flat-Config von eslint-config-next umgestellt

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-09 16:35:35 +02:00
parent de28922784
commit d3718da1f8
21 changed files with 1070 additions and 21 deletions
+27
View File
@@ -66,6 +66,33 @@ Falls die Tabelle `Ausgaben` noch nicht existiert:
mysql -u root -p RXF < create_table.sql
```
Das Script legt auch die Tabelle `ausgaben_passkeys` für die Passkey-Anmeldung an. Die
Anwendung erstellt diese Tabelle beim ersten Zugriff selbst — hat der DB-Benutzer
keine CREATE-Rechte, das SQL aus `create_table.sql` manuell ausführen.
### Passkeys (WebAuthn) konfigurieren
Im Container erwartet die Anwendung `RP_ID`, `RP_ORIGIN` und `RP_NAME`. In der
Compose-Datei werden diese aus den **app-eigenen** Variablen `AUSGABEN_RP_*`
befüllt — mit den Produktionswerten als Default:
```yaml
- RP_ID=${AUSGABEN_RP_ID:-ausgaben.fuerst-stuttgart.de}
- RP_ORIGIN=${AUSGABEN_RP_ORIGIN:-https://ausgaben.fuerst-stuttgart.de}
- RP_NAME=${AUSGABEN_RP_NAME:-Ausgaben-Log}
```
**Warum eigene Namen**: Auf dem Server (`/opt/stacks/myapp/`) laufen mehrere Apps im
selben Stack und teilen sich eine `.env`. Dort sind `RP_ID`/`RP_ORIGIN` bereits für
werte-next gesetzt. Würde diese App dieselben Namen lesen, bekäme sie werte's Host —
und die Passkey-Anmeldung schlüge fehl. Die Defaults oben greifen, solange in der
geteilten `.env` keine `AUSGABEN_RP_*` stehen; ein Eintrag dort überschreibt sie.
**Wichtig**: `RP_ID` muss exakt dem Hostnamen entsprechen (ohne `https://` und ohne
Port), `RP_ORIGIN` der vollen URL. Passen die Werte nicht zur aufgerufenen Adresse,
schlägt die Passkey-Anmeldung fehl. Bereits registrierte Passkeys werden bei einer
Änderung von `RP_ID` ungültig. WebAuthn setzt HTTPS voraus (via Traefik).
### Datenbank-Verbindung
Die Anwendung verwendet die gleiche MySQL-Datenbank wie die alte Ausgaben-Anwendung: