Commit Graph
3 Commits
Author SHA1 Message Date
ScarriffleandClaude Opus 5 08f8267dcc fix(auth): SSO-Korrekturen aus dem Review + stiller Token-Refresh
Drei Fehler, die den Flow gebrochen haetten:

- Ein Abbruch im Browser liefert bei AppAuth ein regulaeres Ergebnis mit
  USER_CANCELED_AUTH_FLOW, nicht null. Der bisherige Null-Check lief ins
  Leere und "Zurueck" endete in einer roten Fehlermeldung.
- launch(intent) lag ausserhalb von runCatching. Verlaesst der Nutzer den
  Screen waehrend der Discovery, ist der Result-Launcher abgemeldet und die
  IllegalStateException haette die App beendet.
- Nonce und Provider lagen nur in ViewModel-Feldern. Der Custom Tab laeuft
  in eigener Task, dieser Prozess wird dabei routinemaessig getoetet — die
  Anmeldung waere nach erfolgreichem Login beim IdP gescheitert. Der Nonce
  kommt jetzt aus AuthorizationResponse.request, Provider und Client-ID
  werden vor dem Start persistiert.

Weiter: AuthState.update verlangt genau eines von (Response, Exception) und
haette bei null/null geworfen; onCleared() verwarf den @Singleton-Service
fuer die zweite AuthViewModel-Instanz mit.

Neu ist der geforderte Hintergrund-Refresh: laeuft das Calendarr-Token
binnen 24 h ab, wird beim Start ueber den Provider-Refresh-Token ein frisches
ID-Token geholt und getauscht — ohne Browser. Best effort; schlaegt es fehl,
bleibt das vorhandene Token in Kraft.

Ausserdem: Scopes kommen ausschliesslich vom Server (mobile_scopes), Spinner
pro Provider statt global, fehlender Browser als eigener Fehlerfall, Issuer
wird validiert, keine namenlosen Identitaeten mehr.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 18:33:36 +02:00
ScarriffleandClaude Opus 5 8b0af0f44a feat(auth): SSO-Anmeldung ueber OpenID Connect (AppAuth)
Zusaetzlicher Anmeldeweg neben Benutzername/Passwort. Der Login-Screen holt
die konfigurierten Provider von GET /api/auth/oidc/providers; ohne Provider
oder gegen einen aelteren Server bleibt der Screen unveraendert.

Die App laeuft als Public Client: Authorization Code Flow mit PKCE in einem
Chrome Custom Tab (nie ein WebView), ohne Client Secret. Das ID-Token wird
anschliessend an POST /api/auth/oidc/exchange gegen ein Calendarr-Token
getauscht; die Antwort hat dieselbe Form wie der Passwort-Login, sodass der
bestehende Session-Pfad unveraendert weiterlaeuft.

- OidcAuthenticator kapselt Discovery, PKCE-Request und Code-Tausch.
- Die angefragten Scopes kommen vom Server (mobile_scopes) — ein Scope, den
  der Provider nicht kennt, wuerde die ganze Anfrage scheitern lassen.
- AuthState mit dem Refresh-Token liegt in den EncryptedSharedPreferences,
  nie im Klartext, und wird beim Logout mitgeloescht.
- Provider und Client-ID werden vor dem Browser-Start persistiert, weil der
  Custom Tab in einer eigenen Task laeuft und dieser Prozess dabei getoetet
  werden kann; der Nonce kommt aus AuthorizationResponse.request, das AppAuth
  ueber den Redirect zurueckreicht.
- Abbruch im Browser meldet AppAuth als regulaeres Ergebnis mit
  USER_CANCELED_AUTH_FLOW und wird still behandelt, nicht als Fehler.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 18:25:15 +02:00
ScarriffleandClaude Opus 4.8 9ced441935 feat: event reminders UI, per-calendar mute, notifications, default duration
- Add reminder editor (presets + custom number+unit) wired through save
- Per-calendar reminder mute: filter-sheet toggle + greyed-out editor hint;
  reminders are kept, never deleted
- New AlarmManager-based NotificationScheduler + channel + POST_NOTIFICATIONS;
  skips muted calendars
- New synced setting default_event_duration_minutes for new events

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 10:02:46 +02:00