refactor: debug logs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
/// Consistent authentication interceptor for all API requests
|
||||
/// Implements security requirements from OpenAPI specification
|
||||
@@ -77,8 +77,8 @@ class ApiAuthInterceptor extends Interceptor {
|
||||
final requiresAuth = _requiresAuth(path);
|
||||
final hasOptionalAuth = _hasOptionalAuth(path);
|
||||
|
||||
debugPrint(
|
||||
'DEBUG: Auth interceptor for $path - requires: $requiresAuth, optional: $hasOptionalAuth, token present: ${_authToken != null}',
|
||||
DebugLogger.auth(
|
||||
'Auth interceptor for $path - requires: $requiresAuth, optional: $hasOptionalAuth, token present: ${_authToken != null}',
|
||||
);
|
||||
|
||||
if (requiresAuth) {
|
||||
@@ -109,12 +109,14 @@ class ApiAuthInterceptor extends Interceptor {
|
||||
customHeaders.forEach((key, value) {
|
||||
// Don't override critical headers that we manage
|
||||
final lowerKey = key.toLowerCase();
|
||||
if (lowerKey != 'authorization' &&
|
||||
lowerKey != 'content-type' &&
|
||||
if (lowerKey != 'authorization' &&
|
||||
lowerKey != 'content-type' &&
|
||||
lowerKey != 'accept') {
|
||||
options.headers[key] = value;
|
||||
} else {
|
||||
debugPrint('WARNING: Skipping reserved header override attempt: $key');
|
||||
DebugLogger.warning(
|
||||
'Skipping reserved header override attempt: $key',
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -134,20 +136,20 @@ class ApiAuthInterceptor extends Interceptor {
|
||||
// Handle authentication errors consistently
|
||||
if (statusCode == 401) {
|
||||
// 401 always indicates invalid/expired auth token
|
||||
debugPrint('DEBUG: 401 Unauthorized on $path - clearing auth token');
|
||||
DebugLogger.auth('401 Unauthorized on $path - clearing auth token');
|
||||
_clearAuthToken();
|
||||
} else if (statusCode == 403) {
|
||||
// 403 on protected endpoints indicates insufficient permissions or invalid token
|
||||
final requiresAuth = _requiresAuth(path);
|
||||
final optionalAuth = _hasOptionalAuth(path);
|
||||
if (requiresAuth && !optionalAuth) {
|
||||
debugPrint(
|
||||
'DEBUG: 403 Forbidden on protected endpoint $path - clearing auth token',
|
||||
DebugLogger.auth(
|
||||
'403 Forbidden on protected endpoint $path - clearing auth token',
|
||||
);
|
||||
_clearAuthToken();
|
||||
} else {
|
||||
debugPrint(
|
||||
'DEBUG: 403 Forbidden on public/optional endpoint $path - keeping auth token',
|
||||
DebugLogger.auth(
|
||||
'403 Forbidden on public/optional endpoint $path - keeping auth token',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'auth_state_manager.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
/// Comprehensive caching manager for auth-related operations
|
||||
/// Reduces redundant operations and improves app performance
|
||||
@@ -31,13 +31,13 @@ class AuthCacheManager {
|
||||
void cacheUserData(dynamic userData) {
|
||||
_cache[_userDataKey] = userData;
|
||||
_cacheTimestamps[_userDataKey] = DateTime.now();
|
||||
debugPrint('DEBUG: User data cached');
|
||||
DebugLogger.storage('User data cached');
|
||||
}
|
||||
|
||||
/// Get cached user data
|
||||
dynamic getCachedUserData() {
|
||||
if (_isCacheValid(_userDataKey, _mediumCache)) {
|
||||
debugPrint('DEBUG: Using cached user data');
|
||||
DebugLogger.storage('Using cached user data');
|
||||
return _cache[_userDataKey];
|
||||
}
|
||||
return null;
|
||||
@@ -97,14 +97,14 @@ class AuthCacheManager {
|
||||
void clearCacheEntry(String key) {
|
||||
_cache.remove(key);
|
||||
_cacheTimestamps.remove(key);
|
||||
debugPrint('DEBUG: Cache entry cleared: $key');
|
||||
DebugLogger.storage('Cache entry cleared: $key');
|
||||
}
|
||||
|
||||
/// Clear all auth-related cache
|
||||
void clearAuthCache() {
|
||||
_cache.clear();
|
||||
_cacheTimestamps.clear();
|
||||
debugPrint('DEBUG: All auth cache cleared');
|
||||
DebugLogger.storage('All auth cache cleared');
|
||||
}
|
||||
|
||||
/// Clear expired cache entries
|
||||
@@ -125,7 +125,9 @@ class AuthCacheManager {
|
||||
}
|
||||
|
||||
if (expiredKeys.isNotEmpty) {
|
||||
debugPrint('DEBUG: Cleaned ${expiredKeys.length} expired cache entries');
|
||||
DebugLogger.storage(
|
||||
'Cleaned ${expiredKeys.length} expired cache entries',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +170,9 @@ class AuthCacheManager {
|
||||
_cacheTimestamps.remove(key);
|
||||
}
|
||||
|
||||
debugPrint('DEBUG: Cache optimized, removed $entriesToRemove old entries');
|
||||
DebugLogger.storage(
|
||||
'Cache optimized, removed $entriesToRemove old entries',
|
||||
);
|
||||
}
|
||||
|
||||
/// Cache state from AuthState for quick access
|
||||
|
||||
@@ -5,6 +5,7 @@ import '../providers/app_providers.dart';
|
||||
import '../models/user.dart';
|
||||
import 'token_validator.dart';
|
||||
import 'auth_cache_manager.dart';
|
||||
import '../utils/debug_logger.dart';
|
||||
|
||||
/// Comprehensive auth state representation
|
||||
@immutable
|
||||
@@ -95,10 +96,10 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
final token = await storage.getAuthToken();
|
||||
|
||||
if (token != null && token.isNotEmpty) {
|
||||
debugPrint('DEBUG: Found stored token during initialization: ${token.substring(0, 10)}...');
|
||||
DebugLogger.auth('Found stored token during initialization');
|
||||
// Validate token before setting authenticated state
|
||||
final isValid = await _validateToken(token);
|
||||
debugPrint('DEBUG: Token validation result: $isValid');
|
||||
DebugLogger.auth('Token validation result: $isValid');
|
||||
if (isValid) {
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.authenticated,
|
||||
@@ -114,7 +115,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
_loadUserData();
|
||||
} else {
|
||||
// Token is invalid, clear it
|
||||
debugPrint('DEBUG: Token validation failed, deleting token');
|
||||
DebugLogger.auth('Token validation failed, deleting token');
|
||||
await storage.deleteAuthToken();
|
||||
state = state.copyWith(
|
||||
status: AuthStatus.unauthenticated,
|
||||
@@ -167,19 +168,19 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
|
||||
// Use API key directly as Bearer token
|
||||
final tokenStr = apiKey.trim();
|
||||
|
||||
|
||||
// Validate token format (consistent with credentials method)
|
||||
if (!_isValidTokenFormat(tokenStr)) {
|
||||
throw Exception('Invalid API key format');
|
||||
}
|
||||
|
||||
|
||||
// Update API service with the API key
|
||||
_updateApiServiceToken(tokenStr);
|
||||
|
||||
// Validate by attempting to fetch user info
|
||||
try {
|
||||
await api.getCurrentUser(); // Just validate, don't store user data yet
|
||||
|
||||
|
||||
// Save token to storage
|
||||
final storage = _ref.read(optimizedStorageServiceProvider);
|
||||
await storage.saveAuthToken(tokenStr);
|
||||
@@ -191,7 +192,8 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
// Store API key as a special credential type
|
||||
await storage.saveCredentials(
|
||||
serverId: activeServer.id,
|
||||
username: 'api_key_user', // Special username to indicate API key auth
|
||||
username:
|
||||
'api_key_user', // Special username to indicate API key auth
|
||||
password: tokenStr, // Store API key in password field
|
||||
);
|
||||
await storage.setRememberCredentials(true);
|
||||
@@ -215,7 +217,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
// Load user data in background (consistent with credentials method)
|
||||
_loadUserData();
|
||||
|
||||
debugPrint('DEBUG: API key login successful');
|
||||
DebugLogger.auth('API key login successful');
|
||||
return true;
|
||||
} catch (e) {
|
||||
// If user fetch fails, the API key might be invalid
|
||||
@@ -300,7 +302,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
// Load user data in background
|
||||
_loadUserData();
|
||||
|
||||
debugPrint('DEBUG: Login successful');
|
||||
DebugLogger.auth('Login successful');
|
||||
return true;
|
||||
} catch (e) {
|
||||
debugPrint('ERROR: Login failed: $e');
|
||||
@@ -399,7 +401,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
|
||||
/// Handle token invalidation (called by API service)
|
||||
Future<void> onTokenInvalidated() async {
|
||||
debugPrint('DEBUG: Auth token invalidated');
|
||||
DebugLogger.auth('Auth token invalidated');
|
||||
|
||||
// Clear token from storage
|
||||
final storage = _ref.read(optimizedStorageServiceProvider);
|
||||
@@ -416,7 +418,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
// Attempt silent re-login if credentials are available
|
||||
final hasCredentials = await storage.getSavedCredentials() != null;
|
||||
if (hasCredentials) {
|
||||
debugPrint('DEBUG: Attempting silent re-login after token invalidation');
|
||||
DebugLogger.auth('Attempting silent re-login after token invalidation');
|
||||
await silentLogin();
|
||||
}
|
||||
}
|
||||
@@ -449,7 +451,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
clearError: true,
|
||||
);
|
||||
|
||||
debugPrint('DEBUG: Logout complete');
|
||||
DebugLogger.auth('Logout complete');
|
||||
} catch (e) {
|
||||
debugPrint('ERROR: Logout failed: $e');
|
||||
// Even if logout fails, clear local state
|
||||
@@ -470,7 +472,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
if (state.token != null) {
|
||||
final jwtUserInfo = TokenValidator.extractUserInfo(state.token!);
|
||||
if (jwtUserInfo != null) {
|
||||
debugPrint('DEBUG: Extracted user info from JWT token');
|
||||
DebugLogger.auth('Extracted user info from JWT token');
|
||||
state = state.copyWith(user: jwtUserInfo);
|
||||
|
||||
// Still try to load from server in background for complete data
|
||||
@@ -502,7 +504,7 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
|
||||
final user = await api.getCurrentUser();
|
||||
state = state.copyWith(user: user);
|
||||
debugPrint('DEBUG: Loaded complete user data from server');
|
||||
DebugLogger.auth('Loaded complete user data from server');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Warning: Failed to load server user data: $e');
|
||||
@@ -527,8 +529,8 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
// Check cache first
|
||||
final cachedResult = TokenValidationCache.getCachedResult(token);
|
||||
if (cachedResult != null) {
|
||||
debugPrint(
|
||||
'DEBUG: Using cached token validation result: ${cachedResult.isValid}',
|
||||
DebugLogger.auth(
|
||||
'Using cached token validation result: ${cachedResult.isValid}',
|
||||
);
|
||||
return cachedResult.isValid;
|
||||
}
|
||||
@@ -571,13 +573,13 @@ class AuthStateManager extends StateNotifier<AuthState> {
|
||||
validationUser != null &&
|
||||
state.isAuthenticated) {
|
||||
state = state.copyWith(user: validationUser);
|
||||
debugPrint('DEBUG: Cached user data from token validation');
|
||||
DebugLogger.auth('Cached user data from token validation');
|
||||
}
|
||||
|
||||
TokenValidationCache.cacheResult(token, serverResult);
|
||||
|
||||
debugPrint(
|
||||
'DEBUG: Server token validation: ${serverResult.isValid} - ${serverResult.message}',
|
||||
DebugLogger.auth(
|
||||
'Server token validation: ${serverResult.isValid} - ${serverResult.message}',
|
||||
);
|
||||
return serverResult.isValid;
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user