Skip to content

Commit d724185

Browse files
authored
chore: kickoff release
2 parents 6ea7a04 + 71e4df0 commit d724185

File tree

40 files changed

+1656
-106
lines changed

40 files changed

+1656
-106
lines changed

Amplify/Categories/Auth/Models/AuthSignInStep.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ public enum AuthSignInStep {
3939
///
4040
case continueSignInWithMFASelection(AllowedMFATypes)
4141

42+
/// Auth step is for continuing sign in by setting up EMAIL multi factor authentication.
43+
///
44+
case continueSignInWithEmailMFASetup
45+
46+
/// Auth step is for continuing sign in by selecting multi factor authentication type to setup
47+
///
48+
case continueSignInWithMFASetupSelection(AllowedMFATypes)
49+
50+
/// Auth step is for confirming sign in with OTP
51+
///
52+
/// OTP for the factor will be sent to the delivery medium.
53+
case confirmSignInWithOTP(AuthCodeDeliveryDetails)
54+
4255
/// Auth step required the user to change their password.
4356
///
4457
case resetPassword(AdditionalInfo?)
@@ -51,3 +64,5 @@ public enum AuthSignInStep {
5164
///
5265
case done
5366
}
67+
68+
extension AuthSignInStep: Equatable { }

Amplify/Categories/Auth/Models/MFAType.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ public enum MFAType: String {
1212

1313
/// Time-based One Time Password linked with an authenticator app
1414
case totp
15+
16+
/// Email Service linked with an email
17+
case email
1518
}

Amplify/Categories/Auth/Models/TOTPSetupDetails.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@ public struct TOTPSetupDetails {
4040
}
4141

4242
}
43+
44+
extension TOTPSetupDetails: Equatable { }

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/AWSCognitoAuthPlugin+PluginSpecificAPI.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ public extension AWSCognitoAuthPlugin {
4141
}
4242

4343
func updateMFAPreference(
44-
sms: MFAPreference?,
45-
totp: MFAPreference?
44+
sms: MFAPreference? = nil,
45+
totp: MFAPreference? = nil,
46+
email: MFAPreference? = nil
4647
) async throws {
4748
let task = UpdateMFAPreferenceTask(
4849
smsPreference: sms,
4950
totpPreference: totp,
51+
emailPreference: email,
5052
authStateMachine: authStateMachine,
5153
userPoolFactory: authEnvironment.cognitoUserPoolFactory)
5254
return try await task.value

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/AWSCognitoAuthPluginBehavior.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ protocol AWSCognitoAuthPluginBehavior: AuthCategoryPlugin {
4949
/// - totp: The preference that needs to be updated for TOTP
5050
func updateMFAPreference(
5151
sms: MFAPreference?,
52-
totp: MFAPreference?
52+
totp: MFAPreference?,
53+
email: MFAPreference?
5354
) async throws
5455
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/InitializeResolveChallenge.swift

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,54 @@ struct InitializeResolveChallenge: Action {
1818

1919
func execute(withDispatcher dispatcher: EventDispatcher, environment: Environment) async {
2020
logVerbose("\(#fileID) Starting execution", environment: environment)
21+
do {
22+
let nextStep = try resolveNextSignInStep(for: challenge)
23+
let event = SignInChallengeEvent(eventType: .waitForAnswer(challenge, signInMethod, nextStep))
24+
logVerbose("\(#fileID) Sending event \(event.type)", environment: environment)
25+
await dispatcher.send(event)
26+
} catch let error as SignInError {
27+
let errorEvent = SignInEvent(eventType: .throwAuthError(error))
28+
logVerbose("\(#fileID) Sending event \(errorEvent)",
29+
environment: environment)
30+
await dispatcher.send(errorEvent)
31+
} catch {
32+
let error = SignInError.service(error: error)
33+
let errorEvent = SignInEvent(eventType: .throwAuthError(error))
34+
logVerbose("\(#fileID) Sending event \(errorEvent)",
35+
environment: environment)
36+
await dispatcher.send(errorEvent)
37+
}
38+
}
2139

22-
let event = SignInChallengeEvent(eventType: .waitForAnswer(challenge, signInMethod))
23-
logVerbose("\(#fileID) Sending event \(event.type)", environment: environment)
24-
await dispatcher.send(event)
40+
private func resolveNextSignInStep(for challenge: RespondToAuthChallenge) throws -> AuthSignInStep {
41+
switch challenge.challenge.authChallengeType {
42+
case .smsMfa:
43+
let delivery = challenge.codeDeliveryDetails
44+
return .confirmSignInWithSMSMFACode(delivery, challenge.parameters)
45+
case .totpMFA:
46+
return .confirmSignInWithTOTPCode
47+
case .customChallenge:
48+
return .confirmSignInWithCustomChallenge(challenge.parameters)
49+
case .newPasswordRequired:
50+
return .confirmSignInWithNewPassword(challenge.parameters)
51+
case .selectMFAType:
52+
return .continueSignInWithMFASelection(challenge.getAllowedMFATypesForSelection)
53+
case .emailMFA:
54+
return .confirmSignInWithOTP(challenge.codeDeliveryDetails)
55+
case .setUpMFA:
56+
var allowedMFATypesForSetup = challenge.getAllowedMFATypesForSetup
57+
// remove SMS, as it is not supported and should not be sent back to the customer, since it could be misleading
58+
allowedMFATypesForSetup.remove(.sms)
59+
if allowedMFATypesForSetup.count > 1 {
60+
return .continueSignInWithMFASetupSelection(allowedMFATypesForSetup)
61+
} else if let mfaType = allowedMFATypesForSetup.first,
62+
mfaType == .email {
63+
return .continueSignInWithEmailMFASetup
64+
}
65+
throw SignInError.unknown(message: "Unable to determine next step from challenge:\n\(challenge)")
66+
case .unknown(let cognitoChallengeType):
67+
throw SignInError.unknown(message: "Challenge not supported\(cognitoChallengeType)")
68+
}
2569
}
2670

2771
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/SoftwareTokenSetup/InitializeTOTPSetup.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010
struct InitializeTOTPSetup: Action {
1111

1212
var identifier: String = "InitializeTOTPSetup"
13-
let authResponse: SignInResponseBehavior
13+
let authResponse: RespondToAuthChallenge
1414

1515
func execute(withDispatcher dispatcher: EventDispatcher, environment: Environment) async {
1616
logVerbose("\(#fileID) Start execution", environment: environment)
@@ -26,9 +26,9 @@ extension InitializeTOTPSetup: CustomDebugDictionaryConvertible {
2626
var debugDictionary: [String: Any] {
2727
[
2828
"identifier": identifier,
29-
"challengeName": authResponse.challengeName?.rawValue ?? "",
29+
"challengeName": authResponse.challenge.rawValue,
3030
"session": authResponse.session?.masked() ?? "",
31-
"challengeParameters": authResponse.challengeParameters ?? [:]
31+
"challengeParameters": authResponse.parameters ?? [:]
3232
]
3333
}
3434
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/SoftwareTokenSetup/SetUpTOTP.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import AWSCognitoIdentityProvider
1212
struct SetUpTOTP: Action {
1313

1414
var identifier: String = "SetUpTOTP"
15-
let authResponse: SignInResponseBehavior
15+
let authResponse: RespondToAuthChallenge
1616
let signInEventData: SignInEventData
1717

1818
func execute(withDispatcher dispatcher: EventDispatcher, environment: Environment) async {
@@ -65,9 +65,9 @@ extension SetUpTOTP: CustomDebugDictionaryConvertible {
6565
var debugDictionary: [String: Any] {
6666
[
6767
"identifier": identifier,
68-
"challengeName": authResponse.challengeName?.rawValue ?? "",
68+
"challengeName": authResponse.challenge.rawValue,
6969
"session": authResponse.session?.masked() ?? "",
70-
"challengeParameters": authResponse.challengeParameters ?? [:],
70+
"challengeParameters": authResponse.parameters ?? [:],
7171
"signInEventData": signInEventData.debugDictionary
7272
]
7373
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/VerifySignInChallenge.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,41 @@ struct VerifySignInChallenge: Action {
1919

2020
let signInMethod: SignInMethod
2121

22+
let currentSignInStep: AuthSignInStep
23+
2224
func execute(withDispatcher dispatcher: EventDispatcher, environment: Environment) async {
2325
logVerbose("\(#fileID) Starting execution", environment: environment)
2426
let username = challenge.username
2527
var deviceMetadata = DeviceMetadata.noData
2628

2729
do {
30+
31+
if case .continueSignInWithMFASetupSelection = currentSignInStep {
32+
let newChallenge = RespondToAuthChallenge(
33+
challenge: .mfaSetup,
34+
username: challenge.username,
35+
session: challenge.session,
36+
parameters: ["MFAS_CAN_SETUP": "[\"\(confirmSignEventData.answer)\"]"])
37+
38+
let event: SignInEvent
39+
guard let mfaType = MFAType(rawValue: confirmSignEventData.answer) else {
40+
throw SignInError.inputValidation(field: "Unknown MFA type")
41+
}
42+
43+
switch mfaType {
44+
case .email:
45+
event = SignInEvent(eventType: .receivedChallenge(newChallenge))
46+
case .totp:
47+
event = SignInEvent(eventType: .initiateTOTPSetup(username, newChallenge))
48+
default:
49+
throw SignInError.unknown(message: "MFA Type not supported for setup")
50+
}
51+
52+
logVerbose("\(#fileID) Sending event \(event)", environment: environment)
53+
await dispatcher.send(event)
54+
return
55+
}
56+
2857
let userpoolEnv = try environment.userPoolEnvironment()
2958
let username = challenge.username
3059
let session = challenge.session
@@ -64,7 +93,7 @@ struct VerifySignInChallenge: Action {
6493
// Remove the saved device details and retry verify challenge
6594
await DeviceMetadataHelper.removeDeviceMetaData(for: username, with: environment)
6695
let event = SignInChallengeEvent(
67-
eventType: .retryVerifyChallengeAnswer(confirmSignEventData)
96+
eventType: .retryVerifyChallengeAnswer(confirmSignEventData, currentSignInStep)
6897
)
6998
logVerbose("\(#fileID) Sending event \(event)", environment: environment)
7099
await dispatcher.send(event)

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/AuthChallengeType.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ enum AuthChallengeType {
2222

2323
case setUpMFA
2424

25+
case emailMFA
26+
2527
case unknown(CognitoIdentityProviderClientTypes.ChallengeNameType)
2628

2729
}
@@ -41,6 +43,8 @@ extension CognitoIdentityProviderClientTypes.ChallengeNameType: Codable {
4143
return .selectMFAType
4244
case .mfaSetup:
4345
return .setUpMFA
46+
case .emailOtp:
47+
return .emailMFA
4448
default:
4549
return .unknown(self)
4650
}

0 commit comments

Comments
 (0)