diff --git a/CHANGELOG.md b/CHANGELOG.md index 2935241..c6cd0a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ # Changelog +## 1.1.6 (2024-08-13) + +### Bug Fixes +- **Authenticator**: Properly handling expired sessions when loading the component (#87) + ## 1.1.5 (2024-07-02) ### Bug Fixes -- **Authenticator**: Settting corner radius according to the theme (#84) +- **Authenticator**: Setting corner radius according to the theme (#84) ## 1.1.4 (2024-06-07) diff --git a/Sources/Authenticator/Configuration/AmplifyConfiguration.swift b/Sources/Authenticator/Configuration/AmplifyConfiguration.swift index d13485c..2722571 100644 --- a/Sources/Authenticator/Configuration/AmplifyConfiguration.swift +++ b/Sources/Authenticator/Configuration/AmplifyConfiguration.swift @@ -106,11 +106,25 @@ struct AmplifyConfiguration { } } + var hasIdentityPool = false + if let cognitoConfiguration = configuration.value(at: "CredentialsProvider.CognitoIdentity.Default"), + case .string(let poolId) = cognitoConfiguration["PoolId"], !poolId.isEmpty { + hasIdentityPool = true + } + + var hasUserPool = false + if let cognitoConfiguration = configuration.value(at: "CognitoUserPool.Default"), + case .string(let poolId) = cognitoConfiguration["PoolId"], !poolId.isEmpty { + hasUserPool = true + } + self.cognito = CognitoConfiguration( usernameAttributes: usernameAttributes, signupAttributes: signUpAttributes, passwordProtectionSettings: passwordProtectionSettings, - verificationMechanisms: verificationMechanisms + verificationMechanisms: verificationMechanisms, + hasUserPool: hasUserPool, + hasIdentityPool: hasIdentityPool ) } } @@ -179,12 +193,18 @@ struct CognitoConfiguration { return .username } + var hasUserPool: Bool + var hasIdentityPool: Bool + static var empty: CognitoConfiguration { .init( usernameAttributes: [], signupAttributes: [], passwordProtectionSettings: .init(minLength: 0, characterPolicy: []), - verificationMechanisms: []) + verificationMechanisms: [], + hasUserPool: false, + hasIdentityPool: false + ) } } diff --git a/Sources/Authenticator/Constants/ComponentInformation.swift b/Sources/Authenticator/Constants/ComponentInformation.swift index 8322a33..a999414 100644 --- a/Sources/Authenticator/Constants/ComponentInformation.swift +++ b/Sources/Authenticator/Constants/ComponentInformation.swift @@ -8,6 +8,6 @@ import Foundation public class ComponentInformation { - public static let version = "1.1.5" + public static let version = "1.1.6" public static let name = "amplify-ui-swift-authenticator" } diff --git a/Sources/Authenticator/Models/AuthenticatorState.swift b/Sources/Authenticator/Models/AuthenticatorState.swift index e2899ec..c02a3b2 100644 --- a/Sources/Authenticator/Models/AuthenticatorState.swift +++ b/Sources/Authenticator/Models/AuthenticatorState.swift @@ -88,9 +88,16 @@ public class AuthenticatorState: ObservableObject, AuthenticatorStateProtocol { let authSession = try await authenticationService.fetchAuthSession(options: nil) if authSession.isSignedIn { - let user = try await authenticationService.getCurrentUser() - log.info("The user is signed in, going to signedIn step") - setCurrentStep(.signedIn(user: user)) + // The user has previously signed in, but validate if the session is still valid + if isSessionValid(authSession) { + log.info("The user is signed in, going to signedIn step") + let user = try await authenticationService.getCurrentUser() + setCurrentStep(.signedIn(user: user)) + } else { + log.info("The user's credentials have expired. Signing out and going to signedOut step") + _ = await Amplify.Auth.signOut() + setCurrentStep(signedOutStep) + } } else { log.info("The user is not signed in, going to signedOut step") setCurrentStep(signedOutStep) @@ -103,6 +110,25 @@ public class AuthenticatorState: ObservableObject, AuthenticatorStateProtocol { } } + private func isSessionValid(_ session: AuthSession) -> Bool { + guard let cognitoSession = session as? AWSAuthCognitoSession else { + // Consider non-Cognito sessions to be valid if it's signed in + return session.isSignedIn + } + + if configuration.hasIdentityPool, case .failure(_) = cognitoSession.getIdentityId() { + log.verbose("Could not fetch Identity ID") + return false + } + + if configuration.hasUserPool, case .failure(_) = cognitoSession.getCognitoTokens(){ + log.verbose("Could not fetch Cognito Tokens") + return false + } + + return true + } + private func setUserAgentSuffix() { guard let plugin = try? Amplify.Auth.getPlugin(for: "awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin else { log.error("Unable to retrieve the AWSCognitoAuthPlugin") diff --git a/Tests/AuthenticatorTests/Mocks/MockAuthenticatorState.swift b/Tests/AuthenticatorTests/Mocks/MockAuthenticatorState.swift index 5ed4aa0..85944d2 100644 --- a/Tests/AuthenticatorTests/Mocks/MockAuthenticatorState.swift +++ b/Tests/AuthenticatorTests/Mocks/MockAuthenticatorState.swift @@ -15,7 +15,9 @@ class MockAuthenticatorState: AuthenticatorStateProtocol { usernameAttributes: [], signupAttributes: [], passwordProtectionSettings: .init(minLength: 0, characterPolicy: []), - verificationMechanisms: [] + verificationMechanisms: [], + hasUserPool: true, + hasIdentityPool: true ) var setCurrentStepCount = 0