Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,48 @@ extension SignInState {
)
#endif

case .autoSigningIn:
case .autoSigningIn(let signInEventData):

if let signInEvent = event as? SignInEvent,
case .receivedChallenge(let challenge) = signInEvent.eventType {
let action = InitializeResolveChallenge(
challenge: challenge,
signInMethod: signInEventData.signInMethod
)
let subState = SignInChallengeState.notStarted
return .init(
newState:
.resolvingChallenge(
subState,
challenge.challenge.authChallengeType,
signInEventData.signInMethod
),
actions: [action]
)
}

if let signInEvent = event as? SignInEvent,
case .initiateDeviceSRP(let username, let challengeResponse) = signInEvent.eventType {
let action = StartDeviceSRPFlow(
username: username,
authResponse: challengeResponse
)
return .init(
newState: .resolvingDeviceSrpa(.notStarted),
actions: [action]
)
}

if let signInEvent = event as? SignInEvent,
case .initiateTOTPSetup(_, let challengeResponse) = signInEvent.eventType {
let action = InitializeTOTPSetup(
authResponse: challengeResponse)
return .init(
newState: .resolvingTOTPSetup(.notStarted, signInEventData),
actions: [action]
)
}

if case .finalizeSignIn(let signedInData) = event.isSignInEvent {
return .init(
newState: .signedIn(signedInData),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,41 @@ class AWSAuthAutoSignInTests: BasePluginTest {
}
}

/// Test auto sign in success
///
/// - Given: Given an auth plugin with mocked service set up to return `.selectChallenge` with `.password` and `.passwordSrp`
/// for `InitiateAuth` and in signed up state
/// - When:
/// - I invoke autoSignIn
/// - Then:
/// - I should get a result with `.continueSignInWithFirstFactorSelection`
///
func testAutoSignInSuccessWithContinueFirstFactorSelection() async {
mockIdentityProvider = MockIdentityProvider(
mockInitiateAuthResponse: { input in
return InitiateAuthOutput(
availableChallenges: [.password, .passwordSrp],
challengeName: .selectChallenge,
session: "session"
)
}
)

do {
let result = try await plugin.autoSignIn()
guard case .continueSignInWithFirstFactorSelection(let authFactorTypes) = result.nextStep else {
XCTFail("Result should be .continueSignInWithFirstFactorSelection for next step")
return
}

XCTAssertTrue(authFactorTypes.count == 2)
XCTAssertTrue(authFactorTypes.contains(.password))
XCTAssertTrue(authFactorTypes.contains(.passwordSRP))
} catch {
XCTFail("Received failure with error \(error)")
}
}

/// Test auto sign in success
///
/// - Given: Given an auth plugin with mocked service and in `.signingIn` authentication state and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,40 +591,40 @@ class CredentialStoreConfigurationTests: AWSAuthBaseTest {
Defaults.makeDefaultUserPoolConfigData(),
Defaults.makeIdentityConfigData()
)

#if os(watchOS)
let accessGroup = keychainAccessGroupWatch
#else
let accessGroup = keychainAccessGroup
#endif

let credentialStore = AWSCognitoAuthCredentialStore(
authConfiguration: authConfig,
accessGroup: accessGroup
)

do {
try credentialStore.saveCredential(initialCognitoCredentials)
} catch {
XCTFail("Unable to save credentials")
}

// Verify credentials are saved
guard let savedCredentials = try? credentialStore.retrieveCredential() else {
XCTFail("Unable to retrieve saved credentials")
return
}
XCTAssertNotNil(savedCredentials)

// When: Simulate fresh install by clearing UserDefaults flag
UserDefaults.standard.removeObject(forKey: "amplify_secure_storage_scopes.awsCognitoAuthPlugin.isKeychainConfigured")

// Initialize new credential store with same access group (simulates app extension scenario)
let newCredentialStore = AWSCognitoAuthCredentialStore(
authConfiguration: authConfig,
accessGroup: accessGroup
)

// Then: Shared keychain credentials should NOT be cleared
guard let retrievedCredentials = try? newCredentialStore.retrieveCredential(),
case .userPoolAndIdentityPool(
Expand All @@ -635,7 +635,7 @@ class CredentialStoreConfigurationTests: AWSAuthBaseTest {
XCTFail("Shared keychain credentials should not be cleared")
return
}

XCTAssertNotNil(retrievedCredentials)
XCTAssertNotNil(retrievedTokens)
XCTAssertNotNil(retrievedIdentityID)
Expand Down Expand Up @@ -663,28 +663,28 @@ class CredentialStoreConfigurationTests: AWSAuthBaseTest {
Defaults.makeDefaultUserPoolConfigData(),
Defaults.makeIdentityConfigData()
)

let credentialStore = AWSCognitoAuthCredentialStore(authConfiguration: authConfig)

do {
try credentialStore.saveCredential(initialCognitoCredentials)
} catch {
XCTFail("Unable to save credentials")
}

// Verify credentials are saved
guard let savedCredentials = try? credentialStore.retrieveCredential() else {
XCTFail("Unable to retrieve saved credentials")
return
}
XCTAssertNotNil(savedCredentials)

// When: Simulate fresh install by clearing UserDefaults flag
UserDefaults.standard.removeObject(forKey: "amplify_secure_storage_scopes.awsCognitoAuthPlugin.isKeychainConfigured")

// Initialize new credential store without access group
let newCredentialStore = AWSCognitoAuthCredentialStore(authConfiguration: authConfig)

// Then: Non-shared keychain credentials should be cleared
let retrievedCredentials = try? newCredentialStore.retrieveCredential()
XCTAssertNil(retrievedCredentials, "Non-shared keychain credentials should be cleared on fresh install")
Expand All @@ -702,24 +702,24 @@ class CredentialStoreConfigurationTests: AWSAuthBaseTest {
Defaults.makeIdentityConfigData()
)
let userDefaultsKey = "amplify_secure_storage_scopes.awsCognitoAuthPlugin.isKeychainConfigured"

// Test without access group
UserDefaults.standard.removeObject(forKey: userDefaultsKey)
XCTAssertFalse(UserDefaults.standard.bool(forKey: userDefaultsKey))

_ = AWSCognitoAuthCredentialStore(authConfiguration: authConfig)
XCTAssertTrue(UserDefaults.standard.bool(forKey: userDefaultsKey))

// Test with access group
UserDefaults.standard.removeObject(forKey: userDefaultsKey)
XCTAssertFalse(UserDefaults.standard.bool(forKey: userDefaultsKey))

#if os(watchOS)
let accessGroup = keychainAccessGroupWatch
#else
let accessGroup = keychainAccessGroup
#endif

_ = AWSCognitoAuthCredentialStore(
authConfiguration: authConfig,
accessGroup: accessGroup
Expand Down
Loading