fix: Soft-Logout darf nie mehr destruktiv enden (onSoftLogout-Guard)
Qualitäts-Review-Befund (b): Der Refresh-Token-Fix (9dc83f7) war richtig analysiert, aber unvollständig – drei Restlücken gegen das matrix-SDK 6.2.0 verifiziert und geschlossen: 1. Client._handleSoftLogout ruft bei JEDEM Refresh-Fehler logout() auf, und logout() macht 'finally clear()' – die lokale Session inkl. Krypto-Schlüssel wird selbst bei einem transienten Netzwerkfehler zerstört. Mit refreshToken:true laufen Access-Tokens künftig ab, Refreshes werden Routine – das Restrisiko wäre also GESTIEGEN. Fix: eigener onSoftLogout-Handler (soft_logout_guard.dart) mit 3 Versuchen, der nie wirft → SDK ruft nie logout() auf; bei Dauerfehler bleibt der Client soft-logged-out und der nächste Sync versucht es erneut (CLAUDE.md: Fehlerpfade dürfen NIE in einem stillen Logout enden). 2. Das Push-Hintergrund-Isolate (background_push.dart) teilt sich die pyramid.sqlite mit der Haupt-App; getEventByPushNotification() ruft ensureNotSoftLoggedOut() auf. Ohne Guard hätte ein Refresh-Fehler im Isolate (inkl. Token-Rotations-Race mit der Haupt-App) die Session der GESAMTEN App gelöscht. Guard auch dort gesetzt; das Race heilt der Retry, weil refreshAccessToken() den Token bei jedem Versuch frisch aus der DB liest. 3. isLoggedInProvider behandelte softLoggedOut wie ausgeloggt – die UI wäre bei jedem Routine-Token-Refresh kurz auf den Login-Screen gesprungen (für Nutzer nicht von einem 'Random Logout' zu unterscheiden). Jetzt zählt nur echtes loggedOut. UNGETESTET (Pi) – gehört zum selben ausstehenden PC-Praxistest wie9dc83f7: Login → Nachrichten → Logout → Neu-Login → alte Nachrichten lesbar; zusätzlich auth_log.txt auf die neuen Guard-Einträge prüfen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -110,6 +110,11 @@ final isLoggedInProvider = StreamProvider<bool>((ref) async* {
|
||||
final client = await ref.watch(matrixClientProvider.future);
|
||||
yield client.isLogged();
|
||||
await for (final loginState in client.onLoginStateChanged.stream) {
|
||||
yield loginState == mx.LoginState.loggedIn;
|
||||
// softLoggedOut ist KEIN Logout: Die Session existiert lokal weiter, das
|
||||
// SDK versucht gerade einen stillen Token-Refresh. Würde hier `false`
|
||||
// geliefert, spränge die UI bei jedem Routine-Refresh kurz auf den
|
||||
// Login-Screen – für Nutzer nicht von einem „Random Logout" zu
|
||||
// unterscheiden. Nur ein echtes loggedOut zählt.
|
||||
yield loginState != mx.LoginState.loggedOut;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user