From ecf760d9ec5e611661b0ff63b3ae14aa21699c3d Mon Sep 17 00:00:00 2001 From: cogwheel0 <172976095+cogwheel0@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:44:05 +0530 Subject: [PATCH] feat(auth): Enhance logout flow with comprehensive data clearing --- lib/core/auth/api_auth_interceptor.dart | 1 - lib/core/auth/auth_cache_manager.dart | 4 +-- lib/core/auth/auth_state_manager.dart | 27 +++++++++++++++---- .../services/optimized_storage_service.dart | 6 ++++- .../services/secure_credential_storage.dart | 5 ++-- .../auth/views/connection_issue_page.dart | 13 +++++++++ 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/lib/core/auth/api_auth_interceptor.dart b/lib/core/auth/api_auth_interceptor.dart index b9c46d9..e935ee6 100644 --- a/lib/core/auth/api_auth_interceptor.dart +++ b/lib/core/auth/api_auth_interceptor.dart @@ -174,7 +174,6 @@ class ApiAuthInterceptor extends Interceptor { /// Clear auth token and notify callbacks /// Note: This should only be called for explicit logout, not for connection errors - void _clearAuthToken() { _authToken = null; final future = onTokenInvalidated?.call(); diff --git a/lib/core/auth/auth_cache_manager.dart b/lib/core/auth/auth_cache_manager.dart index 0ce001d..2be9fa8 100644 --- a/lib/core/auth/auth_cache_manager.dart +++ b/lib/core/auth/auth_cache_manager.dart @@ -100,11 +100,11 @@ class AuthCacheManager { DebugLogger.storage('Cache entry cleared: $key'); } - /// Clear all auth-related cache + /// Clear all auth-related cache including server configs void clearAuthCache() { _cache.clear(); _cacheTimestamps.clear(); - DebugLogger.storage('All auth cache cleared'); + DebugLogger.storage('All auth cache cleared (including server configs and custom headers)'); } /// Clear expired cache entries diff --git a/lib/core/auth/auth_state_manager.dart b/lib/core/auth/auth_state_manager.dart index 681565a..b9678de 100644 --- a/lib/core/auth/auth_state_manager.dart +++ b/lib/core/auth/auth_state_manager.dart @@ -677,7 +677,7 @@ class AuthStateManager extends _$AuthStateManager { } } - /// Logout user + /// Logout user and clear all data including server configs and custom headers Future logout() async { _update( (current) => @@ -699,14 +699,20 @@ class AuthStateManager extends _$AuthStateManager { } } - // Clear all local auth data + // Clear all local auth data (including server configs with custom headers) final storage = ref.read(optimizedStorageServiceProvider); await storage.clearAuthData(); _updateApiServiceToken(null); // Clear active server to force return to server connection page await storage.setActiveServerId(null); + + // Invalidate all auth-related providers to clear cached data ref.invalidate(activeServerProvider); + ref.invalidate(serverConfigsProvider); + + // Clear auth cache manager + _cacheManager.clearAuthCache(); // Update state _update( @@ -719,7 +725,7 @@ class AuthStateManager extends _$AuthStateManager { ), ); - DebugLogger.auth('Logout complete'); + DebugLogger.auth('Logout complete - all data cleared including server configs and custom headers'); } catch (e, stack) { DebugLogger.error( 'logout-failed', @@ -729,8 +735,19 @@ class AuthStateManager extends _$AuthStateManager { ); // Even if logout fails, clear local state where possible final storage = ref.read(optimizedStorageServiceProvider); + try { + await storage.clearAuthData(); + } catch (clearError) { + DebugLogger.error( + 'logout-clear-failed', + scope: 'auth/state', + error: clearError, + ); + } await storage.setActiveServerId(null); ref.invalidate(activeServerProvider); + ref.invalidate(serverConfigsProvider); + _cacheManager.clearAuthCache(); _update( (current) => current.copyWith( @@ -739,8 +756,8 @@ class AuthStateManager extends _$AuthStateManager { clearToken: true, clearUser: true, error: - 'Logout error: $e. Secure credentials may remain stored; ' - 'please clear them from your device keychain.', + 'Logout error: $e. Some data may remain stored; ' + 'please clear app data from your device settings if needed.', ), ); _updateApiServiceToken(null); diff --git a/lib/core/services/optimized_storage_service.dart b/lib/core/services/optimized_storage_service.dart index bfb3fd1..4dc0585 100644 --- a/lib/core/services/optimized_storage_service.dart +++ b/lib/core/services/optimized_storage_service.dart @@ -395,11 +395,15 @@ class OptimizedStorageService { // --------------------------------------------------------------------------- // Batch operations // --------------------------------------------------------------------------- + /// Clear all authentication-related data including credentials, tokens, + /// server configurations, and custom headers Future clearAuthData() async { await Future.wait([ deleteAuthToken(), deleteSavedCredentials(), _preferencesBox.delete(_activeServerIdKey), + // Clear server configurations (which include custom headers) + _secureCredentialStorage.clearAll(), ]); _cache.removeWhere( @@ -416,7 +420,7 @@ class OptimizedStorageService { ); DebugLogger.log( - 'Auth data cleared in batch operation', + 'Auth data cleared in batch operation (including server configs and custom headers)', scope: 'storage/optimized', ); } diff --git a/lib/core/services/secure_credential_storage.dart b/lib/core/services/secure_credential_storage.dart index 2ef6a52..1bdc7b7 100644 --- a/lib/core/services/secure_credential_storage.dart +++ b/lib/core/services/secure_credential_storage.dart @@ -280,11 +280,12 @@ class SecureCredentialStorage { } } - /// Clear all secure data + /// Clear all secure data including credentials, tokens, and server configurations + /// (which contain custom headers) Future clearAll() async { try { await _secureStorage.deleteAll(); - DebugLogger.storage('clear-ok', scope: 'credentials'); + DebugLogger.storage('clear-ok (all secure data including server configs with custom headers)', scope: 'credentials'); } catch (e) { DebugLogger.error('clear-failed', scope: 'credentials', error: e); } diff --git a/lib/features/auth/views/connection_issue_page.dart b/lib/features/auth/views/connection_issue_page.dart index 3fc0468..8c017de 100644 --- a/lib/features/auth/views/connection_issue_page.dart +++ b/lib/features/auth/views/connection_issue_page.dart @@ -12,6 +12,7 @@ import '../../../core/widgets/error_boundary.dart'; import '../../../l10n/app_localizations.dart'; import '../../../shared/theme/theme_extensions.dart'; import '../../../shared/widgets/conduit_components.dart'; +import '../../../shared/widgets/themed_dialogs.dart'; import '../providers/unified_auth_providers.dart'; class ConnectionIssuePage extends ConsumerStatefulWidget { @@ -248,6 +249,18 @@ class _ConnectionIssuePageState extends ConsumerState { } Future _logout(AppLocalizations l10n) async { + // Show confirmation dialog before logging out + final confirm = await ThemedDialogs.confirm( + context, + title: l10n.signOut, + message: l10n.endYourSession, + confirmText: l10n.signOut, + isDestructive: true, + ); + + if (!mounted) return; + if (!confirm) return; + setState(() { _isLoggingOut = true; _statusMessage = null;