Skip to content

Commit e313118

Browse files
harsh62atierian
andauthored
fix(Auth): Add correct validation for initial state when executing confirm sign in (#2587)
* fix(Auth): Add correct validation for initial state when executing confirm sign in * Update AWSAuthSignInPluginTests.swift * Update AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/AWSAuthSignInPluginTests.swift Co-authored-by: Ian Saultz <[email protected]> * Update AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/AWSAuthSignInPluginTests.swift Co-authored-by: Ian Saultz <[email protected]> Co-authored-by: Ian Saultz <[email protected]>
1 parent 58f37d5 commit e313118

File tree

2 files changed

+81
-18
lines changed

2 files changed

+81
-18
lines changed

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthConfirmSignInTask.swift

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@ class AWSAuthConfirmSignInTask: AuthConfirmSignInTask {
2828
if let validationError = request.hasError() {
2929
throw validationError
3030
}
31-
32-
let pluginOptions = (request.options.pluginOptions as? AWSAuthConfirmSignInOptions)
33-
34-
await taskHelper.didStateMachineConfigured()
35-
3631
let invalidStateError = AuthError.invalidState(
3732
"User is not attempting signIn operation",
3833
AuthPluginErrorConstants.invalidStateError, nil)
34+
35+
await taskHelper.didStateMachineConfigured()
36+
37+
if case .configured(let authNState, _) = await authStateMachine.currentState,
38+
case .signingIn(let signInState) = authNState,
39+
case .resolvingChallenge(let challengeState, _, _) = signInState,
40+
case .waitingForAnswer = challengeState {
41+
await sendConfirmSignInEvent()
42+
}
43+
3944
let stateSequences = await authStateMachine.listen()
4045
for await state in stateSequences {
4146
guard case .configured(let authNState, let authZState) = state else {
@@ -68,19 +73,11 @@ class AWSAuthConfirmSignInTask: AuthConfirmSignInTask {
6873
} else if case .resolvingChallenge(let challengeState, _, _) = signInState {
6974
switch challengeState {
7075
case .waitingForAnswer:
71-
// Convert the attributes to [String: String]
72-
let attributePrefix = AuthPluginConstants.cognitoIdentityUserUserAttributePrefix
73-
let attributes = pluginOptions?.userAttributes?.reduce(
74-
into: [String: String]()) {
75-
$0[attributePrefix + $1.key.rawValue] = $1.value
76-
} ?? [:]
77-
let confirmSignInData = ConfirmSignInEventData(
78-
answer: self.request.challengeResponse,
79-
attributes: attributes,
80-
metadata: pluginOptions?.metadata)
81-
let event = SignInChallengeEvent(
82-
eventType: .verifyChallengeAnswer(confirmSignInData))
83-
await authStateMachine.send(event)
76+
guard let result = try UserPoolSignInHelper.checkNextStep(signInState) else {
77+
continue
78+
}
79+
return result
80+
8481
default:
8582
continue
8683
}
@@ -96,4 +93,22 @@ class AWSAuthConfirmSignInTask: AuthConfirmSignInTask {
9693
throw invalidStateError
9794
}
9895

96+
func sendConfirmSignInEvent() async {
97+
let pluginOptions = (request.options.pluginOptions as? AWSAuthConfirmSignInOptions)
98+
99+
// Convert the attributes to [String: String]
100+
let attributePrefix = AuthPluginConstants.cognitoIdentityUserUserAttributePrefix
101+
let attributes = pluginOptions?.userAttributes?.reduce(
102+
into: [String: String]()) {
103+
$0[attributePrefix + $1.key.rawValue] = $1.value
104+
} ?? [:]
105+
let confirmSignInData = ConfirmSignInEventData(
106+
answer: self.request.challengeResponse,
107+
attributes: attributes,
108+
metadata: pluginOptions?.metadata)
109+
let event = SignInChallengeEvent(
110+
eventType: .verifyChallengeAnswer(confirmSignInData))
111+
await authStateMachine.send(event)
112+
}
113+
99114
}

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/AWSAuthSignInPluginTests.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,54 @@ class AWSAuthSignInPluginTests: BasePluginTest {
585585
}
586586
}
587587

588+
/// Test a signIn with customAuthWIthoutSRP
589+
///
590+
/// - Given: An auth plugin with mocked service. Returning a new challenge after confirm sign in is called
591+
///
592+
/// - When:
593+
/// - I invoke signIn and then confirm sign in
594+
/// - Then:
595+
/// - The next step smsMfA should be triggered
596+
///
597+
func testSignInWithCustomAuthIncorrectCode() async {
598+
599+
self.mockIdentityProvider = MockIdentityProvider(mockInitiateAuthResponse: { _ in
600+
InitiateAuthOutputResponse(
601+
authenticationResult: .none,
602+
challengeName: .customChallenge,
603+
challengeParameters: InitiateAuthOutputResponse.validChalengeParams,
604+
session: "someSession")
605+
}, mockRespondToAuthChallengeResponse: { _ in
606+
RespondToAuthChallengeOutputResponse(
607+
authenticationResult: .none,
608+
challengeName: .smsMfa,
609+
challengeParameters: ["paramKey": "value"],
610+
session: "session")
611+
})
612+
613+
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
614+
metadata: ["somekey": "somevalue"],
615+
authFlowType: .customWithoutSRP)
616+
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
617+
do {
618+
let result = try await plugin.signIn(
619+
username: "username",
620+
password: "password",
621+
options: options)
622+
guard case .confirmSignInWithCustomChallenge = result.nextStep,
623+
case let confirmSignInResult = try await plugin.confirmSignIn(
624+
challengeResponse: "245234"
625+
),
626+
case .confirmSignInWithSMSMFACode = confirmSignInResult.nextStep
627+
else {
628+
return XCTFail("Incorrect challenge type")
629+
}
630+
} catch {
631+
XCTFail("Should not fail with \(error)")
632+
}
633+
}
634+
635+
588636
// MARK: - Service error for initiateAuth
589637

590638
/// Test a signIn with `InternalErrorException` from service

0 commit comments

Comments
 (0)