From 5684f34c6d245998c00b612b100646a4ef7836c1 Mon Sep 17 00:00:00 2001 From: Harsh <6162866+harsh62@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:04:53 -0400 Subject: [PATCH] fix(Auth): Throw error if hosted UI is not presented during sign out (#3769) * fix(Auth): Throw error if hosted UI is not presented during sign out * add unit test for hostedUI error * fix swift lint * Update AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignOut/ShowHostedUISignOut.swift Co-authored-by: Sebastian Villena <97059974+ruisebas@users.noreply.github.com> * Update AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignOut/ShowHostedUISignOut.swift Co-authored-by: Sebastian Villena <97059974+ruisebas@users.noreply.github.com> * worked on review comments --------- Co-authored-by: Sebastian Villena <97059974+ruisebas@users.noreply.github.com> --- .../Actions/SignOut/ShowHostedUISignOut.swift | 52 ++++++++----------- .../CodeGen/Errors/HostedUIError.swift | 4 ++ .../CodeGen/Errors/SignOutError.swift | 18 +++++-- .../CodeGen/Events/SignOutEvent.swift | 8 +-- .../ErrorMapping/SignInError+Helper.swift | 13 ++++- .../SignOut/SignOutState+Resolver.swift | 4 +- .../Constants/AuthPluginErrorConstants.swift | 4 ++ .../SignOut/ShowHostedUISignOutTests.swift | 36 +++++-------- .../Mocks/MockData/SignedInData+Mock.swift | 11 ++++ .../AuthorizationTestData.swift | 6 +++ .../SignOutStateNotStartedTests.swift | 2 +- .../SignOutStateRevokingTokenTests.swift | 2 +- .../SignOutStateSigningOutGloballyTests.swift | 2 +- .../SignOutStateSigningOutLocallyTests.swift | 2 +- .../AWSAuthSignOutTaskTests.swift | 20 +++++++ 15 files changed, 116 insertions(+), 68 deletions(-) diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignOut/ShowHostedUISignOut.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignOut/ShowHostedUISignOut.swift index 6d64dbf93a..4ff593f96d 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignOut/ShowHostedUISignOut.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignOut/ShowHostedUISignOut.swift @@ -26,17 +26,14 @@ class ShowHostedUISignOut: NSObject, Action { guard let environment = environment as? AuthEnvironment, let hostedUIEnvironment = environment.hostedUIEnvironment else { - let message = AuthPluginErrorConstants.configurationError - let error = AuthenticationError.configuration(message: message) + let error = HostedUIError.pluginConfiguration(AuthPluginErrorConstants.configurationError) await sendEvent(with: error, dispatcher: dispatcher, environment: environment) return } let hostedUIConfig = hostedUIEnvironment.configuration - guard let callbackURL = URL(string: hostedUIConfig.oauth.signOutRedirectURI), let callbackURLScheme = callbackURL.scheme else { - let error = AuthenticationError.configuration(message: "Callback URL could not be retrieved") - await sendEvent(with: error, dispatcher: dispatcher, environment: environment) + await sendEvent(with: HostedUIError.signOutRedirectURI, dispatcher: dispatcher, environment: environment) return } @@ -48,13 +45,7 @@ class ShowHostedUISignOut: NSObject, Action { callbackScheme: callbackURLScheme, inPrivate: false, presentationAnchor: signOutEvent.presentationAnchor) - await sendEvent(with: nil, dispatcher: dispatcher, environment: environment) - - } catch HostedUIError.signOutURI { - let error = AuthenticationError.configuration(message: "Could not create logout URL") - await sendEvent(with: error, dispatcher: dispatcher, environment: environment) - return } catch { self.logVerbose("\(#fileID) Received error \(error)", environment: environment) await sendEvent(with: error, dispatcher: dispatcher, environment: environment) @@ -65,32 +56,33 @@ class ShowHostedUISignOut: NSObject, Action { dispatcher: EventDispatcher, environment: Environment) async { - var hostedUIError: AWSCognitoHostedUIError? - if let hostedUIInternalError = error as? HostedUIError, - case .cancelled = hostedUIInternalError { - let event = SignOutEvent(eventType: .userCancelled) - self.logVerbose("\(#fileID) Sending event \(event.type)", environment: environment) - await dispatcher.send(event) - return - } - - if let error = error as? AuthErrorConvertible { - hostedUIError = AWSCognitoHostedUIError(error: error.authError) + let event: SignOutEvent + if let hostedUIInternalError = error as? HostedUIError { + event = SignOutEvent(eventType: .hostedUISignOutError(hostedUIInternalError)) + } else if let error = error as? AuthErrorConvertible { + event = getEvent(for: AWSCognitoHostedUIError(error: error.authError)) } else if let error = error { - let serviceError = AuthError.service("HostedUI failed with error", - "", error) - hostedUIError = AWSCognitoHostedUIError(error: serviceError) + let serviceError = AuthError.service( + "HostedUI failed with error", + "", + error + ) + event = getEvent(for: AWSCognitoHostedUIError(error: serviceError)) + } else { + event = getEvent(for: nil) } - let event: SignOutEvent + self.logVerbose("\(#fileID) Sending event \(event.type)", environment: environment) + await dispatcher.send(event) + } + + private func getEvent(for hostedUIError: AWSCognitoHostedUIError?) -> SignOutEvent { if self.signOutEvent.globalSignOut { - event = SignOutEvent(eventType: .signOutGlobally(self.signInData, + return SignOutEvent(eventType: .signOutGlobally(self.signInData, hostedUIError: hostedUIError)) } else { - event = SignOutEvent(eventType: .revokeToken(self.signInData, + return SignOutEvent(eventType: .revokeToken(self.signInData, hostedUIError: hostedUIError)) } - self.logVerbose("\(#fileID) Sending event \(event.type)", environment: environment) - await dispatcher.send(event) } } diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/HostedUIError.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/HostedUIError.swift index d8ba2e8ef1..d87ec3c106 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/HostedUIError.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/HostedUIError.swift @@ -15,6 +15,8 @@ enum HostedUIError: Error { case signOutURI + case signOutRedirectURI + case proofCalculation case codeValidation @@ -23,6 +25,8 @@ enum HostedUIError: Error { case serviceMessage(String) + case pluginConfiguration(String) + case cancelled case invalidContext diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/SignOutError.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/SignOutError.swift index cfd962d247..7aaff48375 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/SignOutError.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Errors/SignOutError.swift @@ -10,7 +10,7 @@ import Amplify enum SignOutError: Error { - case userCancelled + case hostedUI(HostedUIError) case localSignOut } @@ -18,10 +18,22 @@ enum SignOutError: Error { extension SignOutError: AuthErrorConvertible { var authError: AuthError { switch self { - case .userCancelled: - return AuthError.service("", "", AWSCognitoAuthError.userCancelled) + case .hostedUI(let error): + return error.authError case .localSignOut: return AuthError.unknown("", nil) } } } + +extension SignOutError: Equatable { + static func == (lhs: SignOutError, rhs: SignOutError) -> Bool { + switch (lhs, rhs) { + case (.hostedUI, .hostedUI), + (.localSignOut, .localSignOut): + return true + default: + return false + } + } +} diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Events/SignOutEvent.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Events/SignOutEvent.swift index 4d30ec5a38..3d223e5a7a 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Events/SignOutEvent.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Events/SignOutEvent.swift @@ -41,7 +41,7 @@ struct SignOutEvent: StateMachineEvent { case signedOutFailure(AuthenticationError) - case userCancelled + case hostedUISignOutError(HostedUIError) } let id: String @@ -66,8 +66,8 @@ struct SignOutEvent: StateMachineEvent { return "SignOutEvent.globalSignOutError" case .signOutGuest: return "SignOutEvent.signOutGuest" - case .userCancelled: - return "SignOutEvent.userCancelled" + case .hostedUISignOutError: + return "SignOutEvent.hostedUISignOutError" } } @@ -94,7 +94,7 @@ extension SignOutEvent.EventType: Equatable { (.signedOutFailure, .signedOutFailure), (.globalSignOutError, .globalSignOutError), (.signOutGuest, .signOutGuest), - (.userCancelled, .userCancelled): + (.hostedUISignOutError, .hostedUISignOutError): return true default: return false diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/ErrorMapping/SignInError+Helper.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/ErrorMapping/SignInError+Helper.swift index 2a5630d898..a6e21bced9 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/ErrorMapping/SignInError+Helper.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/ErrorMapping/SignInError+Helper.swift @@ -74,10 +74,15 @@ extension HostedUIError: AuthErrorConvertible { AuthPluginErrorConstants.hostedUITokenURI.recoverySuggestion) case .signOutURI: - return .service( + return .configuration( AuthPluginErrorConstants.hostedUISignOutURI.errorDescription, AuthPluginErrorConstants.hostedUISignOutURI.recoverySuggestion) + case .signOutRedirectURI: + return .configuration( + AuthPluginErrorConstants.hostedUISignOutRedirectURI.errorDescription, + AuthPluginErrorConstants.hostedUISignOutRedirectURI.recoverySuggestion) + case .proofCalculation: return .invalidState( AuthPluginErrorConstants.hostedUIProofCalculation.errorDescription, @@ -107,11 +112,15 @@ extension HostedUIError: AuthErrorConvertible { case .unableToStartASWebAuthenticationSession: return .service( AuthPluginErrorConstants.hostedUIUnableToStartASWebAuthenticationSession.errorDescription, - AuthPluginErrorConstants.hostedUIUnableToStartASWebAuthenticationSession.recoverySuggestion) + AuthPluginErrorConstants.hostedUIUnableToStartASWebAuthenticationSession.recoverySuggestion, + AWSCognitoAuthError.errorLoadingUI) case .serviceMessage(let message): return .service(message, AuthPluginErrorConstants.serviceError) + case .pluginConfiguration(let message): + return .configuration(message, AuthPluginErrorConstants.configurationError) + case .unknown: return .unknown("WebUI signIn encountered an unknown error", nil) diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/Resolvers/SignOut/SignOutState+Resolver.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/Resolvers/SignOut/SignOutState+Resolver.swift index 37e5ec4f04..17523862b4 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/Resolvers/SignOut/SignOutState+Resolver.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/Resolvers/SignOut/SignOutState+Resolver.swift @@ -117,9 +117,9 @@ extension SignOutState { newState: SignOutState.revokingToken, actions: [action] ) - case .userCancelled: + case .hostedUISignOutError(let error): let action = CancelSignOut(signedInData: signedInData) - return .init(newState: .error(.userCancelled), actions: [action]) + return .init(newState: .error(.hostedUI(error)), actions: [action]) default: return .from(oldState) } diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Support/Constants/AuthPluginErrorConstants.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Support/Constants/AuthPluginErrorConstants.swift index b6bbdfff89..ab899e5682 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Support/Constants/AuthPluginErrorConstants.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Support/Constants/AuthPluginErrorConstants.swift @@ -56,6 +56,10 @@ enum AuthPluginErrorConstants { "SignOut URI could not be created", "Check the configuration to make sure that HostedUI related information are present") + static let hostedUISignOutRedirectURI: AuthPluginErrorString = ( + "Callback URL could not be retrieved", + "Check the configuration to make sure that HostedUI related information are present") + static let hostedUIProofCalculation: AuthPluginErrorString = ( "Proof calculation failed", "Reach out with amplify team via github to raise an issue") diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ActionTests/SignOut/ShowHostedUISignOutTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ActionTests/SignOut/ShowHostedUISignOutTests.swift index e00f5a4b3e..af2129ad19 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ActionTests/SignOut/ShowHostedUISignOutTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ActionTests/SignOut/ShowHostedUISignOutTests.swift @@ -114,7 +114,7 @@ class ShowHostedUISignOutTests: XCTestCase { return } - XCTAssertEqual(event.eventType, .userCancelled) + XCTAssertEqual(event.eventType, .hostedUISignOutError(.cancelled)) expectation.fulfill() }, environment: Defaults.makeDefaultAuthEnvironment( @@ -142,21 +142,19 @@ class ShowHostedUISignOutTests: XCTestCase { await action.execute( withDispatcher: MockDispatcher { event in guard let event = event as? SignOutEvent, - case .signOutGlobally(let data, let hostedUIError) = event.eventType else { + case .hostedUISignOutError(let hostedUIError) = event.eventType else { XCTFail("Expected SignOutEvent.signOutGlobally, got \(event)") expectation.fulfill() return } - guard let hostedUIError = hostedUIError, - case .configuration(let errorDescription, _, let serviceError) = hostedUIError.error else { + guard case .configuration(let errorDescription, _, let serviceError) = hostedUIError.authError else { XCTFail("Expected AuthError.configuration") expectation.fulfill() return } - XCTAssertEqual(errorDescription, "Could not create logout URL") - XCTAssertEqual(data, signInData) + XCTAssertEqual(errorDescription, "SignOut URI could not be created") XCTAssertNil(serviceError) expectation.fulfill() }, @@ -185,14 +183,13 @@ class ShowHostedUISignOutTests: XCTestCase { await action.execute( withDispatcher: MockDispatcher { event in guard let event = event as? SignOutEvent, - case .signOutGlobally(let data, let hostedUIError) = event.eventType else { - XCTFail("Expected SignOutEvent.signOutGlobally, got \(event)") + case .hostedUISignOutError(let hostedUIError) = event.eventType else { + XCTFail("Expected SignOutEvent.hostedUISignOutError, got \(event)") expectation.fulfill() return } - guard let hostedUIError = hostedUIError, - case .invalidState(let errorDescription, let recoverySuggestion, let serviceError) = hostedUIError.error else { + guard case .invalidState(let errorDescription, let recoverySuggestion, let serviceError) = hostedUIError.authError else { XCTFail("Expected AuthError.invalidState") expectation.fulfill() return @@ -200,7 +197,6 @@ class ShowHostedUISignOutTests: XCTestCase { XCTAssertEqual(errorDescription, AuthPluginErrorConstants.hostedUIInvalidPresentation.errorDescription) XCTAssertEqual(recoverySuggestion, AuthPluginErrorConstants.hostedUIInvalidPresentation.recoverySuggestion) - XCTAssertEqual(data, signInData) XCTAssertNil(serviceError) expectation.fulfill() }, @@ -229,21 +225,19 @@ class ShowHostedUISignOutTests: XCTestCase { await action.execute( withDispatcher: MockDispatcher { event in guard let event = event as? SignOutEvent, - case .signOutGlobally(let data, let hostedUIError) = event.eventType else { + case .hostedUISignOutError(let hostedUIError) = event.eventType else { XCTFail("Expected SignOutEvent.signOutGlobally, got \(event)") expectation.fulfill() return } - guard let hostedUIError = hostedUIError, - case .configuration(let errorDescription, _, let serviceError) = hostedUIError.error else { + guard case .configuration(let errorDescription, _, let serviceError) = hostedUIError.authError else { XCTFail("Expected AuthError.configuration") expectation.fulfill() return } XCTAssertEqual(errorDescription, "Callback URL could not be retrieved") - XCTAssertEqual(data, signInData) XCTAssertNil(serviceError) expectation.fulfill() }, @@ -269,20 +263,18 @@ class ShowHostedUISignOutTests: XCTestCase { await action.execute( withDispatcher: MockDispatcher { event in guard let event = event as? SignOutEvent, - case .signOutGlobally(let data, let hostedUIError) = event.eventType else { + case .hostedUISignOutError(let hostedUIError) = event.eventType else { XCTFail("Expected SignOutEvent.signOutGlobally, got \(event)") expectation.fulfill() return } - guard let hostedUIError = hostedUIError, - case .configuration(let errorDescription, _, let serviceError) = hostedUIError.error else { + guard case .configuration(let errorDescription, _, let serviceError) = hostedUIError.authError else { XCTFail("Expected AuthError.configuration") expectation.fulfill() return } - XCTAssertEqual(data, signInData) XCTAssertEqual(errorDescription, AuthPluginErrorConstants.configurationError) XCTAssertNil(serviceError) expectation.fulfill() @@ -309,20 +301,18 @@ class ShowHostedUISignOutTests: XCTestCase { await action.execute( withDispatcher: MockDispatcher { event in guard let event = event as? SignOutEvent, - case .signOutGlobally(let data, let hostedUIError) = event.eventType else { + case .hostedUISignOutError(let hostedUIError) = event.eventType else { XCTFail("Expected SignOutEvent.signOutGlobally, got \(event)") expectation.fulfill() return } - guard let hostedUIError = hostedUIError, - case .configuration(let errorDescription, _, let serviceError) = hostedUIError.error else { + guard case .configuration(let errorDescription, _, let serviceError) = hostedUIError.authError else { XCTFail("Expected AuthError.configuration") expectation.fulfill() return } - XCTAssertEqual(data, signInData) XCTAssertEqual(errorDescription, AuthPluginErrorConstants.configurationError) XCTAssertNil(serviceError) expectation.fulfill() diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/Mocks/MockData/SignedInData+Mock.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/Mocks/MockData/SignedInData+Mock.swift index efd34aa2de..e5520078d6 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/Mocks/MockData/SignedInData+Mock.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/Mocks/MockData/SignedInData+Mock.swift @@ -23,4 +23,15 @@ extension SignedInData { signInMethod: .apiBased(.userSRP), cognitoUserPoolTokens: tokens) } + + static var hostedUISignInData: SignedInData { + let tokens = AWSCognitoUserPoolTokens.testData + return SignedInData(signedInDate: Date(), + signInMethod: .hostedUI(.init( + scopes: [], + providerInfo: .init(authProvider: .google, idpIdentifier: ""), + presentationAnchor: nil, + preferPrivateSession: false)), + cognitoUserPoolTokens: tokens) + } } diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/AuthorizationState/AuthorizationTestData.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/AuthorizationState/AuthorizationTestData.swift index c8a4461240..0eb909095e 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/AuthorizationState/AuthorizationTestData.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/AuthorizationState/AuthorizationTestData.swift @@ -53,6 +53,12 @@ extension AmplifyCredentials { credentials: .testData) } + static var hostedUITestData: AmplifyCredentials { + AmplifyCredentials.userPoolAndIdentityPool(signedInData: .hostedUISignInData, + identityID: "identityId", + credentials: AuthAWSCognitoCredentials.testData) + } + static var testDataWithExpiredTokens: AmplifyCredentials { AmplifyCredentials.userPoolAndIdentityPool(signedInData: .expiredTestData, identityID: "identityId", diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateNotStartedTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateNotStartedTests.swift index 46d52736d7..a243505604 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateNotStartedTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateNotStartedTests.swift @@ -22,7 +22,7 @@ class SignOutStateNotStartedTests: XCTestCase { case .signOutLocally, .signedOutSuccess, .signedOutFailure, - .userCancelled, + .hostedUISignOutError, .globalSignOutError: XCTAssertEqual( resolver.resolve( diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateRevokingTokenTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateRevokingTokenTests.swift index 0d858412c1..11a030dbc4 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateRevokingTokenTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateRevokingTokenTests.swift @@ -24,7 +24,7 @@ class SignOutStateRevokingTokenTests: XCTestCase { .signedOutSuccess, .invokeHostedUISignOut, .signOutGuest, - .userCancelled, + .hostedUISignOutError, .globalSignOutError: XCTAssertEqual( resolver.resolve( diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutGloballyTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutGloballyTests.swift index dd52615f57..fe163143d3 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutGloballyTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutGloballyTests.swift @@ -24,7 +24,7 @@ class SignOutStateSigningOutGloballyTests: XCTestCase { .signedOutSuccess, .invokeHostedUISignOut, .signOutGuest, - .userCancelled, + .hostedUISignOutError, .signedOutFailure: XCTAssertEqual( resolver.resolve( diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutLocallyTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutLocallyTests.swift index 8394439384..31e0495e77 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutLocallyTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/ResolverTests/SignOutState/SignOutStateSigningOutLocallyTests.swift @@ -24,7 +24,7 @@ class SignOutStateSigningOutLocallyTests: XCTestCase { .signOutLocally, .invokeHostedUISignOut, .signOutGuest, - .userCancelled, + .hostedUISignOutError, .globalSignOutError: XCTAssertEqual( resolver.resolve( diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/AWSAuthSignOutTaskTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/AWSAuthSignOutTaskTests.swift index 094e68c275..e940246c43 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/AWSAuthSignOutTaskTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/AWSAuthSignOutTaskTests.swift @@ -94,6 +94,26 @@ class AWSAuthSignOutTaskTests: BasePluginTest { } + func testInvalidStateForSignOutWhenSignedInUsingHostedUI() async { + + let initialState = AuthState.configured( + AuthenticationState.signedIn(.hostedUISignInData), + AuthorizationState.sessionEstablished(.hostedUITestData)) + + let authPlugin = configureCustomPluginWith(initialState: initialState) + + let result = await authPlugin.signOut() as? AWSCognitoSignOutResult + + guard case .failed(let authError) = result else { + XCTFail("Sign out should have failed.") + return + } + guard case .configuration = authError else { + XCTFail("Auth error should be service but got: \(authError)") + return + } + } + func testGuestSignOut() async { let initialState = AuthState.configured(