Enhance AuthenticationService with proper error handling

- Add AuthenticationError enum for domain-specific error handling
- Add attemptAutoLogin method for automatic credential-based authentication
- Improve error handling and logging for credential retrieval
- Support 24-hour token expiry validation
This commit is contained in:
David Collado 2025-07-02 23:30:49 +02:00 committed by Peter Steinberger
parent 8f20a0ef26
commit 7975c4b916

View file

@ -218,27 +218,40 @@ final class AuthenticationService: ObservableObject {
/// Attempt automatic login using stored credentials for a server profile
func attemptAutoLogin(profile: ServerProfile) async throws {
logger.debug("attemptAutoLogin called for profile: \(profile.name) (id: \(profile.id)), isAuthenticated: \(isAuthenticated)")
logger.debug("Profile requiresAuth: \(profile.requiresAuth), username: \(profile.username ?? "nil")")
// Check if we already have valid authentication
if isAuthenticated {
let tokenValid = await verifyToken()
if tokenValid {
logger.info("Already authenticated with valid token")
logger.info("Already authenticated with valid token for user: \(currentUser ?? "unknown")")
return
} else {
logger.warning("Token verification failed, will attempt fresh login")
}
}
// Get stored password from keychain
guard let password = try? KeychainService.getPassword(for: profile.id) else {
logger.debug("No stored password found for profile: \(profile.name)")
// Check if profile requires authentication
if !profile.requiresAuth {
logger.debug("Profile does not require authentication, but server requires it - treating as credentials not found")
throw AuthenticationError.credentialsNotFound
}
// Get stored password from keychain
do {
let password = try KeychainService.getPassword(for: profile.id)
logger.debug("Successfully retrieved password from keychain for profile: \(profile.name)")
logger.debug("Password length: \(password.count) characters")
// Get username from profile or use default
guard let username = profile.username else {
logger.error("No username configured for profile: \(profile.name)")
throw AuthenticationError.credentialsNotFound
}
logger.debug("Attempting authentication with username: \(username)")
// Attempt authentication with stored credentials
do {
try await authenticateWithPassword(username: username, password: password)
@ -257,6 +270,19 @@ final class AuthenticationService: ObservableObject {
}
throw AuthenticationError.invalidCredentials
}
} catch let keychainError {
logger.error("Failed to retrieve password from keychain for profile: \(profile.name), error: \(keychainError)")
logger.debug("Looking for keychain item with account: server-\(profile.id)")
if let keychainErr = keychainError as? KeychainService.KeychainError {
switch keychainErr {
case .itemNotFound:
logger.debug("Keychain item not found for profile id: \(profile.id)")
default:
logger.error("Keychain error: \(keychainErr)")
}
}
throw AuthenticationError.credentialsNotFound
}
}
// MARK: - Private Methods