diff --git a/aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPlugin.kt b/aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPlugin.kt index 391e17d4d..497f9e54e 100644 --- a/aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPlugin.kt +++ b/aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPlugin.kt @@ -1820,12 +1820,18 @@ internal class RealAWSCognitoAuthPlugin( when (authState.authNState) { is AuthenticationState.SignedIn -> { GlobalScope.async { - val accessToken = getSession().userPoolTokensResult.value?.accessToken - accessToken?.run { - val userid = SessionHelper.getUserSub(accessToken) ?: "" - val username = SessionHelper.getUsername(accessToken) ?: "" - onSuccess.accept(AuthUser(userid, username)) - } ?: onError.accept(InvalidUserPoolConfigurationException()) + val userPoolToken = getSession().userPoolTokensResult + val userPoolTokenResultError = userPoolToken.error + if (userPoolTokenResultError != null && userPoolTokenResultError is SessionExpiredException) { + onError.accept(userPoolTokenResultError) + } else { + val accessToken = userPoolToken.value?.accessToken + accessToken?.run { + val userid = SessionHelper.getUserSub(accessToken) ?: "" + val username = SessionHelper.getUsername(accessToken) ?: "" + onSuccess.accept(AuthUser(userid, username)) + } ?: onError.accept(InvalidUserPoolConfigurationException()) + } } } is AuthenticationState.SignedOut -> { diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPluginTest.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPluginTest.kt index 1ac6db3d3..3099bca7f 100644 --- a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPluginTest.kt +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPluginTest.kt @@ -52,6 +52,7 @@ import com.amplifyframework.auth.AuthCodeDeliveryDetails import com.amplifyframework.auth.AuthDevice import com.amplifyframework.auth.AuthException import com.amplifyframework.auth.AuthSession +import com.amplifyframework.auth.AuthUser import com.amplifyframework.auth.AuthUserAttribute import com.amplifyframework.auth.AuthUserAttributeKey import com.amplifyframework.auth.MFAType @@ -59,6 +60,7 @@ import com.amplifyframework.auth.TOTPSetupDetails import com.amplifyframework.auth.cognito.exceptions.configuration.InvalidUserPoolConfigurationException import com.amplifyframework.auth.cognito.helpers.AuthHelper import com.amplifyframework.auth.cognito.helpers.SRPHelper +import com.amplifyframework.auth.cognito.helpers.SessionHelper import com.amplifyframework.auth.cognito.options.AWSCognitoAuthResendUserAttributeConfirmationCodeOptions import com.amplifyframework.auth.cognito.options.AWSCognitoAuthSignInOptions import com.amplifyframework.auth.cognito.options.AWSCognitoAuthUpdateUserAttributeOptions @@ -67,6 +69,7 @@ import com.amplifyframework.auth.cognito.options.AWSCognitoAuthVerifyTOTPSetupOp import com.amplifyframework.auth.cognito.options.AuthFlowType import com.amplifyframework.auth.cognito.usecases.ResetPasswordUseCase import com.amplifyframework.auth.exceptions.InvalidStateException +import com.amplifyframework.auth.exceptions.SessionExpiredException import com.amplifyframework.auth.exceptions.SignedOutException import com.amplifyframework.auth.options.AuthConfirmResetPasswordOptions import com.amplifyframework.auth.options.AuthConfirmSignUpOptions @@ -91,6 +94,7 @@ import com.amplifyframework.statemachine.codegen.data.DeviceMetadata import com.amplifyframework.statemachine.codegen.data.SignInMethod import com.amplifyframework.statemachine.codegen.data.SignedInData import com.amplifyframework.statemachine.codegen.data.UserPoolConfiguration +import com.amplifyframework.statemachine.codegen.errors.SessionError import com.amplifyframework.statemachine.codegen.states.AuthState import com.amplifyframework.statemachine.codegen.states.AuthenticationState import com.amplifyframework.statemachine.codegen.states.AuthorizationState @@ -242,6 +246,100 @@ class RealAWSCognitoAuthPluginTest { verify(exactly = 0) { onSuccess.accept(any()) } } + @Test + fun testGetCurrentUserSucceedsIfSignedIn() { + // GIVEN + val onSuccess = mockk>() + val onError = mockk>() + mockkObject(SessionHelper) + every { SessionHelper.getUsername(any()) } returns "username" + every { SessionHelper.getUserSub(any()) } returns "sub" + // WHEN + plugin.getCurrentUser(onSuccess, onError) + + // THEN + verify { onSuccess.accept(any()) } + verify(exactly = 0) { onError.accept(any()) } + } + + @Test + fun testGetCurrentUserFailsWithInvalidStateException() { + // GIVEN + val onSuccess = mockk>() + val onError = mockk>(relaxed = true) + + setupCurrentAuthState(authNState = AuthenticationState.NotConfigured()) + + // WHEN + plugin.getCurrentUser(onSuccess, onError) + + // THEN + verify(exactly = 0) { onSuccess.accept(any()) } + verify { onError.accept(InvalidStateException()) } + } + + @Test + fun testGetCurrentUserFailsWithSignedOutException() { + // GIVEN + val onSuccess = mockk>() + val onError = mockk>(relaxed = true) + + setupCurrentAuthState( + authNState = AuthenticationState.SignedOut(mockk()), + authZState = AuthorizationState.Configured() + ) + // WHEN + plugin.getCurrentUser(onSuccess, onError) + + // THEN + verify(exactly = 0) { onSuccess.accept(any()) } + verify { onError.accept(SignedOutException()) } + } + + @Test + fun testGetCurrentUserFailsWithExpiredSessionException() { + // GIVEN + val onGetCurrentUserSuccess = mockk>() + val onGetCurrentUserError = mockk>(relaxed = true) + val sessionExpiredException = SessionExpiredException() + val sessionError = SessionError(sessionExpiredException, credentials) + val authNState = AuthenticationState.SignedIn( + mockk { + every { username } returns "username" + }, + mockk() + ) + val authZState = AuthorizationState.Error(sessionError) + + setupCurrentAuthState( + authNState = authNState, + authZState = authZState + ) + + val sessionErrorState = mockk { + every { this@mockk.authNState } returns AuthenticationState.SignedIn( + mockk { + every { username } returns "username" + }, + mockk() + ) + every { this@mockk.authZState } returns AuthorizationState.Error(sessionError) + } + + every { + authStateMachine.listen(any(), captureLambda(), null) + } answers { + lambda<(AuthState) -> Unit>().invoke(sessionErrorState) + } + + // WHEN + plugin.getCurrentUser(onGetCurrentUserSuccess, onGetCurrentUserError) + + // THEN + verify(exactly = 0) { onGetCurrentUserSuccess.accept(any()) } + verify(timeout = 1000L) { onGetCurrentUserError.accept(sessionExpiredException) } + } + @Test fun testCustomSignInWithSRPSucceedsWithChallenge() { // GIVEN