Skip to content

Commit 1e91890

Browse files
authored
fix(auth): Return session expired on revoke token (#2652)
1 parent a6e41e6 commit 1e91890

File tree

6 files changed

+131
-68
lines changed

6 files changed

+131
-68
lines changed

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/FetchAuthorizationSession/FetchIdentity/FetchAuthIdentityId.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ struct FetchAuthIdentityId: Action {
6565
}
6666

6767
func isNotAuthorizedError(_ error: Error) -> Bool {
68-
if case .client(let clientError, _) = error as? SdkError<GetIdOutputError>,
69-
case .retryError(let serviceError) = clientError,
70-
let sdkError = serviceError as? SdkError<GetIdOutputError>,
71-
case .service(let getIdError, _ ) = sdkError,
68+
69+
if let getIdError: GetIdOutputError = error.internalAWSServiceError(),
7270
case .notAuthorizedException = getIdError {
7371
return true
7472
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/FetchAuthorizationSession/InformSessionError.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ struct InformSessionError: Action {
3737
}
3838

3939
func isNotAuthorizedError(_ error: Error) -> Bool {
40-
if let initiateAuthError = error as? InitiateAuthOutputError,
41-
case .notAuthorizedException = initiateAuthError {
40+
41+
42+
if let serviceError: GetCredentialsForIdentityOutputError = error.internalAWSServiceError(),
43+
case .notAuthorizedException = serviceError {
4244
return true
4345
}
44-
if let initiateAuthError = error as? GetCredentialsForIdentityOutputError,
45-
case .notAuthorizedException = initiateAuthError {
46+
if let serviceError: InitiateAuthOutputError = error.internalAWSServiceError(),
47+
case .notAuthorizedException = serviceError {
4648
return true
4749
}
4850
return false

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Service/ErrorMapping/SdkError+AuthError.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,51 @@ extension SdkError: AuthErrorConvertible {
8282
}
8383

8484
}
85+
86+
extension Error {
87+
func internalAWSServiceError<E>() -> E? {
88+
if let internalError = self as? E {
89+
return internalError
90+
}
91+
92+
if let sdkError = self as? SdkError<E> {
93+
return sdkError.internalAWSServiceError()
94+
}
95+
return nil
96+
}
97+
}
98+
99+
extension SdkError {
100+
101+
func internalAWSServiceError<E>() -> E? {
102+
switch self {
103+
104+
case .service(let error, _):
105+
if let serviceError = error as? E {
106+
return serviceError
107+
}
108+
109+
case .client(let clientError, _):
110+
return clientError.internalAWSServiceError()
111+
112+
default: break
113+
114+
}
115+
return nil
116+
}
117+
}
118+
119+
extension ClientError {
120+
121+
func internalAWSServiceError<E>() -> E? {
122+
switch self {
123+
case .retryError(let retryError):
124+
if let sdkError = retryError as? SdkError<E> {
125+
return sdkError.internalAWSServiceError()
126+
}
127+
128+
default: break
129+
}
130+
return nil
131+
}
132+
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/ErrorMapping/SignInError+Helper.swift

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,80 +12,39 @@ import AWSCognitoIdentityProvider
1212

1313
extension SignInError {
1414

15-
var isUserUnConfirmed: Bool {
15+
var isUserNotConfirmed: Bool {
1616
switch self {
1717
case .service(error: let serviceError):
18-
if let cognitoError = serviceError as? SdkError<InitiateAuthOutputError>,
19-
case .service(let serviceError, _) = cognitoError,
20-
case .userNotConfirmedException = serviceError {
21-
return true
22-
} else if let cognitoError = serviceError as? SdkError<InitiateAuthOutputError>,
23-
case .client(let clientError, _) = cognitoError,
24-
case .retryError(let retryError) = clientError,
25-
let cognitoServiceError = retryError as? SdkError<InitiateAuthOutputError>,
26-
case .service(let internalServiceError, _) = cognitoServiceError,
27-
case .userNotConfirmedException = internalServiceError {
28-
return true
29-
} else if let cognitoError = serviceError as? SdkError<RespondToAuthChallengeOutputError>,
30-
case .service(let serviceError, _) = cognitoError,
31-
case .userNotConfirmedException = serviceError {
32-
return true
33-
} else if let cognitoError = serviceError as? SdkError<RespondToAuthChallengeOutputError>,
34-
case .client(let clientError, _) = cognitoError,
35-
case .retryError(let retryError) = clientError,
36-
let cognitoServiceError = retryError as? SdkError<RespondToAuthChallengeOutputError>,
37-
case .service(let internalServiceError, _) = cognitoServiceError,
38-
case .userNotConfirmedException = internalServiceError {
39-
return true
40-
} else if let cognitoError = serviceError as? InitiateAuthOutputError,
41-
case .userNotConfirmedException = cognitoError {
18+
19+
if let internalError: InitiateAuthOutputError = serviceError.internalAWSServiceError(),
20+
case .userNotConfirmedException = internalError {
4221
return true
43-
} else if let cognitoError = serviceError as? RespondToAuthChallengeOutputError,
44-
case .userNotConfirmedException = cognitoError {
22+
}
23+
24+
if let internalError: RespondToAuthChallengeOutputError = serviceError.internalAWSServiceError(),
25+
case .userNotConfirmedException = internalError {
4526
return true
4627
}
47-
return false
48-
default:
49-
return false
28+
default: break
5029
}
30+
return false
5131
}
5232

5333
var isResetPassword: Bool {
5434
switch self {
5535
case .service(error: let serviceError):
56-
if let cognitoError = serviceError as? SdkError<InitiateAuthOutputError>,
57-
case .service(let serviceError, _) = cognitoError,
58-
case .passwordResetRequiredException = serviceError {
36+
if let internalError: InitiateAuthOutputError = serviceError.internalAWSServiceError(),
37+
case .passwordResetRequiredException = internalError {
5938
return true
60-
} else if let cognitoError = serviceError as? SdkError<InitiateAuthOutputError>,
61-
case .client(let clientError, _) = cognitoError,
62-
case .retryError(let retryError) = clientError,
63-
let cognitoServiceError = retryError as? SdkError<InitiateAuthOutputError>,
64-
case .service(let internalServiceError, _) = cognitoServiceError,
65-
case .passwordResetRequiredException = internalServiceError {
66-
return true
67-
} else if let cognitoError = serviceError as? SdkError<RespondToAuthChallengeOutputError>,
68-
case .service(let serviceError, _) = cognitoError,
69-
case .passwordResetRequiredException = serviceError {
70-
return true
71-
} else if let cognitoError = serviceError as? SdkError<RespondToAuthChallengeOutputError>,
72-
case .client(let clientError, _) = cognitoError,
73-
case .retryError(let retryError) = clientError,
74-
let cognitoServiceError = retryError as? SdkError<RespondToAuthChallengeOutputError>,
75-
case .service(let internalServiceError, _) = cognitoServiceError,
76-
case .passwordResetRequiredException = internalServiceError {
77-
return true
78-
} else if let cognitoError = serviceError as? InitiateAuthOutputError,
79-
case .passwordResetRequiredException = cognitoError {
80-
return true
81-
} else if let cognitoError = serviceError as? RespondToAuthChallengeOutputError,
82-
case .passwordResetRequiredException = cognitoError {
39+
}
40+
41+
if let internalError: RespondToAuthChallengeOutputError = serviceError.internalAWSServiceError(),
42+
case .passwordResetRequiredException = internalError {
8343
return true
8444
}
85-
return false
86-
default:
87-
return false
45+
default: break
8846
}
47+
return false
8948
}
9049
}
9150

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Support/Helpers/UserPoolSignInHelper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct UserPoolSignInHelper {
5353
}
5454

5555
private static func validateError(signInError: SignInError) throws -> AuthSignInResult {
56-
if signInError.isUserUnConfirmed {
56+
if signInError.isUserNotConfirmed {
5757
return AuthSignInResult(nextStep: .confirmSignUp(nil))
5858
} else if signInError.isResetPassword {
5959
return AuthSignInResult(nextStep: .resetPassword(nil))

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/AuthorizationTests/AWSAuthFetchSignInSessionOperationTests.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import XCTest
1313
import AWSCognitoIdentity
1414
import AWSCognitoIdentityProvider
1515
import AWSPluginsCore
16+
import ClientRuntime
1617

1718
@testable import AWSPluginsTestCommon
1819

@@ -634,4 +635,59 @@ class AWSAuthFetchSignInSessionOperationTests: BaseAuthorizationTests {
634635
return
635636
}
636637
}
638+
639+
/// Test signedIn session with notAuthorized error
640+
///
641+
/// - Given: Given an auth plugin with signedIn state
642+
/// - When:
643+
/// - I invoke fetchAuthSession and mock notAuthorizedError
644+
/// - Then:
645+
/// - I should get an a valid session with the following details:
646+
/// - isSignedIn = true
647+
/// - aws credentails = .sessionExpired
648+
/// - identity id = .sessionExpired
649+
/// - cognito tokens = .sessionExpired
650+
///
651+
func testSignInSessionWithNotAuthorizedError() async throws {
652+
let initialState = AuthState.configured(
653+
AuthenticationState.signedIn(.testData),
654+
AuthorizationState.sessionEstablished(
655+
AmplifyCredentials.testDataWithExpiredTokens))
656+
657+
let initAuth: MockIdentityProvider.MockInitiateAuthResponse = { _ in
658+
let notAuthorized = InitiateAuthOutputError.notAuthorizedException(.init(message: "NotAuthorized"))
659+
let serviceError = SdkError<InitiateAuthOutputError>.service(notAuthorized, .init(body: .none, statusCode: .accepted))
660+
let clientError = ClientError.retryError(serviceError)
661+
throw SdkError<InitiateAuthOutputError>.client(clientError, nil)
662+
}
663+
664+
let plugin = configurePluginWith(
665+
userPool: { MockIdentityProvider(mockInitiateAuthResponse: initAuth) },
666+
initialState: initialState)
667+
668+
let session = try await plugin.fetchAuthSession(options: AuthFetchSessionRequest.Options())
669+
670+
XCTAssertTrue(session.isSignedIn)
671+
let credentialsResult = (session as? AuthAWSCredentialsProvider)?.getAWSCredentials()
672+
673+
guard case .failure(let error) = credentialsResult,
674+
case .sessionExpired = error else {
675+
XCTFail("Should return sessionExpired error")
676+
return
677+
}
678+
679+
let identityIdResult = (session as? AuthCognitoIdentityProvider)?.getIdentityId()
680+
guard case .failure(let identityIdError) = identityIdResult,
681+
case .sessionExpired = identityIdError else {
682+
XCTFail("Should return sessionExpired error")
683+
return
684+
}
685+
686+
let tokensResult = (session as? AuthCognitoTokensProvider)?.getCognitoTokens()
687+
guard case .failure(let tokenError) = tokensResult,
688+
case .sessionExpired = tokenError else {
689+
XCTFail("Should return sessionExpired error")
690+
return
691+
}
692+
}
637693
}

0 commit comments

Comments
 (0)