From 7654a49f939c8fccae46c445b4db39ca7df47c50 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 2 Oct 2024 16:35:31 -0700 Subject: [PATCH 01/44] feat(docs): adding email mfa --- .../multi-factor-authentication/index.mdx | 511 +++++++++++++----- .../connect-your-frontend/sign-in/index.mdx | 161 ++++-- .../connect-your-frontend/sign-up/index.mdx | 14 +- .../auth/multi-step-sign-in/index.mdx | 378 ++++++++++++- 4 files changed, 866 insertions(+), 198 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 122d25d0f6b..420cc8da88f 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -28,11 +28,15 @@ export function getStaticProps() { }; } -Amplify Auth supports Multi-factor Authentication (MFA) for user sign-in flows. MFA is an extra layer of security used to make sure that users trying to gain access to an account are who they say they are. It requires users to provide additional information to verify their identity. Amplify Auth supports the MFA methods with Time-based-One-Time Passwords (TOTP) as well as text messages (SMS). In this guide we will review how you can set up MFA using TOTP and SMS and the tradeoffs between these methods to help you choose the right set up for your application. We will also review how to set up MFA to remember a device and reduce sign-in friction for your users. +Amplify Auth supports Multi-factor Authentication (MFA) for user sign-in flows. MFA is an extra layer of security used to make sure that users trying to gain access to an account are who they say they are. It requires users to provide additional information to verify their identity. Amplify Auth supports MFA with Time-based-One-Time Passwords (TOTP), text messages (SMS), and email. + +In this guide we will review how you can set up MFA with each of these methods and the discuss tradeoffs between them to help you choose the right setup for your application. We will also review how to set up MFA to remember a device and reduce sign-in friction for your users. ## Configure multi-factor authentication -Use `defineAuth` to enable MFA for your app. The example below is setting up MFA with TOTP but not SMS as you can see that the phone number is not a required attribute. If you are using SMS, then the `PhoneNumber` attribute must be `true`. +Use `defineAuth` to enable MFA for your app. The example below is setting up MFA with TOTP but not SMS as you can see that the phone number is not a required attribute. +- If you plan to use SMS for MFA, then the `phoneNumber` attribute must be `true`. +- If you plan to use email for MFA, then the `email` attribute must also be `true`. ```ts title="amplify/auth/resource.ts" import { defineAuth } from '@aws-amplify/backend'; @@ -44,31 +48,160 @@ export const auth = defineAuth({ // highlight-start multifactor: { mode: 'OPTIONAL', - totp: true + totp: true, } // highlight-end }); ``` -When multi-factor authentication (MFA) is REQUIRED with SMS in your backend auth resource, you will need to pass the phone number during sign-up API call. If you are using the `email` or `username` as the primary sign-in mechanism, you will need to pass the `phone_number` attribute as a user attribute. This will change depending on if you enable SMS, TOTP, or both. Visit the [multi-factor authentication documentation](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/) to learn more about enabling MFA on your backend auth resource. +When MFA is `REQUIRED` with SMS in your backend auth resource, you will need to pass the phone number during sign-up API call. If you are using the `email` or `username` as the primary sign-in mechanism, you will need to pass the `phone_number` attribute as a user attribute. + +Similarly, when MFA is `REQUIRED` with email as your delivery mechanism, you will need to pass an email address during the sign-up API call. If you are using `phoneNumber` or `username` as the primary sign-in mechanism, you will need to pass the `email` attribute as a user attribute. + +This configuration may change depending on the combination of MFA methods enabled in your user pool. ### Understand your MFA options When enabling MFA you will have two key decisions to make: -- **MFA enforcement:** As part of this setup you will determine how MFA is enforced. If you require MFA by setting MFA login to "ON", all your users will need to complete MFA to sign in. If you keep it "Optional", your users will have the choice whether to enable MFA or not for their account. -- **MFA methods:** You will also specify which MFA method you are using - TOTP (Time-based One-time Password), SMS (text message), or both. We recommend that you use TOTP-based MFA as it is more secure and you can reserve SMS for account recovery. +- **MFA enforcement:** As part of this setup you will determine how MFA is enforced. If you require MFA by setting MFA mode to `REQUIRED`, all your users will need to complete MFA to sign in. If you keep it `OPTIONAL`, your users will have the choice whether to enable MFA or not for their account. +- **MFA methods:** You will also specify which MFA method you are using: TOTP (Time-based One-time Password), SMS (text message), email, or any combination thereof. We recommend that you use TOTP-based MFA as it is more secure and you can reserve SMS for account recovery. - + -| | Time-based One-time Password (TOTP) | Short Message Service (SMS) | -| --- | --- | --- | -| **Description** | Generates a short-lived numeric code for user authentication that includes a shared secret key and current time using an authenticator app. | Generates a one-time code shared via text message that is entered with other credentials for user authentication. | -| **Benefits** | More secure than SMS since the code is generated locally and not transmitted over a network. TOTP also works without cell service as long as the TOTP app is installed. | Easy to set up with a user-provided phone number and is familiar to users as a common authentication method. | -| **Constraints** | Requires an app to generate codes and adds to the initial setup of an account. Codes also expire quickly and must be used promptly after it is generated. | SMS requires cell service and can include an additional cost for the user. Although rare, SMS messages can also be intercepted. | +| | Time-based One-time Password (TOTP) | Short Message Service (SMS) | Email | +| --- | --- | --- | --- | +| **Description** | Generates a short-lived numeric code for user authentication that includes a shared secret key and current time using an authenticator app. | Generates a one-time code shared via text message that is entered with other credentials for user authentication. | Generates a one-time code sent to the user's registered email address. The user must access the email and enter the code to complete the authentication process. | +| **Benefits** | More secure than SMS since the code is generated locally and not transmitted over a network. TOTP also works without cell service as long as the TOTP app is installed. | Easy to set up with a user-provided phone number and is familiar to users as a common authentication method. | Email is a widely used and familiar communication channel that requires no additional hardware or software requirements on the user's end. | +| **Constraints** | Requires an app to generate codes and adds to the initial setup of an account. Codes also expire quickly and must be used promptly after it is generated. | SMS requires cell service and can include an additional cost for the user. Although rare, SMS messages can also be intercepted. | Depends on the availability and reliability of email services. Although rare, emails can be intercepted or accounts can become compromised. | + + +If multiple MFA methods are enabled for the user, the `signIn` API will return `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. + +```ts +import { confirmSignIn, SignInOutput } from 'aws-amplify/auth'; + +function handleSignInNextSteps(output: SignInOutput) { + const { nextStep } = output; + switch (nextStep.signInStep) { + // ... + case 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION': + const allowedMFATypes = nextStep.allowedMFATypes; + const mfaType = promptUserForMFAType(allowedMFATypes); + case 'CONFIRM_SIGN_IN_WITH_SMS_CODE': + // prompt user to enter otp code delivered via SMS + break; + case 'CONFIRM_SIGN_IN_WITH_TOTP_CODE': + // prompt user to enter otp code from their authenticator app + break; + case 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE': + // prompt user to enter otp code delivered via EMAIL + break; + // ... + } +} + +function promptUserForMFAType( + allowedMFATypes?: ('SMS' | 'TOTP' | 'EMAIL')[] +): 'SMS' | 'TOTP' | 'EMAIL' { + // Prompt user to select MFA type +} + +async function handleMFASelection(mfaType: 'SMS' | 'TOTP' | 'EMAIL') { + try { + const output = await confirmSignIn({ + challengeResponse: mfaType + }); + handleSignInNextSteps(output); + } catch (error) { + console.log(error); + } +} +``` + + + +If multiple MFA methods are enabled for the user, the `signIn` API will return `continueSignInWithMFASelection` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. + + + + +```dart +Future _handleSignInResult(SignInResult result) async { + switch (result.nextStep.signInStep) { + // ··· + case AuthSignInStep.continueSignInWithMfaSelection: + final allowedMfaTypes = result.nextStep.allowedMfaTypes!; + final selection = await _promptUserPreference(allowedMfaTypes); + return _handleMfaSelection(selection); + // ··· + } +} + +Future _promptUserPreference(Set allowedTypes) async { + // ··· +} + +Future _handleMfaSelection(MfaType selection) async { + try { + final result = await Amplify.Auth.confirmSignIn( + confirmationValue: selection.confirmationValue, + ); + return _handleSignInResult(result); + } on AuthException catch (e) { + safePrint('Error resending code: ${e.message}'); + } +} +``` + + + + +```swift +func signIn(username: String, password: String) async { + do { + let signInResult = try await Amplify.Auth.signIn(username: username, password: password) + switch signInResult.nextStep { + + case .continueSignInWithMFASelection(let allowedMFATypes): + print("Received next step as continue sign in by selecting MFA type") + print("Allowed MFA types \(allowedMFATypes)") + + // Prompt the user to select the MFA type they want to use + // Then invoke `confirmSignIn` api with the MFA type + + default: + + // Use has successfully signed in to the app + print("Step: \(signInResult.nextStep)") + } + } catch let error as AuthError{ + print ("Sign in failed \(error)") + } catch { + print("Unexpected error: \(error)") + } +} + +func confirmSignInWithTOTPAsMFASelection() async { + do { + let signInResult = try await Amplify.Auth.confirmSignIn( + challengeResponse: MFAType.totp.challengeResponse) + + if case .confirmSignInWithTOTPCode = signInResult.nextStep { + print("Received next step as confirm sign in with TOTP") + } + + } catch { + print("Confirm sign in failed \(error)") + } +} +``` + + + ## Multi-factor authentication with SMS @@ -674,6 +807,240 @@ If a user loses access to their TOTP device, they will need to contact an admini In a scenario where MFA is marked as "Required" in the Cognito User Pool and another MFA method is not set up, the administrator would need to first initiate an [`AdminUpdateUserAttributes`](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUpdateUserAttributes.html) call and update the user's phone number attribute. Once this is complete, the administrator can continue changing the MFA preference to SMS as suggested above. +## Multi-factor authentication with EMAIL + + + +If you are using the [Authenticator component](https://ui.docs.amplify.aws/react/connected-components/authenticator) with Amplify, this feature works without any additional code. The guide below is for writing your own implementation. + + + + + + + +If you are using the [Authenticator component](https://ui.docs.amplify.aws/swift/connected-components/authenticator) with Amplify, this feature works without any additional code. The guide below is for writing your own implementation. + + + + + + + +If you are using the [Authenticator component](https://ui.docs.amplify.aws/flutter/connected-components/authenticator) with Amplify, this feature works without any additional code. The guide below is for writing your own implementation. + + + + + + + +If you are using the [Authenticator component](https://ui.docs.amplify.aws/android/connected-components/authenticator) with Amplify, this feature works without any additional code. The guide below is for writing your own implementation. + + + + +Once you have setup email as your second layer of authentication with MFA as shown above, your users will get an authentication code via an email to complete sign-in after they sign in with their username and password. + + + +In order to send email authentication codes, the following prerequisites must be met: +- Cognito must be configured to send emails using [Amazon Simple Email Service (Amazon SES)](/[platform]/build-a-backend/auth/moving-to-production/#email). +- [Advanced Security Features (ASF)](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) must be enabled in your user pool. + + + +### Enable EMAIL MFA during sign-up + +You will need to pass `email` as a user attribute to enable email MFA for your users during sign-up. However, if the primary sign-in mechanism for your Cognito resource is already `email` (without enabling `username`), then you do not need to pass it as an attribute. + + +```ts +import { signUp } from 'aws-amplify/auth'; + +await signUp({ + username: "+15555555555", + password: "hunter2", + options: { + userAttributes: { + email: "hello@mycompany.com", + }, + }, +}); +``` + + + +```dart +Future signUpWithPhoneVerification( + String username, + String password, +) async { + await Amplify.Auth.signUp( + username: username, + password: password, + options: SignUpOptions( + userAttributes: { + // ... if required + AuthUserAttributeKey.email: 'test@example.com', + AuthUserAttributeKey.phoneNumber: '+18885551234', + }, + ), + ); +} +``` + + + +```swift +func signUp(username: String, password: String, email: String, phonenumber: String) async { + do { + let signUpResult = try await Amplify.Auth.signUp( + username: username, + password: password, + options: .init(userAttributes: [ + AuthUserAttribute(.email, value: email), + AuthUserAttribute(.phoneNumber, value: phonenumber) + ]) + ) + if case let .confirmUser(deliveryDetails, _, userId) = signUpResult.nextStep { + print("Delivery details \(String(describing: deliveryDetails)) for userId: \(String(describing: userId)))") + } else { + print("SignUp Complete") + } + } catch let error as AuthError { + print("An error occurred while registering a user \(error)") + } catch { + print("Unexpected error: \(error)") + } +} +``` + + +By default, you have to verify a user account after they sign up using the `confirmSignUp` API. Following the initial `signUp` request, a one-time passcode will be sent to the user's phone number or email, depending on your Amazon Cognito configuration. + + +```ts +import { confirmSignUp } from 'aws-amplify/auth'; + +await confirmSignUp({ + username: "+15555555555", + confirmationCode: "123456", +}) +``` + + + +```dart +Future confirmSignUpPhoneVerification( + String username, + String otpCode, +) async { + await Amplify.Auth.confirmSignUp( + username: username, + confirmationCode: otpCode, + ); +} +``` + + + + +```swift +func confirmSignUp(for username: String, with confirmationCode: String) async { + do { + let confirmSignUpResult = try await Amplify.Auth.confirmSignUp( + for: username, + confirmationCode: confirmationCode + ) + print("Confirm sign up result completed: \(confirmSignUpResult.isSignUpComplete)") + } catch let error as AuthError { + print("An error occurred while confirming sign up \(error)") + } catch { + print("Unexpected error: \(error)") + } +} +``` + + +### Manage EMAIL MFA during sign-in + +After a user signs in, if they have MFA enabled for their account, a challenge will be issued that requires calling the `confirmSignIn` API with the user provided confirmation code sent to their email address. + +If MFA is **ON** or enabled for the user, you must call `confirmSignIn` with the OTP sent to their email address. + + +```ts +import { confirmSignIn } from 'aws-amplify/auth'; + +await confirmSignIn({ + challengeResponse: "123456" +}); +``` + + + +```dart +Future confirmSignInEmailVerification(String otpCode) async { + await Amplify.Auth.confirmSignIn( + confirmationValue: otpCode, + ); +} +``` + + + +```swift +func confirmSignIn() async { + do { + let signInResult = try await Amplify.Auth.confirmSignIn( + challengeResponse: "") + print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") + } catch let error as AuthError { + print("Confirm sign in failed \(error)") + } catch { + print("Unexpected error: \(error)") + } +} +``` + + +After a user has been signed in, call `updateMFAPreference` to record the MFA type as enabled for the user and optionally set it as preferred so that subsequent logins default to using this MFA type. + + +```ts +import { updateMFAPreference } from 'aws-amplify/auth'; + +await updateMFAPreference({ email: 'PREFERRED' }); +``` + + + +```dart +Future updateMfaPreferences() async { + final cognitoPlugin = Amplify.Auth.getPlugin(AmplifyAuthCognito.pluginKey); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.enabled, // or .preferred + ); +} +``` + + + +```swift +func updateMFAPreferences() async throws { + let authCognitoPlugin = try Amplify.Auth.getPlugin( + for: "awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin + + let emailMfaPreference: MFAPreference = .preferred + + try await authCognitoPlugin?.updateMFAPreference( + email: emailMfaPreference) +} +``` + + ## Set up a user's preferred MFA method ### Fetch the current user's MFA preferences @@ -761,126 +1128,6 @@ func updateMFAPreferences() async throws { ``` - -If multiple MFA methods are enabled for the user, the `signIn` API will return `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. - -```ts -import { confirmSignIn, SignInOutput } from 'aws-amplify/auth'; - -function handleSignInNextSteps(output: SignInOutput) { - const { nextStep } = output; - switch (nextStep.signInStep) { - // ... - case 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION': - const allowedMFATypes = nextStep.allowedMFATypes; - const mfaType = promptUserForMFAType(allowedMFATypes); - case 'CONFIRM_SIGN_IN_WITH_SMS_CODE': - // display user to enter otp code; - break; - case 'CONFIRM_SIGN_IN_WITH_TOTP_CODE': - // display user to enter otp code; - break; - // ... - } -} - -function promptUserForMFAType( - allowedMFATypes?: ('SMS' | 'TOTP')[] -): 'SMS' | 'TOTP' { - // Prompt user to select MFA type -} - -async function handleMFASelection(mfaType: 'SMS' | 'TOTP') { - try { - const output = await confirmSignIn({ - challengeResponse: mfaType - }); - handleSignInNextSteps(output); - } catch (error) { - console.log(error); - } -} -``` - - - -If multiple MFA methods are enabled for the user, the `signIn` API will return `continueSignInWithMFASelection` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. - - - - -```dart -Future _handleSignInResult(SignInResult result) async { - switch (result.nextStep.signInStep) { - // ··· - case AuthSignInStep.continueSignInWithMfaSelection: - final allowedMfaTypes = result.nextStep.allowedMfaTypes!; - final selection = await _promptUserPreference(allowedMfaTypes); - return _handleMfaSelection(selection); - // ··· - } -} - -Future _promptUserPreference(Set allowedTypes) async { - // ··· -} - -Future _handleMfaSelection(MfaType selection) async { - try { - final result = await Amplify.Auth.confirmSignIn( - confirmationValue: selection.confirmationValue, - ); - return _handleSignInResult(result); - } on AuthException catch (e) { - safePrint('Error resending code: ${e.message}'); - } -} -``` - - - - -```swift -func signIn(username: String, password: String) async { - do { - let signInResult = try await Amplify.Auth.signIn(username: username, password: password) - switch signInResult.nextStep { - - case .continueSignInWithMFASelection(let allowedMFATypes): - print("Received next step as continue sign in by selecting MFA type") - print("Allowed MFA types \(allowedMFATypes)") - - // Prompt the user to select the MFA type they want to use - // Then invoke `confirmSignIn` api with the MFA type - - default: - - // Use has successfully signed in to the app - print("Step: \(signInResult.nextStep)") - } - } catch let error as AuthError{ - print ("Sign in failed \(error)") - } catch { - print("Unexpected error: \(error)") - } -} - -func confirmSignInWithTOTPAsMFASelection() async { - do { - let signInResult = try await Amplify.Auth.confirmSignIn( - challengeResponse: MFAType.totp.challengeResponse) - - if case .confirmSignInWithTOTPCode = signInResult.nextStep { - print("Received next step as confirm sign in with TOTP") - } - - } catch { - print("Confirm sign in failed \(error)") - } -} -``` - - ## Remember a device Remembering a device is useful in conjunction with MFA because it allows the second factor requirement to be automatically met when your user signs in on that device and reduces friction in their sign-in experience. By default, this feature is turned off. diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index e497d3c9acf..7a398c8066e 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -254,51 +254,42 @@ func signIn(username: String, password: String) -> AnyCancellable { The `signIn` API response will include a `nextStep` property, which can be used to determine if further action is required. It may return the following next steps: -- `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED` - The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. -- `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE` - The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. -- `CONFIRM_SIGN_IN_WITH_TOTP_CODE` - The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. -- `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` - The TOTP setup process must be continued. Complete the process with `confirmSignIn`. -- `CONFIRM_SIGN_IN_WITH_SMS_CODE` - The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. -- `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` - The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. -- `RESET_PASSWORD` - The user must reset their password via `resetPassword`. -- `CONFIRM_SIGN_UP` - The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. -- `DONE` - The sign in process has been completed. +| Next Step | Description | +| --------- | ----------- | +| `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE` | The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_TOTP_CODE` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_SMS_CODE` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_EMAIL_CODE` | The sign-in must be confirmed with a EMAIL code from the user. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | +| `RESET_PASSWORD` | The user must reset their password via `resetPassword`. | +| `CONFIRM_SIGN_UP` | The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. | +| `DONE` | The sign in process has been completed. | + -- `confirmSignInWithNewPassword` - The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. -- `confirmSignInWithCustomChallenge` - The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. -- `confirmSignInWithTOTPCode` - The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. -- `continueSignInWithTOTPSetup` - The TOTP setup process must be continued. Complete the process with `confirmSignIn`. -- `confirmSignInWithSMSMFACode` - The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. -- `continueSignInWithMFASelection` - The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. -- `resetPassword` - The user must reset their password via `resetPassword`. -- `confirmSignUp` - The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. -- `done` - The sign in process has been completed. +| Next Step | Description | +| --------- | ----------- | +| `confirmSignInWithNewPassword` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | +| `confirmSignInWithCustomChallenge` | The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. | +| `confirmSignInWithTOTPCode` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithSMSMFACode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithEmailMFACode` | The sign-in must be confirmed with a EMAIL code from the user. Complete the process with `confirmSignIn`. | +| `continueSignInWithMFASelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithTOTPSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `continueSignInWithEmailMFASetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | +| `resetPassword` | The user must reset their password via `resetPassword`. | +| `confirmSignUp` | The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. | +| `done` | The sign in process has been completed. | -For more information on handling the TOTP and MFA steps that may be returned, see [multi-factor authentication](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/). - -### Confirm sign-in - - - -```ts title="src/main.ts" -import { confirmSignIn, signIn } from 'aws-amplify/auth' - -const { nextStep } = await signIn({ - username: "hello@mycompany.com", - password: "hunter2", -}) - -if (nextStep === "CONFIRM_SIGN_IN_WITH_SMS_CODE") { - await confirmSignIn({ - challengeResponse: "12345" - }) -} -``` +For more information on handling the MFA steps that may be returned, see [multi-factor authentication](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/). - {/* @todo */} @@ -404,7 +395,13 @@ export default function App() { {/* with multi-factor auth */} ## With multi-factor auth enabled -When multi-factor authentication (MFA) is **required** with SMS in your backend auth resource, you will need to pass the phone number during sign-up API call. If you are using the `email` or `username` as the primary sign-in mechanism, you will need to pass the `phone_number` attribute as a user attribute. This will change depending on if you enable SMS, TOTP, or both. Visit the [multi-factor authentication documentation](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/) to learn more about enabling MFA on your backend auth resource. +When you have Email or SMS MFA enabled, Cognito will send messages to your users on your behalf. Email and SMS messages require that your users have email address and phone number attributes respectively. It is recommended to set these attributes as required in your user pool if you wish to use either Email MFA or SMS MFA. When these attributes are required, a user must provide these details before they can complete the sign up process. + +If you have set MFA to be required and you have activated more than one authentication factor, Cognito will prompt new users to select an MFA factor they want to use. Users must have a phone number to select SMS and an email address to select email MFA. + +If a user doesn't have the necessary attributes defined for any available message based MFA, Cognito will prompt them to set up TOTP. + +Visit the [multi-factor authentication documentation](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/) to learn more about enabling MFA on your backend auth resource. @@ -550,12 +547,32 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri - -You will then confirm sign-up, sign in, and receive a `nextStep` in the sign-in result of type `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE`. A confirmation code will also be texted to the phone number provided above. Pass the code you received to the `confirmSignIn` API: +### Confirm sign-in + + +Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. +| Next Step | Description | +| --------- | ----------- | +| `CONFIRM_SIGN_IN_WITH_TOTP_CODE` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_SMS_CODE` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_EMAIL_CODE` | The sign-in must be confirmed with a EMAIL code from the user. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | - -You will then confirm sign-up, sign in, and receive a `nextStep` in the sign-in result of type `confirmSignInWithSMSMFACode`. A confirmation code will also be texted to the phone number provided above. Pass the code you received to the `confirmSignIn` API: + +Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. +| Next Step | Description | +| --------- | ----------- | +| `confirmSignInWithTOTPCode` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithSMSMFACode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithEmailMFACode` | The sign-in must be confirmed with a EMAIL code from the user. Complete the process with `confirmSignIn`. | +| `continueSignInWithMFASelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithTOTPSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `continueSignInWithEmailMFASetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | @@ -566,6 +583,62 @@ You will then confirm sign-up, sign in, and receive a `nextStep` in the sign-in + + +```ts title="src/main.ts" +import { confirmSignIn, signIn } from "aws-amplify/auth"; + +const { nextStep } = await signIn({ + username: "hello@mycompany.com", + password: "hunter2", +}); + +if ( + nextStep.signInStep === "CONFIRM_SIGN_IN_WITH_SMS_CODE" || + nextStep.signInStep === "CONFIRM_SIGN_IN_WITH_EMAIL_CODE" || + nextStep.signInStep === "CONFIRM_SIGN_IN_WITH_TOTP_CODE" +) { + // collect OTP from user + await confirmSignIn({ + challengeResponse: "123456", + }); +} + +if (nextStep.signInStep === "CONTINUE_SIGN_IN_WITH_MFA_SELECTION") { + // present nextStep.allowedMFATypes to user + // collect user selection + await confirmSignIn({ + challengeResponse: "EMAIL", // 'EMAIL', 'SMS', or 'TOTP' + }); +} + +if (nextStep.signInStep === "CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION") { + // present nextStep.allowedMFATypes to user + // collect user selection + await confirmSignIn({ + challengeResponse: "EMAIL", // 'EMAIL' or 'TOTP' + }); +} + +if (nextStep.signInStep === "CONTINUE_SIGN_IN_WITH_EMAIL_SETUP") { + // collect email address from user + await confirmSignIn({ + challengeResponse: "hello@mycompany.com", + }); +} + +if (nextStep.signInStep === "CONTINUE_SIGN_IN_WITH_TOTP_SETUP") { + // present nextStep.totpSetupDetails.getSetupUri() to user + // collect OTP from user + await confirmSignIn({ + challengeResponse: "123456", + }); +} + +``` + + + diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx index 794d6b3ddf3..4ec2b71b02d 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx @@ -286,14 +286,18 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri The `signUp` API response will include a `nextStep` property, which can be used to determine if further action is required. It may return the following next steps: -- `CONFIRM_SIGN_UP` - The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp`. -- `DONE` - The sign up process has been fully completed. -- `COMPLETE_AUTO_SIGN_IN` - The sign up process needs to complete by invoking the `autoSignIn` API. +| Next Step | Description | +| --------- | ----------- | +| `CONFIRM_SIGN_UP` | The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp`. | +| `DONE` | The sign up process has been fully completed. | +| `COMPLETE_AUTO_SIGN_IN` | The sign up process needs to complete by invoking the `autoSignIn` API. | -- `confirmUser` - The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp` API. -- `done` - The sign up process has been fully completed. +| Next Step | Description | +| --------- | ----------- | +| `confirmSignUp` | The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp`. | +| `done` | The sign up process has been fully completed. | ## Confirm sign-up diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 4a738a3fbde..72b9a83a0f4 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -63,6 +63,12 @@ Future _handleSignInResult(SignInResult result) async { switch (result.nextStep.signInStep) { case AuthSignInStep.continueSignInWithMfaSelection: // Handle select from MFA methods case + case AuthSignInStep.continueSignInWithMfaSetupSelection: + // Handle select from MFA methods available to setup + case AuthSignInStep.continueSignInWithEmailMfaSetup: + // Handle email setup case + case AuthSignInStep.confirmSignInWithEmailMfaCode: + // Handle email MFA case case AuthSignInStep.continueSignInWithTotpSetup: // Handle TOTP setup case case AuthSignInStep.confirmSignInWithTotpMfaCode: @@ -84,8 +90,7 @@ Future _handleSignInResult(SignInResult result) async { ``` ### Confirm signin with SMS MFA -If the next step is `confirmSignInWithSmsMfaCode`, Amplify Auth has sent the user a random code over SMS and is waiting for the user to verify that code. -To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. +If the next step is `confirmSignInWithSmsMfaCode`, Amplify Auth has sent the user a random code over SMS and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -156,14 +161,58 @@ Future confirmTotpUser(String totpCode) async { } ``` +### Confirm signin with Email MFA + +If the next step is `confirmSignInWithEmailMfaCode`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. + + + +The result includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery, such as the partial email address of +the recipient, which can be used to prompt the user on where to look for the code. + + + +```dart +Future _handleSignInResult(SignInResult result) async { + switch (result.nextStep.signInStep) { + case AuthSignInStep.confirmSignInWithEmailMfaCode: + final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!; + _handleCodeDelivery(codeDeliveryDetails); + // ... + } +} + +void _handleCodeDelivery(AuthCodeDeliveryDetails codeDeliveryDetails) { + safePrint( + 'A confirmation code has been sent to ${codeDeliveryDetails.destination}. ' + 'Please check your ${codeDeliveryDetails.deliveryMedium.name} for the code.', + ); +} +``` + +```dart +Future confirmMfaUser(String mfaCode) async { + try { + final result = await Amplify.Auth.confirmSignIn( + confirmationValue: mfaCode, + ); + return _handleSignInResult(result); + } on AuthException catch (e) { + safePrint('Error confirming MFA code: ${e.message}'); + } +} +``` + + ### Continue signin with MFA Selection -If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently only supports SMS and TOTP as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. +If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. The MFA types which are currently supported by Amplify Auth are: - `MfaType.sms` - `MfaType.totp` +- `MfaType.email` ```dart Future _handleSignInResult(SignInResult result) async { @@ -193,6 +242,34 @@ Future _handleMfaSelection(MfaType selection) async { } ``` +### Continue signin with Email Setup + +If the next step is `continueSignInWithEmailMfaSetup`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. + +```dart +Future _handleSignInResult(SignInResult result) async { + switch (result.nextStep.signInStep) { + // ··· + case AuthSignInStep.continueSignInWithEmailMfaSetup: + // Prompt user to enter an email address they would like to use for MFA + // ··· + } +} + +// Then, pass the email address to `confirmSignIn` + +Future confirmTotpUser(String emailAddress) async { + try { + final result = await Amplify.Auth.confirmSignIn( + confirmationValue: emailAddress, + ); + return _handleSignInResult(result); + } on AuthException catch (e) { + safePrint('Error confirming email address: ${e.message}'); + } +} +``` + ### Continue signin with TOTP Setup If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. @@ -225,6 +302,44 @@ Future confirmTotpUser(String totpCode) async { } } ``` + +### Continue signin with MFA Setup Selection +If the next step is `continueSignInWithMfaSetupSelection`, then the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. + +The MFA types which are currently supported by Amplify Auth are: + +- `MfaType.sms` +- `MfaType.totp` +- `MfaType.email` + +```dart +Future _handleSignInResult(SignInResult result) async { + switch (result.nextStep.signInStep) { + // ··· + case AuthSignInStep.continueSignInWithMfaSetupSelection: + final allowedMfaTypes = result.nextStep.allowedMfaTypes!; + final selection = await _promptUserPreference(allowedMfaTypes); + return _handleMfaSelection(selection); + // ··· + } +} + +Future _promptUserPreference(Set allowedTypes) async { + // ··· +} + +Future _handleMfaSelection(MfaType selection) async { + try { + final result = await Amplify.Auth.confirmSignIn( + confirmationValue: selection.confirmationValue, + ); + return _handleSignInResult(result); + } on AuthException catch (e) { + safePrint('Error selecting MFA method: ${e.message}'); + } +} +``` + ### Confirm signin with custom challenge If the next step is `confirmSignInWithCustomChallenge`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). @@ -435,20 +550,33 @@ try { { AuthNextSignInStep nextStep = result.getNextStep(); switch (nextStep.getSignInStep()) { - case CONFIRM_SIGN_IN_WITH_TOTP_CODE -> { + case CONFIRM_SIGN_IN_WITH_TOTP_CODE: { Log.i("AuthQuickstart", "Received next step as confirm sign in with TOTP code"); // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code break; } - case CONTINUE_SIGN_IN_WITH_TOTP_SETUP -> { + case CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION: { + Log.i("AuthQuickstart", "Received next step as continue sign in by selecting an MFA method to setup"); + Log.i("AuthQuickstart", "Allowed MFA types for setup" + nextStep.getAllowedMFATypes()); + // Prompt the user to select the MFA type they want to setup + // Then invoke `confirmSignIn` api with the MFA type + break; + } + case CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP: { + Log.i("AuthQuickstart", "Received next step as continue sign in by setting up email MFA"); + // Prompt the user to enter the email address they would like to use to receive OTPs + // Then invoke `confirmSignIn` api with the email address + break; + } + case CONTINUE_SIGN_IN_WITH_TOTP_SETUP: { Log.i("AuthQuickstart", "Received next step as continue sign in by setting up TOTP"); Log.i("AuthQuickstart", "Shared secret that will be used to set up TOTP in the authenticator app" + nextStep.getTotpSetupDetails().getSharedSecret()); // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code break; } - case CONTINUE_SIGN_IN_WITH_MFA_SELECTION -> { + case CONTINUE_SIGN_IN_WITH_MFA_SELECTION: { Log.i("AuthQuickstart", "Received next step as continue sign in by selecting MFA type"); Log.i("AuthQuickstart", "Allowed MFA type" + nextStep.getAllowedMFATypes()); // Prompt the user to select the MFA type they want to use @@ -462,6 +590,13 @@ try { // Then invoke `confirmSignIn` api with the code break; } + case CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE: { + Log.i("AuthQuickstart", "Email code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); + Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo()); + // Prompt the user to enter the Email MFA code they received + // Then invoke `confirmSignIn` api with the code + break; + } case CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE: { Log.i("AuthQuickstart", "Custom challenge, additional info: " + nextStep.getAdditionalInfo()); // Prompt the user to enter custom challenge answer @@ -522,9 +657,20 @@ try { val nextStep = result.nextStep when(nextStep.signInStep){ AuthSignInStep.CONFIRM_SIGN_IN_WITH_TOTP_CODE -> { - Log.i("AuthQuickstart", "Received next step as confirm sign in with TOTP code") - // Prompt the user to enter the TOTP code generated in their authenticator app - // Then invoke `confirmSignIn` api with the code + Log.i("AuthQuickstart", "Received next step as confirm sign in with TOTP code") + // Prompt the user to enter the TOTP code generated in their authenticator app + // Then invoke `confirmSignIn` api with the code + } + AuthSignInStep.CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION -> { + Log.i("AuthQuickstart", "Received next step as continue sign in by selecting an MFA method to setup"); + Log.i("AuthQuickstart", "Allowed MFA types for setup" + nextStep.getAllowedMFATypes()); + // Prompt the user to select the MFA type they want to setup + // Then invoke `confirmSignIn` api with the MFA type + } + AuthSignInStep.CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP -> { + Log.i("AuthQuickstart", "Received next step as continue sign in by setting up email MFA"); + // Prompt the user to enter the email address they would like to use to receive OTPs + // Then invoke `confirmSignIn` api with the email address } AuthSignInStep.CONTINUE_SIGN_IN_WITH_TOTP_SETUP -> { Log.i("AuthQuickstart", "Received next step as continue sign in by setting up TOTP") @@ -544,6 +690,12 @@ try { // Prompt the user to enter the SMS MFA code they received // Then invoke `confirmSignIn` api with the code } + AuthSignInStep.CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE -> { + Log.i("AuthQuickstart", "Email code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); + Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo()); + // Prompt the user to enter the Email MFA code they received + // Then invoke `confirmSignIn` api with the code + } AuthSignInStep.CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE -> { Log.i("AuthQuickstart","Custom challenge, additional info: ${nextStep.additionalInfo}") // Prompt the user to enter custom challenge answer @@ -605,6 +757,17 @@ try { // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code } + AuthSignInStep.CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION -> { + Log.i("AuthQuickstart", "Received next step as continue sign in by selecting an MFA method to setup"); + Log.i("AuthQuickstart", "Allowed MFA types for setup" + nextStep.getAllowedMFATypes()); + // Prompt the user to select the MFA type they want to setup + // Then invoke `confirmSignIn` api with the MFA type + } + AuthSignInStep.CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP -> { + Log.i("AuthQuickstart", "Received next step as continue sign in by setting up email MFA"); + // Prompt the user to enter the email address they would like to use to receive OTPs + // Then invoke `confirmSignIn` api with the email address + } AuthSignInStep.CONTINUE_SIGN_IN_WITH_TOTP_SETUP -> { Log.i("AuthQuickstart", "Received next step as continue sign in by setting up TOTP") Log.i("AuthQuickstart", "Shared secret that will be used to set up TOTP in the authenticator app ${nextStep.totpSetupDetails.sharedSecret}") @@ -674,20 +837,33 @@ RxAmplify.Auth.signIn("username", "password", options).subscribe( { AuthNextSignInStep nextStep = result.getNextStep(); switch (nextStep.getSignInStep()) { - case CONFIRM_SIGN_IN_WITH_TOTP_CODE -> { + case CONFIRM_SIGN_IN_WITH_TOTP_CODE: { Log.i("AuthQuickstart", "Received next step as confirm sign in with TOTP code"); // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code break; } - case CONTINUE_SIGN_IN_WITH_TOTP_SETUP -> { + case CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION: { + Log.i("AuthQuickstart", "Received next step as continue sign in by selecting an MFA method to setup"); + Log.i("AuthQuickstart", "Allowed MFA types for setup" + nextStep.getAllowedMFATypes()); + // Prompt the user to select the MFA type they want to setup + // Then invoke `confirmSignIn` api with the MFA type + break; + } + case CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP: { + Log.i("AuthQuickstart", "Received next step as continue sign in by setting up email MFA"); + // Prompt the user to enter the email address they would like to use to receive OTPs + // Then invoke `confirmSignIn` api with the email address + break; + } + case CONTINUE_SIGN_IN_WITH_TOTP_SETUP: { Log.i("AuthQuickstart", "Received next step as continue sign in by setting up TOTP"); Log.i("AuthQuickstart", "Shared secret that will be used to set up TOTP in the authenticator app" + nextStep.getTotpSetupDetails().getSharedSecret()); // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code break; } - case CONTINUE_SIGN_IN_WITH_MFA_SELECTION -> { + case CONTINUE_SIGN_IN_WITH_MFA_SELECTION: { Log.i("AuthQuickstart", "Received next step as continue sign in by selecting MFA type"); Log.i("AuthQuickstart", "Allowed MFA type" + nextStep.getAllowedMFATypes()); // Prompt the user to select the MFA type they want to use @@ -701,6 +877,13 @@ RxAmplify.Auth.signIn("username", "password", options).subscribe( // Then invoke `confirmSignIn` api with the code break; } + case CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE: { + Log.i("AuthQuickstart", "Email code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); + Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo()); + // Prompt the user to enter the Email MFA code they received + // Then invoke `confirmSignIn` api with the code + break; + } case CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE: { Log.i("AuthQuickstart", "Custom challenge, additional info: " + nextStep.getAdditionalInfo()); // Prompt the user to enter custom challenge answer @@ -848,20 +1031,35 @@ RxAmplify.Auth.confirmSignIn( ### Confirm signin with TOTP MFA -If the next step is `confirmSignInWithTOTPCode`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. +If the next step is `CONFIRM_SIGN_IN_WITH_TOTP_CODE`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. +### Confirm signin with Email MFA + +If the next step is `CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE`, Amplify Auth has sent the user a random code to their email address and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. + +Note: the signIn result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. + ### Continue signin with MFA Selection -If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently only supports SMS and TOTP as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. +If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SELECTION`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. + +### Continue signin with Email Setup + +If the next step is `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. ### Continue signin with TOTP Setup -If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. +If the next step is `CONTINUE_SIGN_IN_WITH_TOTP_SETUP`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. Once the authenticator app is set up, the user can generate a TOTP code and provide it to the library to complete the sign in process. +### Continue signin with MFA Setup Selection + +If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION`, the user must select the MFA method to setup. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. + + ### Confirm signin with custom challenge If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the Lambda trigger you setup when you configured a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. @@ -1283,7 +1481,7 @@ func signIn(username: String, password: String) async { let signInResult = try await Amplify.Auth.signIn(username: username, password: password) switch signInResult.nextStep { case .confirmSignInWithSMSMFACode(let deliveryDetails, let info): - print("SMS code send to \(deliveryDetails.destination)") + print("SMS code sent to \(deliveryDetails.destination)") print("Additional info \(String(describing: info))") // Prompt the user to enter the SMSMFA code they received @@ -1294,6 +1492,13 @@ func signIn(username: String, password: String) async { // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code + + case .confirmSignInWithEmailMFACode(let deliveryDetails, let info): + print("Email code sent to \(deliveryDetails.destination)") + print("Additional info \(String(describing: info))") + + // Prompt the user to enter the Email MFA code they received + // Then invoke `confirmSignIn` api with the code case .continueSignInWithTOTPSetup(let setUpDetails): print("Received next step as continue sign in by setting up TOTP") @@ -1302,6 +1507,19 @@ func signIn(username: String, password: String) async { // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code + case .continueSignInWithEmailMFASetup: + print("Received next step as continue sign in by setting up email MFA") + + // Prompt the user to enter the email address they wish to use for MFA + // Then invoke `confirmSignIn` api with the email address + + case .continueSignInWithMFASetupSelection(let allowedMFATypes): + print("Received next step as continue sign in by selecting MFA type to setup") + print("Allowed MFA types \(allowedMFATypes)") + + // Prompt the user to select the MFA type they want to setup + // Then invoke `confirmSignIn` api with the MFA type + case .continueSignInWithMFASelection(let allowedMFATypes): print("Received next step as continue sign in by selecting MFA type") print("Allowed MFA types \(allowedMFATypes)") @@ -1474,9 +1692,71 @@ func confirmSignIn(totpCode: String) -> AnyCancellable { +### Confirm signin with Email MFA +If the next step is `confirmSignInWithEmailMFACode`, Amplify Auth has sent a random code to the user's email address, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. + +Note: the signin result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. + + + + + +```swift +func confirmSignIn(confirmationCodeFromUser: String) async { + do { + let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: confirmationCodeFromUser) + if signInResult.isSignedIn { + print("Confirm sign in succeeded. The user is signed in.") + } else { + print("Confirm sign in succeeded.") + print("Next step: \(signInResult.nextStep)") + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + } catch let error as AuthError { + print("Confirm sign in failed \(error)") + } catch { + print("Unexpected error: \(error)") + } +} +``` + + + + + +```swift +func confirmSignIn(confirmationCodeFromUser: String) -> AnyCancellable { + Amplify.Publisher.create { + try await Amplify.Auth.confirmSignIn(challengeResponse: confirmationCodeFromUser) + }.sink { + if case let .failure(authError) = $0 { + print("Confirm sign in failed \(authError)") + } + } + receiveValue: { signInResult in + if signInResult.isSignedIn { + print("Confirm sign in succeeded. The user is signed in.") + } else { + print("Confirm sign in succeeded.") + print("Next step: \(signInResult.nextStep)") + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + } +} +``` + + + + + + ### Continue signin with MFA Selection -If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently only supports SMS and TOTP as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. +If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. @@ -1523,6 +1803,19 @@ func confirmSignInWithTOTPAsMFASelection() -> AnyCancellable { + +### Continue signin with Email Setup +If the next step is `continueSignInWithEmailMFASetup`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. + +```swift +// Confirm sign in with Email Setup +case .continueSignInWithEmailMFASetup: + print("Received next step as continue sign in by setting up email MFA") + + // Prompt the user to enter the email address they wish to use for MFA + // Then invoke `confirmSignIn` api with the email address +``` + ### Continue signin with TOTP Setup If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. @@ -1596,6 +1889,57 @@ func confirmSignInWithTOTPSetup(totpCodeFromAuthenticatorApp: String) -> AnyCanc + +### Continue signin with MFA Setup Selection + +If the next step is `continueSignInWithMFASetupSelection`, the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. + + + + + +```swift +func continueSignInWithEmailMFASetupSelection() async { + do { + let signInResult = try await Amplify.Auth.confirmSignIn( + challengeResponse: MFAType.email.challengeResponse) + + if case .confirmSignInWithTOTPCode = signInResult.nextStep { + print("Received next step as confirm sign in with TOTP") + } + + } catch { + print("Confirm sign in failed \(error)") + } +} +``` + + + + + +```swift +func continueSignInWithEmailMFASetupSelection() -> AnyCancellable { + Amplify.Publisher.create { + try await Amplify.Auth.confirmSignIn( + challengeResponse: MFAType.email.challengeResponse) + }.sink { + if case let .failure(authError) = $0 { + print("Confirm sign in failed \(authError)") + } + } + receiveValue: { signInResult in + if case .confirmSignInWithTOTPCode = signInResult.nextStep { + print("Received next step as confirm sign in with TOTP") + } + } +} +``` + + + + + ### Confirm signin with custom challenge If the next step is `confirmSignInWithCustomChallenge`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the Lambda trigger you setup when you configured a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. From d25eb65ddef3d3fad9ffa1f491a7c3701c35cc23 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Thu, 3 Oct 2024 08:41:08 -0700 Subject: [PATCH 02/44] feat(docs): update flutter fn names --- .../auth/concepts/multi-factor-authentication/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 420cc8da88f..cc001058399 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -872,7 +872,7 @@ await signUp({ ```dart -Future signUpWithPhoneVerification( +Future signUpWithEmailVerification( String username, String password, ) async { @@ -932,7 +932,7 @@ await confirmSignUp({ ```dart -Future confirmSignUpPhoneVerification( +Future confirmSignUpEmailVerification( String username, String otpCode, ) async { From d2c62f619754678a6c7885253e28e4e9358ea792 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Tue, 8 Oct 2024 09:06:46 -0700 Subject: [PATCH 03/44] chore: resolve accessibility issues --- .../auth/multi-step-sign-in/index.mdx | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 72b9a83a0f4..34d67cb6bf8 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -88,7 +88,7 @@ Future _handleSignInResult(SignInResult result) async { } } ``` -### Confirm signin with SMS MFA +## Confirm signin with SMS MFA If the next step is `confirmSignInWithSmsMfaCode`, Amplify Auth has sent the user a random code over SMS and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -130,7 +130,7 @@ Future confirmMfaUser(String mfaCode) async { } ``` -### Confirm signin with TOTP MFA +## Confirm signin with TOTP MFA If the next step is `confirmSignInWithTOTPCode`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. @@ -161,7 +161,7 @@ Future confirmTotpUser(String totpCode) async { } ``` -### Confirm signin with Email MFA +## Confirm signin with Email MFA If the next step is `confirmSignInWithEmailMfaCode`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -204,7 +204,7 @@ Future confirmMfaUser(String mfaCode) async { ``` -### Continue signin with MFA Selection +## Continue signin with MFA Selection If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. @@ -242,7 +242,7 @@ Future _handleMfaSelection(MfaType selection) async { } ``` -### Continue signin with Email Setup +## Continue signin with Email Setup If the next step is `continueSignInWithEmailMfaSetup`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. @@ -270,7 +270,7 @@ Future confirmTotpUser(String emailAddress) async { } ``` -### Continue signin with TOTP Setup +## Continue signin with TOTP Setup If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. @@ -303,7 +303,7 @@ Future confirmTotpUser(String totpCode) async { } ``` -### Continue signin with MFA Setup Selection +## Continue signin with MFA Setup Selection If the next step is `continueSignInWithMfaSetupSelection`, then the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. The MFA types which are currently supported by Amplify Auth are: @@ -340,7 +340,7 @@ Future _handleMfaSelection(MfaType selection) async { } ``` -### Confirm signin with custom challenge +## Confirm signin with custom challenge If the next step is `confirmSignInWithCustomChallenge`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). @@ -382,7 +382,7 @@ If `failAuthentication=true` is returned by the Lambda, Cognito will invalidate -### Confirm signin with new password +## Confirm signin with new password If the next step is `confirmSignInWithNewPassword`, Amplify Auth requires the user choose a new password they proceeding with the sign in. Prompt the user for a new password and pass it to the `confirmSignIn` API. @@ -411,7 +411,7 @@ Future confirmNewPassword(String newPassword) async { } ``` -### Reset password +## Reset password If the next step is `resetPassword`, Amplify Auth requires that the user reset their password before proceeding. Use the `resetPassword` API to guide the user through resetting their password, then call `Amplify.Auth.signIn` when that's complete to restart the sign-in flow. @@ -448,7 +448,7 @@ void _handleCodeDelivery(AuthCodeDeliveryDetails codeDeliveryDetails) { ); } ``` -### Confirm Signup +## Confirm Signup If the next step is `resetPassword`, Amplify Auth requires that the user confirm their email or phone number before proceeding. Use the `resendSignUpCode` API to send a new sign up code to the registered email or phone number, followed by `confirmSignUp` to complete the sign up. @@ -502,7 +502,7 @@ Future confirmSignUp({ Once the sign up is confirmed, call `Amplify.Auth.signIn` again to restart the sign-in flow. -### Done +## Done The sign-in flow is complete when the next step is `done`, which means the user is successfully authenticated. As a convenience, the `SignInResult` also provides the `isSignedIn` property, which will be true if the next step is `done`. @@ -929,7 +929,7 @@ RxAmplify.Auth.signIn("username", "password", options).subscribe( -### Confirm signin with SMS MFA +## Confirm signin with SMS MFA If the next step is `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE`, Amplify Auth has sent the user a random code over SMS, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. @@ -1029,38 +1029,38 @@ RxAmplify.Auth.confirmSignIn( -### Confirm signin with TOTP MFA +## Confirm signin with TOTP MFA If the next step is `CONFIRM_SIGN_IN_WITH_TOTP_CODE`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. -### Confirm signin with Email MFA +## Confirm signin with Email MFA If the next step is `CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE`, Amplify Auth has sent the user a random code to their email address and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. Note: the signIn result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. -### Continue signin with MFA Selection +## Continue signin with MFA Selection If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SELECTION`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. -### Continue signin with Email Setup +## Continue signin with Email Setup If the next step is `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. -### Continue signin with TOTP Setup +## Continue signin with TOTP Setup If the next step is `CONTINUE_SIGN_IN_WITH_TOTP_SETUP`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. Once the authenticator app is set up, the user can generate a TOTP code and provide it to the library to complete the sign in process. -### Continue signin with MFA Setup Selection +## Continue signin with MFA Setup Selection If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION`, the user must select the MFA method to setup. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. -### Confirm signin with custom challenge +## Confirm signin with custom challenge If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the Lambda trigger you setup when you configured a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. @@ -1174,7 +1174,7 @@ NotAuthorizedException{message=Failed since user is not authorized., cause=NotAu -### Confirm signin with new password +## Confirm signin with new password If you receive a `UserNotConfirmedException` while signing in, Amplify Auth requires a new password for the user before they can proceed. Prompt the user for a new password and pass it to the `confirmSignIn` API. @@ -1265,7 +1265,7 @@ RxAmplify.Auth.confirmSignIn( -### Reset password +## Reset password If you receive `PasswordResetRequiredException`, authentication flow could not proceed without resetting the password. The next step is to invoke `resetPassword` api and follow the reset password flow. @@ -1327,7 +1327,7 @@ RxAmplify.Auth.resetPassword( -### Confirm Signup +## Confirm Signup If you receive `CONFIRM_SIGN_UP` as a next step, sign up could not proceed without confirming user information such as email or phone number. The next step is to invoke the `confirmSignUp` API and follow the confirm signup flow. @@ -1397,7 +1397,7 @@ RxAmplify.Auth.confirmSignUp( -### Get Current User +## Get Current User This call fetches the current logged in user and should be used after a user has been successfully signed in. If the user is signed in, it will return the current userId and username. @@ -1453,7 +1453,7 @@ try { -### Done +## Done Sign In flow is complete when you get `done`. This means the user is successfully authenticated. As a convenience, the SignInResult also provides the `isSignedIn` property, which will be true if the next step is `done`. @@ -1571,7 +1571,7 @@ func signIn(username: String, password: String) async { The `nextStep` property is of enum type `AuthSignInStep`. Depending on its value, your code should take one of the following actions: -### Confirm signin with SMS MFA +## Confirm signin with SMS MFA If the next step is `confirmSignInWithSMSMFACode`, Amplify Auth has sent the user a random code over SMS, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. Note: the signin result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial phone number of the SMS recipient. @@ -1632,7 +1632,7 @@ func confirmSignIn(confirmationCodeFromUser: String) -> AnyCancellable { -### Confirm signin with TOTP MFA +## Confirm signin with TOTP MFA If the next step is `confirmSignInWithTOTPCode`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. @@ -1692,7 +1692,7 @@ func confirmSignIn(totpCode: String) -> AnyCancellable { -### Confirm signin with Email MFA +## Confirm signin with Email MFA If the next step is `confirmSignInWithEmailMFACode`, Amplify Auth has sent a random code to the user's email address, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. Note: the signin result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. @@ -1754,7 +1754,7 @@ func confirmSignIn(confirmationCodeFromUser: String) -> AnyCancellable { -### Continue signin with MFA Selection +## Continue signin with MFA Selection If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. @@ -1804,7 +1804,7 @@ func confirmSignInWithTOTPAsMFASelection() -> AnyCancellable { -### Continue signin with Email Setup +## Continue signin with Email Setup If the next step is `continueSignInWithEmailMFASetup`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. ```swift @@ -1816,7 +1816,7 @@ case .continueSignInWithEmailMFASetup: // Then invoke `confirmSignIn` api with the email address ``` -### Continue signin with TOTP Setup +## Continue signin with TOTP Setup If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. @@ -1890,7 +1890,7 @@ func confirmSignInWithTOTPSetup(totpCodeFromAuthenticatorApp: String) -> AnyCanc -### Continue signin with MFA Setup Selection +## Continue signin with MFA Setup Selection If the next step is `continueSignInWithMFASetupSelection`, the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. @@ -1940,7 +1940,7 @@ func continueSignInWithEmailMFASetupSelection() -> AnyCancellable { -### Confirm signin with custom challenge +## Confirm signin with custom challenge If the next step is `confirmSignInWithCustomChallenge`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the Lambda trigger you setup when you configured a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. @@ -2011,7 +2011,7 @@ Exception: notAuthorized{message=Failed since user is not authorized., cause=No -### Confirm signin with new password +## Confirm signin with new password If the next step is `confirmSignInWithNewPassword`, Amplify Auth requires a new password for the user before they can proceed. Prompt the user for a new password and pass it to the `confirmSignIn` API. @@ -2071,7 +2071,7 @@ func confirmSignIn(newPasswordFromUser: String) -> AnyCancellable { -### Reset password +## Reset password If you receive `resetPassword`, authentication flow could not proceed without resetting the password. The next step is to invoke `resetPassword` api and follow the reset password flow. @@ -2117,7 +2117,7 @@ func resetPassword(username: String) -> AnyCancellable { -### Confirm Signup +## Confirm Signup If you receive `confirmSignUp` as a next step, sign up could not proceed without confirming user information such as email or phone number. The next step is to invoke the `confirmSignUp` API and follow the confirm signup flow. @@ -2164,7 +2164,7 @@ func confirmSignUp(for username: String, with confirmationCode: String) -> AnyCa -### Done +## Done Signin flow is complete when you get `done`. This means the user is successfully authenticated. As a convenience, the SignInResult also provides the `isSignedIn` property, which will be true if the next step is `done`. From 6d46e967e3b7b46055a767018ab16a3a103b09b8 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 12:42:37 -0700 Subject: [PATCH 04/44] feat(auth): add ASF pricing callout --- .../auth/concepts/multi-factor-authentication/index.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index cc001058399..e8f165d00dd 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -850,6 +850,10 @@ In order to send email authentication codes, the following prerequisites must be + +Additional pricing applies for ASF. [Learn more about Amazon Cognito pricing](https://aws.amazon.com/cognito/pricing/) + + ### Enable EMAIL MFA during sign-up You will need to pass `email` as a user attribute to enable email MFA for your users during sign-up. However, if the primary sign-in mechanism for your Cognito resource is already `email` (without enabling `username`), then you do not need to pass it as an attribute. From 29a99a6180a21932b387f024b7106bb544ea4de9 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:50:04 -0700 Subject: [PATCH 05/44] feat(auth): add android inline filter sections --- next-env.d.ts | 2 +- .../multi-factor-authentication/index.mdx | 359 +++++++++++++++++- 2 files changed, 354 insertions(+), 7 deletions(-) diff --git a/next-env.d.ts b/next-env.d.ts index 4f11a03dc6c..a4a7b3f5cfa 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index e8f165d00dd..fd58b891811 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -858,7 +858,7 @@ Additional pricing applies for ASF. [Learn more about Amazon Cognito pricing](ht You will need to pass `email` as a user attribute to enable email MFA for your users during sign-up. However, if the primary sign-in mechanism for your Cognito resource is already `email` (without enabling `username`), then you do not need to pass it as an attribute. - + ```ts import { signUp } from 'aws-amplify/auth'; @@ -874,6 +874,84 @@ await signUp({ ``` + + + + + +```java +ArrayList attributes = new ArrayList<>(); +attributes.add(new AuthUserAttribute(AuthUserAttributeKey.email(), "my@email.com")); +attributes.add(new AuthUserAttribute(AuthUserAttributeKey.phoneNumber(), "+15551234567")); + +Amplify.Auth.signUp( + "username", + "Password123", + AuthSignUpOptions.builder().userAttributes(attributes).build(), + result -> Log.i("AuthQuickstart", result.toString()), + error -> Log.e("AuthQuickstart", error.toString()) +); +``` + + + + +```kotlin +val attrs = mapOf( + AuthUserAttributeKey.email() to "my@email.com", + AuthUserAttributeKey.phoneNumber() to "+15551234567" +) +val options = AuthSignUpOptions.builder() + .userAttributes(attrs.map { AuthUserAttribute(it.key, it.value) }) + .build() +Amplify.Auth.signUp("username", "Password123", options, + { Log.i("AuthQuickstart", "Sign up result = $it") }, + { Log.e("AuthQuickstart", "Sign up failed", it) } +) +``` + + + + +```kotlin +val attrs = mapOf( + AuthUserAttributeKey.email() to "my@email.com", + AuthUserAttributeKey.phoneNumber() to "+15551234567" +) +val options = AuthSignUpOptions.builder() + .userAttributes(attrs.map { AuthUserAttribute(it.key, it.value) }) + .build() +try { + val result = Amplify.Auth.signUp("username", "Password123", options) + Log.i("AuthQuickstart", "Sign up OK: $result") +} catch (error: AuthException) { + Log.e("AuthQuickstart", "Sign up failed", error) +} +``` + + + + +```java +ArrayList attributes = new ArrayList<>(); +attributes.add(new AuthUserAttribute(AuthUserAttributeKey.email(), "my@email.com")); +attributes.add(new AuthUserAttribute(AuthUserAttributeKey.phoneNumber(), "+15551234567")); + +RxAmplify.Auth.signUp( + "username", + "Password123", + AuthSignUpOptions.builder().userAttributes(attributes).build()) + .subscribe( + result -> Log.i("AuthQuickstart", result.toString()), + error -> Log.e("AuthQuickstart", error.toString()) + ); +``` + + + + + + ```dart Future signUpWithEmailVerification( @@ -923,7 +1001,7 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri By default, you have to verify a user account after they sign up using the `confirmSignUp` API. Following the initial `signUp` request, a one-time passcode will be sent to the user's phone number or email, depending on your Amazon Cognito configuration. - + ```ts import { confirmSignUp } from 'aws-amplify/auth'; @@ -934,6 +1012,74 @@ await confirmSignUp({ ``` + + + + + +```java + try { + Amplify.Auth.confirmSignUp( + "username", + "confirmation code", + result -> Log.i("AuthQuickstart", "Confirm signUp result completed: " + result.isSignUpComplete()), + error -> Log.e("AuthQuickstart", "An error occurred while confirming sign up: " + error) + ); +} catch (Exception error) { + Log.e("AuthQuickstart", "unexpected error: " + error); +} +``` + + + + +```kotlin + try { + Amplify.Auth.confirmSignUp( + "username", + "confirmation code", + { result -> + Log.i("AuthQuickstart", "Confirm signUp result completed: ${result.isSignUpComplete}") + } + ) { error -> + Log.e("AuthQuickstart", "An error occurred while confirming sign up: $error") + } +} catch (error: Exception) { + Log.e("AuthQuickstart", "unexpected error: $error") +} +``` + + + + +```kotlin +try { + val result = Amplify.Auth.confirmSignUp( + "username", + "confirmation code" + ) + Log.i("AuthQuickstart", "Confirm signUp result completed: ${result.isSignUpComplete}") +} catch (error: Exception) { + Log.e("AuthQuickstart", "unexpected error: $error") +} +``` + + + + +```java +RxAmplify.Auth.confirmSignUp( + "username", + "confirmation code").subscribe( + result -> Log.i("AuthQuickstart", "Confirm signUp result completed: " + result.isSignUpComplete()), + error -> Log.e("AuthQuickstart", "An error occurred while confirming sign up: " + error) +); +``` + + + + + ```dart Future confirmSignUpEmailVerification( @@ -973,7 +1119,7 @@ After a user signs in, if they have MFA enabled for their account, a challenge w If MFA is **ON** or enabled for the user, you must call `confirmSignIn` with the OTP sent to their email address. - + ```ts import { confirmSignIn } from 'aws-amplify/auth'; @@ -982,6 +1128,101 @@ await confirmSignIn({ }); ``` + + + + + +```java +try { + Amplify.Auth.confirmSignIn( + "confirmation code", + result -> { + if (result.isSignedIn()) { + Log.i("AuthQuickstart", "Confirm signIn succeeded"); + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + }, + error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error) + ); +} catch (Exception error) { + Log.e("AuthQuickstart", "Unexpected error: " + error); +} +``` + + + + +```kotlin +try { + Amplify.Auth.confirmSignIn( + "confirmation code", + { result -> + if (result.isSignedIn) { + Log.i("AuthQuickstart","Confirm signIn succeeded") + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: ${result.nextStep}") + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + } + ) { error -> Log.e("AuthQuickstart", "Confirm sign in failed: $error")} +} catch (error: Exception) { + Log.e("AuthQuickstart", "Unexpected error: $error") +} +``` + + + + +```kotlin +try { + val result = Amplify.Auth.confirmSignIn( + "confirmation code" + ) + if (result.isSignedIn) { + Log.i("AuthQuickstart", "Confirm signIn succeeded") + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: ${result.nextStep}" + ) + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } +} catch (error: Exception) { + Log.e("AuthQuickstart", "Unexpected error: $error") +} +``` + + + + +```java + +RxAmplify.Auth.confirmSignIn( + "confirmation code").subscribe( + result -> { + if (result.isSignedIn()) { + Log.i("AuthQuickstart", "Confirm signIn succeeded"); + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + }, + error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error) + ); +``` + + + + ```dart @@ -1011,7 +1252,7 @@ func confirmSignIn() async { After a user has been signed in, call `updateMFAPreference` to record the MFA type as enabled for the user and optionally set it as preferred so that subsequent logins default to using this MFA type. - + ```ts import { updateMFAPreference } from 'aws-amplify/auth'; @@ -1019,6 +1260,44 @@ await updateMFAPreference({ email: 'PREFERRED' }); ``` + + + + +```java +if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") instanceof AWSCognitoAuthPlugin) { + AWSCognitoAuthPlugin plugin = (AWSCognitoAuthPlugin) Amplify.Auth.getPlugin("awsCognitoAuthPlugin"); + plugin.updateMFAPreference( + MfaPreference.DISABLED, // SMS Preference + MfaPreference.DISABLED, // TOTP Preference + MfaPreference.PREFERRED, // Email Preference + () -> Log.i("AuthQuickstart", "MFA preference updated successfully"), + e -> Log.e("AuthQuickstart", "Failed to update MFA preference.", e) + ); + } +``` + + + + +```kotlin +if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin) { + val plugin = Amplify.Auth.getPlugin("awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin + plugin.updateMFAPreference( + MfaPreference.DISABLED, // SMS Preference + MfaPreference.DISABLED, // TOTP Preference + MfaPreference.PREFERRED, // Email Preference + { Log.i("AuthQuickstart", "MFA preference updated successfully" ) }, + { e: AuthException? -> Log.e("AuthQuickstart", "Failed to update MFA preference", e) } + ) +} +``` + + + + + + ```dart Future updateMfaPreferences() async { @@ -1051,7 +1330,7 @@ func updateMFAPreferences() async throws { Invoke the following API to get the current MFA preference and enabled MFA types, if any, for the current user. - + ```ts import { fetchMFAPreference } from 'aws-amplify/auth'; @@ -1059,6 +1338,38 @@ const { enabled, preferred } = await fetchMFAPreference(); ``` + + + + +```java +if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") instanceof AWSCognitoAuthPlugin) { + AWSCognitoAuthPlugin plugin = (AWSCognitoAuthPlugin) Amplify.Auth.getPlugin("awsCognitoAuthPlugin"); + plugin.fetchMFAPreference( + preference -> Log.i( + "AuthQuickStart", + "Fetched MFA preference, enabled: " + preference.getEnabled() + ", preferred: " + preference.getPreferred() + ), + e -> Log.e("AuthQuickStart", "Failed to fetch MFA preference.", e) + ); +} +``` + + + + +```kotlin +val cognitoAuthPlugin = Amplify.Auth.getPlugin("awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin +cognitoAuthPlugin?.fetchMFAPreference( + { Log.d("AuthQuickStart", "Fetched MFA preference, enabled: ${it.enabled}, preferred: ${it.preferred}") }, + { Log.e("AuthQuickStart", "Failed to fetch MFA preference.", it) } +) +``` + + + + + ```dart Future getCurrentMfaPreference() async { @@ -1095,7 +1406,7 @@ Only one MFA method can be marked as preferred at a time. If the user has multip - + ```ts import { updateMFAPreference } from 'aws-amplify/auth'; @@ -1103,6 +1414,42 @@ await updateMFAPreference({ sms: 'ENABLED', totp: 'PREFERRED' }); ``` + + + + +```java +if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") instanceof AWSCognitoAuthPlugin) { + AWSCognitoAuthPlugin plugin = (AWSCognitoAuthPlugin) Amplify.Auth.getPlugin("awsCognitoAuthPlugin"); + plugin.updateMFAPreference( + MFAPreference.DISABLED, // SMS Preference + MFAPreference.PREFERRED, // TOTP Preference + null // Email Preference + () -> Log.i( "AuthQuickStart", "Preference updated successfully"), + e -> Log.e("AuthQuickStart", "Failed to update MFA preference.", e) + ); +} +``` + + + + +```kotlin +val cognitoAuthPlugin = Amplify.Auth.getPlugin("awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin +cognitoAuthPlugin?.updateMFAPreference( + MFAPreference.DISABLED, // SMS Preference + MFAPreference.PREFERRED, // TOTP Preference + null, // Email Preference + { Log.d("AuthQuickStart", "Preference updated successfully") }, + { Log.e("AuthQuickStart", "Failed to update MFA preference.", it) } +) +``` + + + + + + ```dart Future updateMfaPreferences() async { From bc2b5808537b785e2374d1fba988948a8511588d Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:53:20 -0700 Subject: [PATCH 06/44] feat(docs): Update src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx Co-authored-by: josef --- .../auth/concepts/multi-factor-authentication/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index fd58b891811..6c81b533c15 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -28,7 +28,7 @@ export function getStaticProps() { }; } -Amplify Auth supports Multi-factor Authentication (MFA) for user sign-in flows. MFA is an extra layer of security used to make sure that users trying to gain access to an account are who they say they are. It requires users to provide additional information to verify their identity. Amplify Auth supports MFA with Time-based-One-Time Passwords (TOTP), text messages (SMS), and email. +Amplify Auth supports multi-factor authentication (MFA) for user sign-in flows. MFA is an extra layer of security used to make sure that users trying to gain access to an account are who they say they are. It requires users to provide additional information to verify their identity. Amplify Auth supports MFA with time-based one-time passwords (TOTP), text messages (SMS), and email. In this guide we will review how you can set up MFA with each of these methods and the discuss tradeoffs between them to help you choose the right setup for your application. We will also review how to set up MFA to remember a device and reduce sign-in friction for your users. From 46ac26d91637af92d771fd1a1fc99fc933227393 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:53:38 -0700 Subject: [PATCH 07/44] feat(docs): Update src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com> --- .../build-a-backend/auth/multi-step-sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 34d67cb6bf8..65d3ecdaa81 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -1693,7 +1693,7 @@ func confirmSignIn(totpCode: String) -> AnyCancellable { ## Confirm signin with Email MFA -If the next step is `confirmSignInWithEmailMFACode`, Amplify Auth has sent a random code to the user's email address, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. +If the next step is `confirmSignInWithOTP`, Amplify Auth has sent a random code to the user's email address, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. Note: the signin result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. From 7b9e8d9761fef805c759dc192e812d1703120238 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:53:51 -0700 Subject: [PATCH 08/44] feat(docs): Update src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com> --- .../[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 65d3ecdaa81..7e0622f7f41 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -1495,7 +1495,6 @@ func signIn(username: String, password: String) async { case .confirmSignInWithEmailMFACode(let deliveryDetails, let info): print("Email code sent to \(deliveryDetails.destination)") - print("Additional info \(String(describing: info))") // Prompt the user to enter the Email MFA code they received // Then invoke `confirmSignIn` api with the code From d37790e390c2514eda73fd463aa083483b9b1de7 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:54:01 -0700 Subject: [PATCH 09/44] feat(docs): Update src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com> --- .../build-a-backend/auth/multi-step-sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 7e0622f7f41..1038d50c683 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -1493,7 +1493,7 @@ func signIn(username: String, password: String) async { // Prompt the user to enter the TOTP code generated in their authenticator app // Then invoke `confirmSignIn` api with the code - case .confirmSignInWithEmailMFACode(let deliveryDetails, let info): + case .confirmSignInWithOTP(let deliveryDetails): print("Email code sent to \(deliveryDetails.destination)") // Prompt the user to enter the Email MFA code they received From e7f8d3bf0ff0c6dc6ff01edf1b63ffbb6acd68d5 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:54:44 -0700 Subject: [PATCH 10/44] feat(docs): Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com> --- .../auth/connect-your-frontend/sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 7a398c8066e..44bf24d19d7 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -278,7 +278,7 @@ The `signIn` API response will include a `nextStep` property, which can be used | `confirmSignInWithCustomChallenge` | The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. | | `confirmSignInWithTOTPCode` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | | `confirmSignInWithSMSMFACode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | -| `confirmSignInWithEmailMFACode` | The sign-in must be confirmed with a EMAIL code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithOTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `continueSignInWithMFASelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | | `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | | `continueSignInWithTOTPSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | From 3b430392a5fecc2311740d7ae6d8f8a22b2a78be Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 21 Oct 2024 13:54:58 -0700 Subject: [PATCH 11/44] feat(docs): Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com> --- .../auth/connect-your-frontend/sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 44bf24d19d7..7e7fa79c715 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -568,7 +568,7 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | --------- | ----------- | | `confirmSignInWithTOTPCode` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | | `confirmSignInWithSMSMFACode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | -| `confirmSignInWithEmailMFACode` | The sign-in must be confirmed with a EMAIL code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithOTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `continueSignInWithMFASelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | | `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | | `continueSignInWithTOTPSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | From 0fbd66b13eae10468574361bbcb94eaa5e6a85f2 Mon Sep 17 00:00:00 2001 From: Vincent Tran Date: Wed, 23 Oct 2024 15:59:39 -0700 Subject: [PATCH 12/44] feat(docs): Update android specific additions and fixes for email mfa --- .../multi-factor-authentication/index.mdx | 24 ++-- .../connect-your-frontend/sign-in/index.mdx | 33 +++++- .../connect-your-frontend/sign-up/index.mdx | 9 +- .../auth/multi-step-sign-in/index.mdx | 106 +++++++++--------- 4 files changed, 107 insertions(+), 65 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 6c81b533c15..d6a107f371d 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -1143,7 +1143,7 @@ try { } else { Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step + // If `result.isSignedIn` is true, the next step // is 'done', and the user is now signed in. } }, @@ -1167,7 +1167,7 @@ try { } else { Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: ${result.nextStep}") // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step + // If `result.isSignedIn` is true, the next step // is 'done', and the user is now signed in. } } @@ -1191,7 +1191,7 @@ try { Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: ${result.nextStep}" ) // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step + // If `result.isSignedIn` is true, the next step // is 'done', and the user is now signed in. } } catch (error: Exception) { @@ -1212,7 +1212,7 @@ RxAmplify.Auth.confirmSignIn( } else { Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step + // If `result.isSignedIn` is true, the next step // is 'done', and the user is now signed in. } }, @@ -1268,9 +1268,9 @@ await updateMFAPreference({ email: 'PREFERRED' }); if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") instanceof AWSCognitoAuthPlugin) { AWSCognitoAuthPlugin plugin = (AWSCognitoAuthPlugin) Amplify.Auth.getPlugin("awsCognitoAuthPlugin"); plugin.updateMFAPreference( - MfaPreference.DISABLED, // SMS Preference - MfaPreference.DISABLED, // TOTP Preference - MfaPreference.PREFERRED, // Email Preference + MFAPreference.DISABLED, // SMS Preference + MFAPreference.DISABLED, // TOTP Preference + MFAPreference.PREFERRED, // Email Preference () -> Log.i("AuthQuickstart", "MFA preference updated successfully"), e -> Log.e("AuthQuickstart", "Failed to update MFA preference.", e) ); @@ -1281,12 +1281,12 @@ if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") instanceof AWSCognitoAuthPlug ```kotlin -if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin) { +if (Amplify.Auth.getPlugin("awsCognitoAuthPlugin") is AWSCognitoAuthPlugin) { val plugin = Amplify.Auth.getPlugin("awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin - plugin.updateMFAPreference( - MfaPreference.DISABLED, // SMS Preference - MfaPreference.DISABLED, // TOTP Preference - MfaPreference.PREFERRED, // Email Preference + plugin?.updateMFAPreference( + MFAPreference.DISABLED, // SMS Preference + MFAPreference.DISABLED, // TOTP Preference + MFAPreference.PREFERRED, // Email Preference { Log.i("AuthQuickstart", "MFA preference updated successfully" ) }, { e: AuthException? -> Log.e("AuthQuickstart", "Failed to update MFA preference", e) } ) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 7e7fa79c715..ce2b4eeef21 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -253,7 +253,7 @@ func signIn(username: String, password: String) -> AnyCancellable { The `signIn` API response will include a `nextStep` property, which can be used to determine if further action is required. It may return the following next steps: - + | Next Step | Description | | --------- | ----------- | | `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | @@ -268,7 +268,23 @@ The `signIn` API response will include a `nextStep` property, which can be used | `RESET_PASSWORD` | The user must reset their password via `resetPassword`. | | `CONFIRM_SIGN_UP` | The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. | | `DONE` | The sign in process has been completed. | + + +| Next Step | Description | +| --------- | ----------- | +| `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE` | The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_TOTP_CODE` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_OTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | +| `RESET_PASSWORD` | The user must reset their password via `resetPassword`. | +| `CONFIRM_SIGN_UP` | The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. | +| `DONE` | The sign in process has been completed. | @@ -549,7 +565,7 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri ### Confirm sign-in - + Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. | Next Step | Description | | --------- | ----------- | @@ -562,6 +578,19 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | + +Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. +| Next Step | Description | +| --------- | ----------- | +| `CONFIRM_SIGN_IN_WITH_TOTP_CODE` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `CONFIRM_SIGN_IN_WITH_OTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | + + Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. | Next Step | Description | diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx index 4ec2b71b02d..1f32d88199e 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx @@ -285,7 +285,7 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri The `signUp` API response will include a `nextStep` property, which can be used to determine if further action is required. It may return the following next steps: - + | Next Step | Description | | --------- | ----------- | | `CONFIRM_SIGN_UP` | The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp`. | @@ -293,6 +293,13 @@ The `signUp` API response will include a `nextStep` property, which can be used | `COMPLETE_AUTO_SIGN_IN` | The sign up process needs to complete by invoking the `autoSignIn` API. | + +| Next Step | Description | +| --------- | ----------- | +| `CONFIRM_SIGN_UP_STEP` | The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp`. | +| `DONE` | The sign up process has been fully completed. | + + | Next Step | Description | | --------- | ----------- | diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 1038d50c683..b91e5a0640f 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -590,10 +590,10 @@ try { // Then invoke `confirmSignIn` api with the code break; } - case CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE: { - Log.i("AuthQuickstart", "Email code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); + case CONFIRM_SIGN_IN_WITH_OTP: { + Log.i("AuthQuickstart", "OTP code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo()); - // Prompt the user to enter the Email MFA code they received + // Prompt the user to enter the OTP MFA code they received // Then invoke `confirmSignIn` api with the code break; } @@ -690,10 +690,10 @@ try { // Prompt the user to enter the SMS MFA code they received // Then invoke `confirmSignIn` api with the code } - AuthSignInStep.CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE -> { - Log.i("AuthQuickstart", "Email code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); + AuthSignInStep.CONFIRM_SIGN_IN_WITH_OTP -> { + Log.i("AuthQuickstart", "OTP code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo()); - // Prompt the user to enter the Email MFA code they received + // Prompt the user to enter the OTP MFA code they received // Then invoke `confirmSignIn` api with the code } AuthSignInStep.CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE -> { @@ -786,6 +786,12 @@ try { // Prompt the user to enter the SMS MFA code they received // Then invoke `confirmSignIn` api with the code } + AuthSignInStep.CONFIRM_SIGN_IN_WITH_OTP -> { + Log.i("AuthQuickstart", "OTP code sent to ${nextStep.codeDeliveryDetails?.destination}") + Log.i("AuthQuickstart", "Additional Info ${nextStep.additionalInfo}") + // Prompt the user to enter the OTP MFA code they received + // Then invoke `confirmSignIn` api with the code + } AuthSignInStep.CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE -> { Log.i("AuthQuickstart", "Custom challenge, additional info: ${nextStep.additionalInfo}") // Prompt the user to enter custom challenge answer @@ -877,10 +883,10 @@ RxAmplify.Auth.signIn("username", "password", options).subscribe( // Then invoke `confirmSignIn` api with the code break; } - case CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE: { - Log.i("AuthQuickstart", "Email code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); + case CONFIRM_SIGN_IN_WITH_OTP: { + Log.i("AuthQuickstart", "OTP code sent to " + nextStep.getCodeDeliveryDetails().getDestination()); Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo()); - // Prompt the user to enter the Email MFA code they received + // Prompt the user to enter the OTP MFA code they received // Then invoke `confirmSignIn` api with the code break; } @@ -1071,19 +1077,19 @@ If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awa ```java try { Amplify.Auth.confirmSignIn( - "challenge answer", - result -> { - if (result.isSignedIn()) { - Log.i("AuthQuickstart", "Confirm signIn succeeded"); - } else { - Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); - // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step - // is 'done', and the user is now signed in. - } - }, - error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error) - ); + "challenge answer", + result -> { + if (result.isSignedIn()) { + Log.i("AuthQuickstart", "Confirm signIn succeeded"); + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + }, + error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error) + ); } catch (Exception error) { Log.e("AuthQuickstart", "Unexpected error: " + error); } @@ -1095,21 +1101,21 @@ try { ```kotlin try { -Amplify.Auth.confirmSignIn( - "challenge answer", - { result -> - if (result.isSignedIn) { - Log.i("AuthQuickstart","Confirm signIn succeeded") - } else { - Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: ${result.nextStep}") - // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step - // is 'done', and the user is now signed in. - } - } - ) { error -> - Log.e("AuthQuickstart", "Confirm sign in failed: $error") - } + Amplify.Auth.confirmSignIn( + "challenge answer", + { result -> + if (result.isSignedIn) { + Log.i("AuthQuickstart","Confirm signIn succeeded") + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: ${result.nextStep}") + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + } + ) { error -> + Log.e("AuthQuickstart", "Confirm sign in failed: $error") + } } catch (error: Exception) { Log.e("AuthQuickstart", "Unexpected error: $error") } @@ -1144,19 +1150,19 @@ try { ```java RxAmplify.Auth.confirmSignIn( - "challenge answer").subscribe( - result -> { - if (result.isSignedIn()) { - Log.i("AuthQuickstart", "Confirm signIn succeeded"); - } else { - Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); - // Switch on the next step to take appropriate actions. - // If `signInResult.isSignedIn` is true, the next step - // is 'done', and the user is now signed in. - } - }, - error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error) - ); + "challenge answer").subscribe( + result -> { + if (result.isSignedIn()) { + Log.i("AuthQuickstart", "Confirm signIn succeeded"); + } else { + Log.i("AuthQuickstart", "Confirm sign in not complete. There might be additional steps: " + result.getNextStep()); + // Switch on the next step to take appropriate actions. + // If `signInResult.isSignedIn` is true, the next step + // is 'done', and the user is now signed in. + } + }, + error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error) +); ``` From 77d23ae83dbabc48c7b40d8d5e269d816be09fbe Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Fri, 25 Oct 2024 11:15:58 -0700 Subject: [PATCH 13/44] Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx Co-authored-by: Kha Truong <64438356+khatruong2009@users.noreply.github.com> --- .../auth/connect-your-frontend/sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index ce2b4eeef21..fa75657f65c 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -287,7 +287,7 @@ The `signIn` API response will include a `nextStep` property, which can be used | `DONE` | The sign in process has been completed. | - + | Next Step | Description | | --------- | ----------- | | `confirmSignInWithNewPassword` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | From 3ec6c3b5a0d8cc431b02ebbbd7723955222fc10f Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Fri, 25 Oct 2024 11:16:45 -0700 Subject: [PATCH 14/44] Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx Co-authored-by: Kha Truong <64438356+khatruong2009@users.noreply.github.com> --- .../auth/connect-your-frontend/sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index fa75657f65c..9f443fb1c0b 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -591,7 +591,7 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | - + Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. | Next Step | Description | | --------- | ----------- | From 5309c7d2f84a9e56deecbf3cc560f180bb78c9d7 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Fri, 25 Oct 2024 11:17:06 -0700 Subject: [PATCH 15/44] Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx Co-authored-by: Kha Truong <64438356+khatruong2009@users.noreply.github.com> --- .../auth/connect-your-frontend/sign-in/index.mdx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 9f443fb1c0b..3e7e576f56d 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -604,6 +604,19 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | `continueSignInWithEmailMFASetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | + +Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. +| Next Step | Description | +| --------- | ----------- | +| `confirmSignInWithTotpMfaCode` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithSmsMfaCode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithOtpCode` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | +| `continueSignInWithMfaSelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `continueSignInWithMfaSetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithTotpSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `continueSignInWithEmailMfaSetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | + + From 877f5737436005268bb44b3fb9c51c5c29c6baac Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Fri, 25 Oct 2024 11:17:18 -0700 Subject: [PATCH 16/44] Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx Co-authored-by: Kha Truong <64438356+khatruong2009@users.noreply.github.com> --- .../connect-your-frontend/sign-in/index.mdx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 3e7e576f56d..872ba585b83 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -304,6 +304,23 @@ The `signIn` API response will include a `nextStep` property, which can be used | `done` | The sign in process has been completed. | + +| Next Step | Description | +| --------- | ----------- | +| `confirmSignInWithNewPassword` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | +| `confirmSignInWithCustomChallenge` | The sign-in must be confirmed with a custom challenge response. Complete the process with `confirmSignIn`. | +| `confirmSignInWithTotpMfaCode` | The sign-in must be confirmed with a TOTP code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithSmsMfaCode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | +| `confirmSignInWithOtpCode` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | +| `continueSignInWithMfaSelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | +| `continueSignInWithMfaSetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithTotpSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | +| `continueSignInWithEmailMfaSetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | +| `resetPassword` | The user must reset their password via `resetPassword`. | +| `confirmSignUp` | The user hasn't completed the sign-up flow fully and must be confirmed via `confirmSignUp`. | +| `done` | The sign in process has been completed. | + + For more information on handling the MFA steps that may be returned, see [multi-factor authentication](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/). From 9f096353b83bdf4abcae19df90ece8c32191a9c2 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Fri, 25 Oct 2024 11:18:39 -0700 Subject: [PATCH 17/44] Update src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx Co-authored-by: Kha Truong <64438356+khatruong2009@users.noreply.github.com> --- .../build-a-backend/auth/multi-step-sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index b91e5a0640f..288b28c7314 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -258,7 +258,7 @@ Future _handleSignInResult(SignInResult result) async { // Then, pass the email address to `confirmSignIn` -Future confirmTotpUser(String emailAddress) async { +Future confirmEmailUser(String emailAddress) async { try { final result = await Amplify.Auth.confirmSignIn( confirmationValue: emailAddress, From 3784ddca569016442b75886f48c46b93261f73f6 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 28 Oct 2024 15:21:50 -0700 Subject: [PATCH 18/44] chore: remove android tag from JS code example --- .../auth/concepts/multi-factor-authentication/index.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index d6a107f371d..c24bdf0c331 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -78,9 +78,12 @@ When enabling MFA you will have two key decisions to make: - + If multiple MFA methods are enabled for the user, the `signIn` API will return `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. + + + ```ts import { confirmSignIn, SignInOutput } from 'aws-amplify/auth'; From 396d730fd5a6a34e21b804e70df7e5a94174522d Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 28 Oct 2024 15:23:32 -0700 Subject: [PATCH 19/44] chore: add backend support callout --- .../auth/concepts/multi-factor-authentication/index.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index c24bdf0c331..b87c4f1d788 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -54,6 +54,10 @@ export const auth = defineAuth({ }); ``` + +Email-based MFA is currently not supported with `defineAuth`. We are working towards supporting this feature. For more information, visit the [feature request in GitHub](https://github.com/aws-amplify/amplify-backend/issues/2159). + + When MFA is `REQUIRED` with SMS in your backend auth resource, you will need to pass the phone number during sign-up API call. If you are using the `email` or `username` as the primary sign-in mechanism, you will need to pass the `phone_number` attribute as a user attribute. Similarly, when MFA is `REQUIRED` with email as your delivery mechanism, you will need to pass an email address during the sign-up API call. If you are using `phoneNumber` or `username` as the primary sign-in mechanism, you will need to pass the `email` attribute as a user attribute. From 4ca53c81ddf8f1823c8359050bcdc3fcee59b229 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 28 Oct 2024 15:40:49 -0700 Subject: [PATCH 20/44] chore: create MfaType type --- .../auth/concepts/multi-factor-authentication/index.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index b87c4f1d788..4f3009c2269 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -111,13 +111,15 @@ function handleSignInNextSteps(output: SignInOutput) { } } +type MfaType = 'SMS' | 'TOTP' | 'EMAIL'; + function promptUserForMFAType( - allowedMFATypes?: ('SMS' | 'TOTP' | 'EMAIL')[] -): 'SMS' | 'TOTP' | 'EMAIL' { + allowedMFATypes?: MfaType[] +): MfaType { // Prompt user to select MFA type } -async function handleMFASelection(mfaType: 'SMS' | 'TOTP' | 'EMAIL') { +async function handleMFASelection(mfaType: MfaType) { try { const output = await confirmSignIn({ challengeResponse: mfaType From 53f3bcd6924a08b707075d4ce7b690285d2aab42 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 28 Oct 2024 16:54:32 -0700 Subject: [PATCH 21/44] chore: use type imports where applicable --- .../multi-factor-authentication/index.mdx | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 4f3009c2269..a4e10bd1aa2 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -89,45 +89,43 @@ If multiple MFA methods are enabled for the user, the `signIn` API will return ` ```ts -import { confirmSignIn, SignInOutput } from 'aws-amplify/auth'; +import { confirmSignIn, type SignInOutput } from 'aws-amplify/auth'; function handleSignInNextSteps(output: SignInOutput) { - const { nextStep } = output; - switch (nextStep.signInStep) { - // ... - case 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION': - const allowedMFATypes = nextStep.allowedMFATypes; - const mfaType = promptUserForMFAType(allowedMFATypes); - case 'CONFIRM_SIGN_IN_WITH_SMS_CODE': - // prompt user to enter otp code delivered via SMS - break; - case 'CONFIRM_SIGN_IN_WITH_TOTP_CODE': - // prompt user to enter otp code from their authenticator app - break; - case 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE': - // prompt user to enter otp code delivered via EMAIL - break; - // ... - } + const { nextStep } = output; + switch (nextStep.signInStep) { + // ... + case 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION': + const allowedMFATypes = nextStep.allowedMFATypes; + const mfaType = promptUserForMFAType(allowedMFATypes); + case 'CONFIRM_SIGN_IN_WITH_SMS_CODE': + // prompt user to enter otp code delivered via SMS + break; + case 'CONFIRM_SIGN_IN_WITH_TOTP_CODE': + // prompt user to enter otp code from their authenticator app + break; + case 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE': + // prompt user to enter otp code delivered via EMAIL + break; + // ... + } } type MfaType = 'SMS' | 'TOTP' | 'EMAIL'; -function promptUserForMFAType( - allowedMFATypes?: MfaType[] -): MfaType { - // Prompt user to select MFA type +function promptUserForMFAType(allowedMFATypes?: MfaType[]): MfaType { + // Prompt user to select MFA type } async function handleMFASelection(mfaType: MfaType) { - try { - const output = await confirmSignIn({ - challengeResponse: mfaType - }); - handleSignInNextSteps(output); - } catch (error) { - console.log(error); - } + try { + const output = await confirmSignIn({ + challengeResponse: mfaType, + }); + handleSignInNextSteps(output); + } catch (error) { + console.log(error); + } } ``` From 7e8ca3f2f039ec751ff37f09baf90f4f336e86b9 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Tue, 29 Oct 2024 09:28:04 -0700 Subject: [PATCH 22/44] chore: revert next-env update --- next-env.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next-env.d.ts b/next-env.d.ts index a4a7b3f5cfa..4f11a03dc6c 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/basic-features/typescript for more information. From 9119a8d109d97de3df8808a2748cfee59ba08981 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Tue, 29 Oct 2024 09:37:45 -0700 Subject: [PATCH 23/44] chore: mention mfa preference in mfa selection challenge --- .../auth/concepts/multi-factor-authentication/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index a4e10bd1aa2..8b1f7ed211f 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -83,7 +83,7 @@ When enabling MFA you will have two key decisions to make: -If multiple MFA methods are enabled for the user, the `signIn` API will return `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. +If multiple MFA methods are enabled for the user, and none are set as preferred, the `signIn` API will return `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. @@ -131,7 +131,7 @@ async function handleMFASelection(mfaType: MfaType) { -If multiple MFA methods are enabled for the user, the `signIn` API will return `continueSignInWithMFASelection` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. +If multiple MFA methods are enabled for the user, and none are set as preferred, the `signIn` API will return `continueSignInWithMFASelection` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. From 22c8c5823d878abe110d21ebd0276a6ac1af8c03 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Tue, 29 Oct 2024 10:23:14 -0700 Subject: [PATCH 24/44] chore: adding account recovery callout --- .../auth/concepts/multi-factor-authentication/index.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 8b1f7ed211f..0955a57a92d 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -854,6 +854,7 @@ Once you have setup email as your second layer of authentication with MFA as sho In order to send email authentication codes, the following prerequisites must be met: - Cognito must be configured to send emails using [Amazon Simple Email Service (Amazon SES)](/[platform]/build-a-backend/auth/moving-to-production/#email). - [Advanced Security Features (ASF)](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) must be enabled in your user pool. +- If account recovery is enabled in Cognito, the delivery method for recovery messages cannot be set to `Email only` From ff8309036eae1aba0b6c112302eb2d1740f4751e Mon Sep 17 00:00:00 2001 From: Vincent Tran Date: Tue, 29 Oct 2024 15:39:00 -0700 Subject: [PATCH 25/44] Add Android CONTINUE_SIGN_IN_WITH_MFA_SELECTION example --- .../multi-factor-authentication/index.mdx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 0955a57a92d..35d46f79f29 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -130,6 +130,40 @@ async function handleMFASelection(mfaType: MfaType) { ``` + +```kotlin +fun signIn(username: String, password: String) { + val result: AuthSignInResult + try { + result = Amplify.Auth.signIn(username, password) + } catch (e: AuthException) { + Log.e("MFASelection", "Failed to sign in", e) + } + handleNextSignInStep(username, result.nextStep) +} + +fun handleNextSignInStep( + username: String, + nextStep: AuthNextSignInStep +) { + when (nextStep.signInStep) { + AuthSignInStep.CONTINUE_SIGN_IN_WITH_MFA_SELECTION -> { + // User has multiple MFA methods and none are preferred + promptUserForMfaType(nextStep.allowedMFATypes) + } + else -> { + // Handle other SignInSteps + } + } +} + +fun promptUserForMfaType(mfaTypes: Set?) { + // Prompt user to select one of the passed-in MFA Types + // Then invoke Amplify.Auth.confirmSignIn(selectedMfaType.challengeResponse) +} +``` + + If multiple MFA methods are enabled for the user, and none are set as preferred, the `signIn` API will return `continueSignInWithMFASelection` as the next step in the auth flow. During this scenario, the user should be prompted to select the MFA method they want to use to sign in and their preference should be passed to `confirmSignIn`. From 130c7527a3bf1e41675caa42cdd32ed71efaa299 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Tue, 29 Oct 2024 21:01:35 -0700 Subject: [PATCH 26/44] chore: adding CDK example for enabling email mfa --- cspell.json | 1 + .../multi-factor-authentication/index.mdx | 2 + .../auth/modify-resources-with-cdk/index.mdx | 55 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/cspell.json b/cspell.json index e4ee6df3832..80ac1464f23 100644 --- a/cspell.json +++ b/cspell.json @@ -851,6 +851,7 @@ "metadata", "mfaDescription", "mfaTypes", + "enabledMfas", "MiB", "middleware", "Millis", diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 35d46f79f29..3982618521b 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -56,6 +56,8 @@ export const auth = defineAuth({ Email-based MFA is currently not supported with `defineAuth`. We are working towards supporting this feature. For more information, visit the [feature request in GitHub](https://github.com/aws-amplify/amplify-backend/issues/2159). + +To take advantage of this feature with an Amplify generated backend, the underlying CDK construct can be extended manually. See [overriding Cognito User Pool multi-factor authentication options](/[platform]/build-a-backend/auth/modify-resources-with-cdk/#override-cognito-userpool-multi-factor-authentication-options) for more information. When MFA is `REQUIRED` with SMS in your backend auth resource, you will need to pass the phone number during sign-up API call. If you are using the `email` or `username` as the primary sign-in mechanism, you will need to pass the `phone_number` attribute as a user attribute. diff --git a/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx b/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx index ceb39bdef66..a09a450ee0b 100644 --- a/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx @@ -57,6 +57,61 @@ cfnUserPool.policies = { }; ``` +## Override Cognito UserPool multi-factor authentication options +While Email MFA is not yet supported with `defineAuth`, this feature can be enabled by modifying the underlying CDK construct. + +Start by ensuring your `defineAuth` resource configuration includes a compatible account recovery option and a custom SES sender. + +```ts title="amplify/auth/resource.ts" +import { defineAuth } from "@aws-amplify/backend" + +/** + * Define and configure your auth resource + * @see https://docs.amplify.aws/gen2/build-a-backend/auth + */ +export const auth = defineAuth({ + loginWith: { + email: true, + phone: true, + }, + multifactor: { + mode: "OPTIONAL", + sms: true, + totp: false, + }, + // Important! The logic to resolve this value cannot determine whether email mfa is enabled when overriding the resource. + // Be sure to pick a recovery option appropriate for your application. + accountRecovery: "EMAIL_AND_PHONE_WITHOUT_MFA", + senders: { + email: { + fromEmail: "registrations@example.com", + }, + }, +}) +``` +Next, extend the underlying CDK construct by activating Advanced Security Mode and adding `EMAIL_OTP` to the enabled MFA options. + +```ts title="amplify/backend.ts" + +import { defineBackend } from "@aws-amplify/backend" +import { auth } from "./auth/resource" + +const backend = defineBackend({ + auth, +}) + +const { cfnUserPool } = backend.auth.resources.cfnResources + +// enable ASF +cfnUserPool.userPoolAddOns = { + advancedSecurityMode: "AUDIT", +} + +// add email mfa +// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html#cfn-cognito-userpool-enabledmfas +cfnUserPool.enabledMfas = [...(cfnUserPool.enabledMfas || []), "EMAIL_OTP"] +``` + {/* token validity */} {/* BYO custom idp construct */} {/* extend auth/unauth roles */} From f505d9ca0118b5d26b1482bfaba3504c64fd9d8a Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 09:18:39 -0700 Subject: [PATCH 27/44] chore: add react native to js examples --- .../auth/connect-your-frontend/sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 872ba585b83..e43becb7a02 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -66,7 +66,7 @@ The quickest way to get started with Amplify Auth in your frontend application i {/* signIn api definition */} - + ```ts import { signIn } from 'aws-amplify/auth' From 5d675fe1ee970659f84e6592f08b49e1af738a2e Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 11:02:26 -0700 Subject: [PATCH 28/44] Apply suggestions from code review Co-authored-by: Tyler Roach Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com> --- .../auth/connect-your-frontend/sign-in/index.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index e43becb7a02..1447c0cadc2 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -279,7 +279,7 @@ The `signIn` API response will include a `nextStep` property, which can be used | `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | | `CONFIRM_SIGN_IN_WITH_OTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | -| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `MFAType.EMAIL.challengeResponse` or `MFAType.TOTP.challengeResponse` to `confirmSignIn`. | | `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | | `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | | `RESET_PASSWORD` | The user must reset their password via `resetPassword`. | @@ -296,7 +296,7 @@ The `signIn` API response will include a `nextStep` property, which can be used | `confirmSignInWithSMSMFACode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | | `confirmSignInWithOTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `continueSignInWithMFASelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | -| `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `MFAType.email.challengeResponse` or `MFAType.totp.challengeResponse ` to `confirmSignIn`. | | `continueSignInWithTOTPSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | | `continueSignInWithEmailMFASetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | | `resetPassword` | The user must reset their password via `resetPassword`. | @@ -603,7 +603,7 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | | `CONFIRM_SIGN_IN_WITH_OTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `CONTINUE_SIGN_IN_WITH_MFA_SELECTION` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | -| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION` | The user must select their mode of MFA verification to setup. Complete the process by passing either `MFAType.EMAIL.challengeResponse` or `MFAType.TOTP.challengeResponse` to `confirmSignIn`. | | `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | | `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | @@ -616,7 +616,7 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | `confirmSignInWithSMSMFACode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | | `confirmSignInWithOTP` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `continueSignInWithMFASelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | -| `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithMFASetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `MFAType.email.challengeResponse` or `MFAType.totp.challengeResponse ` to `confirmSignIn`. | | `continueSignInWithTOTPSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | | `continueSignInWithEmailMFASetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | From 86704dcbca10a15374697062b27e8d75089f7a3a Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 12:49:49 -0700 Subject: [PATCH 29/44] chore: add additional js examples --- .../auth/multi-step-sign-in/index.mdx | 508 +++++++++++++++++- 1 file changed, 507 insertions(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 288b28c7314..6e4a0d683a5 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -4,7 +4,7 @@ export const meta = { title: 'Multi-step sign-in', description: 'Use Amazon Cognito Auth plugin to complete a multi step authentication flow', - platforms: ['android', 'swift', 'flutter'] + platforms: ['android', 'swift', 'flutter', 'react', 'nextjs', 'javascript', 'react-native', 'vue', 'angular'] }; export const getStaticPaths = async () => { @@ -20,6 +20,512 @@ export function getStaticProps(context) { }; } + +After a user has finished signup, they can proceed to sign in. Amplify Auth signin flows can be multi-step processes. The required steps are determined by the configuration provided when you define your auth resources. See the [multi-factor authentication](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/) page for more information. + +Depending on the configuration, you may need to call various APIs to finish authenticating a user's signin attempt. To identify the next step in a signin flow, inspect the `nextStep` parameter of the signin result. + +```typescript +import { + confirmSignIn, + confirmSignUp, + resetPassword, + signIn, +} from 'aws-amplify/auth'; + +const { nextStep } = await signIn({ + username: 'hello@mycompany.com', + password: 'hunter2', +}); + +if ( + nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_SMS_CODE' || + nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE' || + nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_TOTP_CODE' +) { + // collect OTP from user + await confirmSignIn({ + challengeResponse: '123456', + }); +} + +if (nextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION') { + // present nextStep.allowedMFATypes to user + // collect user selection + await confirmSignIn({ + challengeResponse: 'EMAIL', // 'EMAIL', 'SMS', or 'TOTP' + }); +} + +if (nextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION') { + // present nextStep.allowedMFATypes to user + // collect user selection + await confirmSignIn({ + challengeResponse: 'EMAIL', // 'EMAIL' or 'TOTP' + }); +} + +if (nextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_EMAIL_SETUP') { + // collect email address from user + await confirmSignIn({ + challengeResponse: 'hello@mycompany.com', + }); +} + +if (nextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_TOTP_SETUP') { + // present nextStep.totpSetupDetails.getSetupUri() to user + // collect OTP from user + await confirmSignIn({ + challengeResponse: '123456', + }); +} + +if (nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE') { + // collect custom challenge answer from user + await confirmSignIn({ + challengeResponse: 'custom-challenge-answer', + }); +} + +if (nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED') { + // collect new password from user + await confirmSignIn({ + challengeResponse: 'new-password', + }); +} + +if (nextStep.signInStep === 'RESET_PASSWORD') { + // initiate reset password flow + await resetPassword({ + username: 'username', + }); +} + +if (nextStep.signInStep === 'CONFIRM_SIGN_UP') { + // user was not confirmed during sign up process + // if user has confirmation code, invoke `confirmSignUp` api + // otherwise, invoke `resendSignUpCode` to resend the code + await confirmSignUp({ + username: 'username', + confirmationCode: '123456', + }); +} + +if (nextStep.signInStep === 'DONE') { + // signin complete +} +``` + +## Confirm signin with SMS MFA + +If the next step is `CONFIRM_SIGN_IN_WITH_SMS_CODE`, Amplify Auth has sent the user a random code over SMS and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. + + + +The result includes `codeDeliveryDetails` with additional information about the code delivery, such as the partial phone number of the SMS recipient, which can be used to prompt the user on where to look for the code. + + + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONFIRM_SIGN_IN_WITH_SMS_CODE': { + const { codeDeliveryDetails } = result.nextStep; + // OTP has been delivered to user via SMS + // Inspect codeDeliveryDetails for additional delivery information + console.log( + `A confirmation code has been sent to ${codeDeliveryDetails?.destination}`, + ); + console.log( + `Please check your ${codeDeliveryDetails?.deliveryMedium} for the code.`, + ); + break; + } + } +} + +``` + +```ts +async function confirmMfaCode(mfaCode: string) { + const result = await confirmSignIn({ challengeResponse: mfaCode }); + + return handleSignInResult(result); +} + +``` + +## Confirm signin with TOTP MFA + +If the next step is `CONFIRM_SIGN_IN_WITH_TOTP_CODE`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. + +After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. + + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONFIRM_SIGN_IN_WITH_TOTP_CODE': { + // Prompt user to open their authenticator app to retrieve the code + console.log( + `Enter a one-time code from your registered authenticator app`, + ); + break; + } + } +} +// Then, pass the TOTP code to `confirmSignIn` +async function confirmTotpCode(totpCode: string) { + const result = await confirmSignIn({ challengeResponse: totpCode }); + + return handleSignInResult(result); +} + +``` + +## Confirm signin with Email MFA + +If the next step is `CONFIRM_SIGN_IN_WITH_EMAIL_CODE`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. + + + +The result includes `codeDeliveryDetails` with additional information about the code delivery, such as the partial email address of the recipient, which can be used to prompt the user on where to look for the code. + + + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE': { + const { codeDeliveryDetails } = result.nextStep; + // OTP has been delivered to user via Email + // Inspect codeDeliveryDetails for additional delivery information + console.log( + `A confirmation code has been sent to ${codeDeliveryDetails?.destination}`, + ); + console.log( + `Please check your ${codeDeliveryDetails?.deliveryMedium} for the code.`, + ); + break; + } + } +} + +``` + +```ts +async function confirmMfaCode(mfaCode: string) { + const result = await confirmSignIn({ challengeResponse: mfaCode }); + + return handleSignInResult(result); +} + +``` + + +## Continue signin with MFA Selection + +If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SELECTION`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and EMAIL as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. + +The MFA types which are currently supported by Amplify Auth are: + +- `SMS` +- `TOTP` +- `EMAIL` + +Once Amplify receives the users selection, you can expect to handle a follow up `nextStep` corresponding with the selected MFA type for setup: +- If `SMS` is selected, `CONFIRM_SIGN_IN_WITH_SMS_CODE` will be the next step. +- If `TOTP` is selected, `CONFIRM_SIGN_IN_WITH_TOTP_CODE` will be the next step. +- If `EMAIL` is selected, `CONFIRM_SIGN_IN_WITH_EMAIL_CODE` will be the next step. + + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION': { + const { allowedMFATypes } = result.nextStep; + // Present available MFA options to user + // Prompt for selection + console.log(`There are multiple MFA options available for sign in.`); + console.log(`Select an MFA type from the allowedMfaTypes list.`); + break; + } + } +} + +type MfaType = 'SMS' | 'TOTP' | 'EMAIL'; + +async function handleMfaSelection(mfaType: MfaType) { + const result = await confirmSignIn({ challengeResponse: mfaType }); + + return handleSignInResult(result); +} + +``` + +## Continue signin with Email Setup + +If the next step is `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONTINUE_SIGN_IN_WITH_EMAIL_SETUP': { + // Prompt the user to enter an email address they would like to use for MFA + break; + } + } +} + +// Then, pass the email address to `confirmSignIn` +async function confirmEmail(email: string) { + const result = await confirmSignIn({ challengeResponse: email }); + + return handleSignInResult(result); +} + +``` + +## Continue signin with TOTP Setup + +The `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` step signifies that the user must set up TOTP before they can sign in. The step returns an associated value of type TOTPSetupDetails which must be used to configure an authenticator app like Microsoft Authenticator or Google Authenticator. TOTPSetupDetails provides a helper method called getSetupURI which generates a URI that can be used, for example, in a button to open the user's installed authenticator app. For more advanced use cases, TOTPSetupDetails also contains a sharedSecret which can be used to either generate a QR code or be manually entered into an authenticator app. + +Once the authenticator app is set up, the user can generate a TOTP code and provide it to the library to complete the sign in process. + + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONTINUE_SIGN_IN_WITH_TOTP_SETUP': { + const { totpSetupDetails } = result.nextStep; + const appName = 'my_app_name'; + const setupUri = totpSetupDetails.getSetupUri(appName); + // Open setupUri with an authenticator app + // Prompt user to enter OTP code to complete setup + break; + } + } +} + +// Then, pass the collected OTP code to `confirmSignIn` +async function confirmTotpCode(totpCode: string) { + const result = await confirmSignIn({ challengeResponse: totpCode }); + + return handleSignInResult(result); +} + +``` + +## Continue signin with MFA Setup Selection + +If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION`, then the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. + +The MFA types which are currently supported by Amplify Auth for setup are: + +- `TOTP` +- `EMAIL` + +Once Amplify receives the users selection, you can expect to handle a follow up `nextStep` corresponding with the selected MFA type for setup: +- If `EMAIL` is selected, `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP` will be the next step. +- If `TOTP` is selected, `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` will be the next step. + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION': { + const { allowedMFATypes } = result.nextStep; + // Present available MFA options to user + // Prompt for selection + console.log(`There are multiple MFA options available for setup.`); + console.log(`Select an MFA type from the allowedMFATypes list.`); + break; + } + } +} + +type MfaType = 'SMS' | 'TOTP' | 'EMAIL'; + +async function handleMfaSelection(mfaType: MfaType) { + const result = await confirmSignIn({ challengeResponse: mfaType }); + + return handleSignInResult(result); +} + +``` + +## Confirm signin with custom challenge + +If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). + +For example, your custom challenge Lambda may pass a prompt to the frontend which requires the user to enter a secret code. + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE': { + const params = result.nextStep.additionalInfo; + const hint = params.hint!; + // Prompt user to enter custom challenge response + console.log(hint); // `Enter the secret code` + break; + } + } +} + +``` + +To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. + +```ts +async function confirmCustomChallenge(answer: string) { + const result = await confirmSignIn({ challengeResponse: answer }); + + return handleSignInResult(result); +} +``` + + + +**Special Handling on `confirmSignIn`** + +If `failAuthentication=true` is returned by the Lambda, Cognito will invalidate the session of the request. This is represented by a `NotAuthorizedException` and requires restarting the sign-in flow by calling `signIn` again. + + + +## Confirm signin with new password + +If the next step is `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED`, Amplify Auth requires the user choose a new password they proceeding with the sign in. + +Prompt the user for a new password and pass it to the `confirmSignIn` API. + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED': { + // Prompt user to enter a new password + console.log(`Please enter a new password.`); + break; + } + } +} + +``` + +```ts +async function confirmNewPassword(newPassword: string) { + const result = await confirmSignIn({ challengeResponse: newPassword }); + + return handleSignInResult(result); +} + +``` + +## Reset password + +If the next step is `RESET_PASSWORD`, Amplify Auth requires that the user reset their password before proceeding. +Use the `resetPassword` API to guide the user through resetting their password, then call `signIn` to restart the sign-in flow. + +See the [reset password](/[platform]/build-a-backend/auth/manage-users/manage-passwords/) docs for more information. + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'RESET_PASSWORD': { + const resetPasswordResult = await resetPassword({ username }); + // initiate reset password flow + await handleResetPasswordResult(resetPasswordResult); + break; + } + } +} + +async function handleResetPasswordResult( + resetPasswordResult: ResetPasswordOutput, +) { + switch (resetPasswordResult.nextStep.resetPasswordStep) { + case 'CONFIRM_RESET_PASSWORD_WITH_CODE': { + const { codeDeliveryDetails } = resetPasswordResult.nextStep; + console.log( + `A confirmation code has been sent to ${codeDeliveryDetails.destination}.`, + ); + console.log( + `Please check your ${codeDeliveryDetails.destination} for the code.`, + ); + break; + } + case 'DONE': { + console.log(`Successfully reset password.`); + break; + } + } +} + +``` + +## Confirm Signup + +If the next step is `CONFIRM_SIGN_UP`, Amplify Auth requires that the user confirm their email or phone number before proceeding. +Use the `resendSignUpCode` API to send a new sign up code to the registered email or phone number, followed by `confirmSignUp` to complete the sign up. + +See the [confirm sign up](/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/#confirm-sign-up) docs for more information. + + + +The result includes `codeDeliveryDetails` with additional information about the code delivery, such as the partial phone number of the SMS recipient, which can be used to prompt the user on where to look for the code. + + + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'CONFIRM_SIGN_UP': { + // Resend sign up code to the registered user + const { destination, deliveryMedium } = await resendSignUpCode({ + username, + }); + console.log(`A confirmation code has been sent to ${destination}.`); + console.log(`Please check your ${deliveryMedium} for the code.`); + break; + } + } +} + +``` + +```ts +async function handleConfirmSignUp(username: string, confirmationCode: string) { + await confirmSignUp({ + username, + confirmationCode, + }); +} + + +``` + +Once the sign up is confirmed, call `signIn` again to restart the sign-in flow. + +## Done + +The sign-in flow is complete when the next step is `DONE`, which means the user is successfully authenticated. +As a convenience, the `SignInResult` also provides the `isSignedIn` property, which will be true if the next step is `DONE`. + +```ts +async function handleSignInResult(result: SignInOutput) { + switch (result.nextStep.signInStep) { + case 'DONE': { + // `result.isSignedIn` is `true` + console.log(`Sign in is complete.`); + break; + } + } +} + + +``` + + + After a user has finished signup, they can proceed to sign in. Amplify Auth signin flows can be multi step processes. The required steps are determined by the configuration you provided when you define your auth resources like described on [Manage MFA Settings](/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/) page. From 839fd1c313487e32ca66cd4068f9ac132b00088c Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 13:32:45 -0700 Subject: [PATCH 30/44] chore: remove broken link --- .../build-a-backend/auth/multi-step-sign-in/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index f2c064148d2..f66437aa509 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -355,7 +355,7 @@ async function handleMfaSelection(mfaType: MfaType) { ## Confirm signin with custom challenge -If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). +If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a custom sign in flow. For example, your custom challenge Lambda may pass a prompt to the frontend which requires the user to enter a secret code. From 8a138f9f2820e10302bc4e3c5171716b9656de35 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 14:32:19 -0700 Subject: [PATCH 31/44] chore: update mfa method language to include email --- .../auth/concepts/multi-factor-authentication/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 3982618521b..52233eda495 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -71,7 +71,7 @@ This configuration may change depending on the combination of MFA methods enable When enabling MFA you will have two key decisions to make: - **MFA enforcement:** As part of this setup you will determine how MFA is enforced. If you require MFA by setting MFA mode to `REQUIRED`, all your users will need to complete MFA to sign in. If you keep it `OPTIONAL`, your users will have the choice whether to enable MFA or not for their account. -- **MFA methods:** You will also specify which MFA method you are using: TOTP (Time-based One-time Password), SMS (text message), email, or any combination thereof. We recommend that you use TOTP-based MFA as it is more secure and you can reserve SMS for account recovery. +- **MFA methods:** You will also specify which MFA method you are using: TOTP (Time-based One-time Password), SMS (text message), email, or any combination thereof. We recommend that you use TOTP-based MFA as it is more secure and you can reserve SMS or email for account recovery. From 7fd2d32869b772493d6e3465bce9da3bb8b3c0d2 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 14:55:22 -0700 Subject: [PATCH 32/44] Apply suggestions from code review Co-authored-by: Tyler-Larkin --- .../auth/concepts/multi-factor-authentication/index.mdx | 4 ++-- .../auth/connect-your-frontend/sign-in/index.mdx | 2 +- .../build-a-backend/auth/multi-step-sign-in/index.mdx | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 52233eda495..e7ec995ff0d 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -195,7 +195,7 @@ Future _handleMfaSelection(MfaType selection) async { ); return _handleSignInResult(result); } on AuthException catch (e) { - safePrint('Error resending code: ${e.message}'); + safePrint('Error sending MFA selection: ${e.message}'); } } ``` @@ -1007,8 +1007,8 @@ Future signUpWithEmailVerification( password: password, options: SignUpOptions( userAttributes: { - // ... if required AuthUserAttributeKey.email: 'test@example.com', + // ... if required AuthUserAttributeKey.phoneNumber: '+18885551234', }, ), diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 1447c0cadc2..5af13aebcb7 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -629,7 +629,7 @@ Following sign in, you will receive a `nextStep` in the sign-in result of one of | `confirmSignInWithSmsMfaCode` | The sign-in must be confirmed with a SMS code from the user. Complete the process with `confirmSignIn`. | | `confirmSignInWithOtpCode` | The sign-in must be confirmed with a code from the user (sent via SMS or Email). Complete the process with `confirmSignIn`. | | `continueSignInWithMfaSelection` | The user must select their mode of MFA verification before signing in. Complete the process with `confirmSignIn`. | -| `continueSignInWithMfaSetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `"EMAIL"` or `"TOTP"` to `confirmSignIn`. | +| `continueSignInWithMfaSetupSelection` | The user must select their mode of MFA verification to setup. Complete the process by passing either `MfaType.email.confirmationValue` or `MfaType.totp.confirmationValue` to `confirmSignIn`. | | `continueSignInWithTotpSetup` | The TOTP setup process must be continued. Complete the process with `confirmSignIn`. | | `continueSignInWithEmailMfaSetup` | The EMAIL setup process must be continued. Complete the process by passing a valid email address to `confirmSignIn`. | diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index f66437aa509..243cd12eb44 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -573,7 +573,7 @@ Future _handleSignInResult(SignInResult result) async { // Handle select from MFA methods available to setup case AuthSignInStep.continueSignInWithEmailMfaSetup: // Handle email setup case - case AuthSignInStep.confirmSignInWithEmailMfaCode: + case AuthSignInStep.confirmSignInWithOtpCode: // Handle email MFA case case AuthSignInStep.continueSignInWithTotpSetup: // Handle TOTP setup case @@ -669,7 +669,7 @@ Future confirmTotpUser(String totpCode) async { ## Confirm signin with Email MFA -If the next step is `confirmSignInWithEmailMfaCode`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. +If the next step is `confirmSignInWithOtpCode`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -681,7 +681,7 @@ the recipient, which can be used to prompt the user on where to look for the cod ```dart Future _handleSignInResult(SignInResult result) async { switch (result.nextStep.signInStep) { - case AuthSignInStep.confirmSignInWithEmailMfaCode: + case AuthSignInStep.confirmSignInWithOtpCode: final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!; _handleCodeDelivery(codeDeliveryDetails); // ... From c02906487ddf48e8b1c515629dfbfe02c81caacd Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 15:44:59 -0700 Subject: [PATCH 33/44] chore: add react native to filters --- .../auth/connect-your-frontend/sign-in/index.mdx | 4 ++-- .../auth/connect-your-frontend/sign-up/index.mdx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx index 5af13aebcb7..d018ea92424 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/index.mdx @@ -253,7 +253,7 @@ func signIn(username: String, password: String) -> AnyCancellable { The `signIn` API response will include a `nextStep` property, which can be used to determine if further action is required. It may return the following next steps: - + | Next Step | Description | | --------- | ----------- | | `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED` | The user was created with a temporary password and must set a new one. Complete the process with `confirmSignIn`. | @@ -582,7 +582,7 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri ### Confirm sign-in - + Following sign in, you will receive a `nextStep` in the sign-in result of one of the following types. Collect the user response and then pass to the `confirmSignIn` API to complete the sign in flow. | Next Step | Description | | --------- | ----------- | diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx index 1f32d88199e..692d8f82939 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/index.mdx @@ -285,7 +285,7 @@ func signUp(username: String, password: String, email: String, phonenumber: Stri The `signUp` API response will include a `nextStep` property, which can be used to determine if further action is required. It may return the following next steps: - + | Next Step | Description | | --------- | ----------- | | `CONFIRM_SIGN_UP` | The sign up needs to be confirmed by collecting a code from the user and calling `confirmSignUp`. | @@ -319,7 +319,7 @@ By default, each user that signs up remains in the unconfirmed status until they You can confirm the sign-up after receiving a confirmation code from the user: - + ```ts import { confirmSignUp } from 'aws-amplify/auth'; From 49db7223fca01ece5cacb975b3cb78b21c3e9567 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 15:47:55 -0700 Subject: [PATCH 34/44] Apply suggestions from code review Co-authored-by: josef --- .../auth/concepts/multi-factor-authentication/index.mdx | 2 +- .../build-a-backend/auth/modify-resources-with-cdk/index.mdx | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index e7ec995ff0d..b6c71f2a633 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -55,7 +55,7 @@ export const auth = defineAuth({ ``` -Email-based MFA is currently not supported with `defineAuth`. We are working towards supporting this feature. For more information, visit the [feature request in GitHub](https://github.com/aws-amplify/amplify-backend/issues/2159). +**Note:** Email-based MFA is currently not supported with `defineAuth`. We are working towards supporting this feature. For more information, visit the [feature request in GitHub](https://github.com/aws-amplify/amplify-backend/issues/2159). To take advantage of this feature with an Amplify generated backend, the underlying CDK construct can be extended manually. See [overriding Cognito User Pool multi-factor authentication options](/[platform]/build-a-backend/auth/modify-resources-with-cdk/#override-cognito-userpool-multi-factor-authentication-options) for more information. diff --git a/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx b/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx index a09a450ee0b..3d5c3b8b143 100644 --- a/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/modify-resources-with-cdk/index.mdx @@ -89,10 +89,9 @@ export const auth = defineAuth({ }, }) ``` -Next, extend the underlying CDK construct by activating Advanced Security Mode and adding `EMAIL_OTP` to the enabled MFA options. +Next, extend the underlying CDK construct by activating [Amazon Cognito's Advanced Security Features (ASF)](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) and add `EMAIL_OTP` to the enabled MFA options. ```ts title="amplify/backend.ts" - import { defineBackend } from "@aws-amplify/backend" import { auth } from "./auth/resource" From 205d43eaafff6bed52e8546f95e921fbb91b28fb Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 16:48:39 -0700 Subject: [PATCH 35/44] chore: update configure mfa language --- .../concepts/multi-factor-authentication/index.mdx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index b6c71f2a633..045cfd8ac6a 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -35,8 +35,8 @@ In this guide we will review how you can set up MFA with each of these methods a ## Configure multi-factor authentication Use `defineAuth` to enable MFA for your app. The example below is setting up MFA with TOTP but not SMS as you can see that the phone number is not a required attribute. -- If you plan to use SMS for MFA, then the `phoneNumber` attribute must be `true`. -- If you plan to use email for MFA, then the `email` attribute must also be `true`. +- If you plan to use SMS for MFA, then the `phoneNumber` attribute must be marked as required in your `userAttributes`. Note that if you have `loginWith.phone` as `true` this attribute will automatically be marked as required. +- If you plan to use email for MFA, then the `email` attribute must also be `true` must be marked as required in your `userAttributes`. Note that if you have `loginWith.email` as `true` this attribute will automatically be marked as required. ```ts title="amplify/auth/resource.ts" import { defineAuth } from '@aws-amplify/backend'; @@ -49,8 +49,13 @@ export const auth = defineAuth({ multifactor: { mode: 'OPTIONAL', totp: true, - } + }, // highlight-end + userAttributes: { + phoneNumber: { + required: true + } + } }); ``` From b3488ddcd8806cf453764e8e97181cbaad6ee2e6 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 16:52:06 -0700 Subject: [PATCH 36/44] chore: add Authenticator UI component not supported --- .../auth/concepts/multi-factor-authentication/index.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 045cfd8ac6a..fc3726e20c5 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -858,8 +858,7 @@ In a scenario where MFA is marked as "Required" in the Cognito User Pool and ano ## Multi-factor authentication with EMAIL - -If you are using the [Authenticator component](https://ui.docs.amplify.aws/react/connected-components/authenticator) with Amplify, this feature works without any additional code. The guide below is for writing your own implementation. +**Note:** Email-based MFA is currently not supported in the [Authenticator component](https://ui.docs.amplify.aws/react/connected-components/authenticator). We are working towards supporting this feature. For more information, visit the [feature request in GitHub](https://github.com/aws-amplify/amplify-ui/issues/5983). From 50bd6a7ce9f9dc5dc24b1dc6ef4d48c7a39ac8ce Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 16:57:43 -0700 Subject: [PATCH 37/44] Apply suggestions from code review Co-authored-by: josef --- .../auth/concepts/multi-factor-authentication/index.mdx | 2 +- .../build-a-backend/auth/multi-step-sign-in/index.mdx | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index fc3726e20c5..9ee3bd521ac 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -887,7 +887,7 @@ If you are using the [Authenticator component](https://ui.docs.amplify.aws/andro -Once you have setup email as your second layer of authentication with MFA as shown above, your users will get an authentication code via an email to complete sign-in after they sign in with their username and password. +Once you have setup email as your second layer of authentication with MFA as shown above, your users will get an authentication code via email to complete sign-in after they sign in with their username and password. diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx index 243cd12eb44..5156881ff7f 100644 --- a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx @@ -2207,7 +2207,11 @@ func confirmSignIn(totpCode: String) -> AnyCancellable { ## Confirm signin with Email MFA If the next step is `confirmSignInWithOTP`, Amplify Auth has sent a random code to the user's email address, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. -Note: the signin result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. + + +**Note:** the sign-in result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. + + From aee8c2f7b04dcb5b29faf418d512ca44e35cae7b Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 17:05:54 -0700 Subject: [PATCH 38/44] chore: quick blurb about mfa preference APIs --- .../auth/concepts/multi-factor-authentication/index.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx index 9ee3bd521ac..731e5b31427 100644 --- a/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/concepts/multi-factor-authentication/index.mdx @@ -1374,6 +1374,8 @@ func updateMFAPreferences() async throws { ## Set up a user's preferred MFA method +Depending on your user pool configuration, it's possible that multiple MFA options may be available to a given user. In order to avoid requiring your users to select an MFA method each time they sign-in to your application, Amplify provides two utility APIs to manage an individual user's MFA preferences. + ### Fetch the current user's MFA preferences Invoke the following API to get the current MFA preference and enabled MFA types, if any, for the current user. From 35ac251179e6e9a7e35f4f1881981b85d92b63bc Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 17:14:46 -0700 Subject: [PATCH 39/44] chore: move multi-step-sign-in to connect your front end --- src/directory/directory.mjs | 6 +++--- .../multi-step-sign-in/index.mdx | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename src/pages/[platform]/build-a-backend/auth/{ => connect-your-frontend}/multi-step-sign-in/index.mdx (100%) diff --git a/src/directory/directory.mjs b/src/directory/directory.mjs index d251f16f1be..5112f863ba0 100644 --- a/src/directory/directory.mjs +++ b/src/directory/directory.mjs @@ -122,6 +122,9 @@ export const directory = { }, { path: 'src/pages/[platform]/build-a-backend/auth/connect-your-frontend/delete-user-account/index.mdx' + }, + { + path: 'src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx' } ] }, @@ -156,9 +159,6 @@ export const directory = { } ] }, - { - path: 'src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx' - }, { path: 'src/pages/[platform]/build-a-backend/auth/sign-in-with-web-ui/index.mdx' }, diff --git a/src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx similarity index 100% rename from src/pages/[platform]/build-a-backend/auth/multi-step-sign-in/index.mdx rename to src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx From 14ec2ed85834f7cd752cb9d2e7cdf6cb00c10c6a Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 17:21:43 -0700 Subject: [PATCH 40/44] chore: adding imports for multi step sign in examples --- .../multi-step-sign-in/index.mdx | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx index 5156881ff7f..5cc84eb5a6b 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx @@ -127,6 +127,8 @@ The result includes `codeDeliveryDetails` with additional information about the ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONFIRM_SIGN_IN_WITH_SMS_CODE': { @@ -144,9 +146,6 @@ async function handleSignInResult(result: SignInOutput) { } } -``` - -```ts async function confirmMfaCode(mfaCode: string) { const result = await confirmSignIn({ challengeResponse: mfaCode }); @@ -163,6 +162,8 @@ After the user enters the code, your implementation must pass the value to Ampli ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONFIRM_SIGN_IN_WITH_TOTP_CODE': { @@ -194,6 +195,8 @@ The result includes `codeDeliveryDetails` with additional information about the ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE': { @@ -240,6 +243,8 @@ Once Amplify receives the users selection, you can expect to handle a follow up ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION': { @@ -268,6 +273,8 @@ async function handleMfaSelection(mfaType: MfaType) { If the next step is `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONTINUE_SIGN_IN_WITH_EMAIL_SETUP': { @@ -294,6 +301,8 @@ Once the authenticator app is set up, the user can generate a TOTP code and prov ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONTINUE_SIGN_IN_WITH_TOTP_SETUP': { @@ -330,6 +339,8 @@ Once Amplify receives the users selection, you can expect to handle a follow up - If `TOTP` is selected, `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` will be the next step. ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION': { @@ -360,6 +371,8 @@ If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awa For example, your custom challenge Lambda may pass a prompt to the frontend which requires the user to enter a secret code. ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE': { @@ -399,6 +412,8 @@ If the next step is `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED`, Amplify Auth r Prompt the user for a new password and pass it to the `confirmSignIn` API. ```ts +import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED': { @@ -428,6 +443,12 @@ Use the `resetPassword` API to guide the user through resetting their password, See the [reset password](/[platform]/build-a-backend/auth/manage-users/manage-passwords/) docs for more information. ```ts +import { + type ResetPasswordOutput, + type SignInOutput, + resetPassword, +} from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'RESET_PASSWORD': { @@ -476,6 +497,12 @@ The result includes `codeDeliveryDetails` with additional information about the ```ts +import { + type SignInOutput, + confirmSignUp, + resendSignUpCode, +} from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'CONFIRM_SIGN_UP': { @@ -490,9 +517,6 @@ async function handleSignInResult(result: SignInOutput) { } } -``` - -```ts async function handleConfirmSignUp(username: string, confirmationCode: string) { await confirmSignUp({ username, @@ -500,7 +524,6 @@ async function handleConfirmSignUp(username: string, confirmationCode: string) { }); } - ``` Once the sign up is confirmed, call `signIn` again to restart the sign-in flow. @@ -511,6 +534,8 @@ The sign-in flow is complete when the next step is `DONE`, which means the user As a convenience, the `SignInResult` also provides the `isSignedIn` property, which will be true if the next step is `DONE`. ```ts +import { type SignInOutput } from '@aws-amplify/auth'; + async function handleSignInResult(result: SignInOutput) { switch (result.nextStep.signInStep) { case 'DONE': { @@ -521,7 +546,6 @@ async function handleSignInResult(result: SignInOutput) { } } - ``` From ee45f7c6aa0523c892ae574977c079ce62326106 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 17:22:25 -0700 Subject: [PATCH 41/44] chore: consolidate ts snippets --- .../auth/connect-your-frontend/multi-step-sign-in/index.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx index 5cc84eb5a6b..c34e17bf69c 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx @@ -214,9 +214,6 @@ async function handleSignInResult(result: SignInOutput) { } } -``` - -```ts async function confirmMfaCode(mfaCode: string) { const result = await confirmSignIn({ challengeResponse: mfaCode }); @@ -424,9 +421,6 @@ async function handleSignInResult(result: SignInOutput) { } } -``` - -```ts async function confirmNewPassword(newPassword: string) { const result = await confirmSignIn({ challengeResponse: newPassword }); From c61ad3e8f89e355217ad32b4349a1c9f02122695 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 17:29:12 -0700 Subject: [PATCH 42/44] chore: update signin to sign-in and add additional references --- .../multi-step-sign-in/index.mdx | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx index c34e17bf69c..504e96db5e5 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx @@ -116,7 +116,7 @@ if (nextStep.signInStep === 'DONE') { } ``` -## Confirm signin with SMS MFA +## Confirm sign-in with SMS MFA If the next step is `CONFIRM_SIGN_IN_WITH_SMS_CODE`, Amplify Auth has sent the user a random code over SMS and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -154,7 +154,7 @@ async function confirmMfaCode(mfaCode: string) { ``` -## Confirm signin with TOTP MFA +## Confirm sign-in with TOTP MFA If the next step is `CONFIRM_SIGN_IN_WITH_TOTP_CODE`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. @@ -184,7 +184,7 @@ async function confirmTotpCode(totpCode: string) { ``` -## Confirm signin with Email MFA +## Confirm sign-in with Email MFA If the next step is `CONFIRM_SIGN_IN_WITH_EMAIL_CODE`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -223,7 +223,7 @@ async function confirmMfaCode(mfaCode: string) { ``` -## Continue signin with MFA Selection +## Continue sign-in with MFA Selection If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SELECTION`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and EMAIL as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. @@ -265,7 +265,7 @@ async function handleMfaSelection(mfaType: MfaType) { ``` -## Continue signin with Email Setup +## Continue sign-in with Email Setup If the next step is `CONTINUE_SIGN_IN_WITH_EMAIL_SETUP`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. @@ -290,7 +290,7 @@ async function confirmEmail(email: string) { ``` -## Continue signin with TOTP Setup +## Continue sign-in with TOTP Setup The `CONTINUE_SIGN_IN_WITH_TOTP_SETUP` step signifies that the user must set up TOTP before they can sign in. The step returns an associated value of type TOTPSetupDetails which must be used to configure an authenticator app like Microsoft Authenticator or Google Authenticator. TOTPSetupDetails provides a helper method called getSetupURI which generates a URI that can be used, for example, in a button to open the user's installed authenticator app. For more advanced use cases, TOTPSetupDetails also contains a sharedSecret which can be used to either generate a QR code or be manually entered into an authenticator app. @@ -322,7 +322,7 @@ async function confirmTotpCode(totpCode: string) { ``` -## Continue signin with MFA Setup Selection +## Continue sign-in with MFA Setup Selection If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION`, then the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. @@ -361,7 +361,7 @@ async function handleMfaSelection(mfaType: MfaType) { ``` -## Confirm signin with custom challenge +## Confirm sign-in with custom challenge If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a custom sign in flow. @@ -402,12 +402,14 @@ If `failAuthentication=true` is returned by the Lambda, Cognito will invalidate -## Confirm signin with new password +## Confirm sign-in with new password If the next step is `CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED`, Amplify Auth requires the user choose a new password they proceeding with the sign in. Prompt the user for a new password and pass it to the `confirmSignIn` API. +See the [sign-in](/[platform]/build-a-backend/auth/connect-your-frontend/sign-in/) and [manage-password](/[platform]/build-a-backend/auth/manage-users/manage-passwords/) docs for more information. + ```ts import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; @@ -482,7 +484,7 @@ async function handleResetPasswordResult( If the next step is `CONFIRM_SIGN_UP`, Amplify Auth requires that the user confirm their email or phone number before proceeding. Use the `resendSignUpCode` API to send a new sign up code to the registered email or phone number, followed by `confirmSignUp` to complete the sign up. -See the [confirm sign up](/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/#confirm-sign-up) docs for more information. +See the [sign up](/[platform]/build-a-backend/auth/connect-your-frontend/sign-up/) docs for more information. @@ -612,7 +614,7 @@ Future _handleSignInResult(SignInResult result) async { } } ``` -## Confirm signin with SMS MFA +## Confirm sign-in with SMS MFA If the next step is `confirmSignInWithSmsMfaCode`, Amplify Auth has sent the user a random code over SMS and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -654,7 +656,7 @@ Future confirmMfaUser(String mfaCode) async { } ``` -## Confirm signin with TOTP MFA +## Confirm sign-in with TOTP MFA If the next step is `confirmSignInWithTOTPCode`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. @@ -685,7 +687,7 @@ Future confirmTotpUser(String totpCode) async { } ``` -## Confirm signin with Email MFA +## Confirm sign-in with Email MFA If the next step is `confirmSignInWithOtpCode`, Amplify Auth has sent the user a random code to their email address and is waiting for the user to verify that code. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, pass the value to the `confirmSignIn` API. @@ -728,7 +730,7 @@ Future confirmMfaUser(String mfaCode) async { ``` -## Continue signin with MFA Selection +## Continue sign-in with MFA Selection If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. @@ -766,7 +768,7 @@ Future _handleMfaSelection(MfaType selection) async { } ``` -## Continue signin with Email Setup +## Continue sign-in with Email Setup If the next step is `continueSignInWithEmailMfaSetup`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. @@ -794,7 +796,7 @@ Future confirmEmailUser(String emailAddress) async { } ``` -## Continue signin with TOTP Setup +## Continue sign-in with TOTP Setup If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. @@ -827,7 +829,7 @@ Future confirmTotpUser(String totpCode) async { } ``` -## Continue signin with MFA Setup Selection +## Continue sign-in with MFA Setup Selection If the next step is `continueSignInWithMfaSetupSelection`, then the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. The MFA types which are currently supported by Amplify Auth are: @@ -864,7 +866,7 @@ Future _handleMfaSelection(MfaType selection) async { } ``` -## Confirm signin with custom challenge +## Confirm sign-in with custom challenge If the next step is `confirmSignInWithCustomChallenge`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the AWS Lambda trigger you configured as part of a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). @@ -906,7 +908,7 @@ If `failAuthentication=true` is returned by the Lambda, Cognito will invalidate -## Confirm signin with new password +## Confirm sign-in with new password If the next step is `confirmSignInWithNewPassword`, Amplify Auth requires the user choose a new password they proceeding with the sign in. Prompt the user for a new password and pass it to the `confirmSignIn` API. @@ -1459,7 +1461,7 @@ RxAmplify.Auth.signIn("username", "password", options).subscribe( -## Confirm signin with SMS MFA +## Confirm sign-in with SMS MFA If the next step is `CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE`, Amplify Auth has sent the user a random code over SMS, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. @@ -1559,38 +1561,38 @@ RxAmplify.Auth.confirmSignIn( -## Confirm signin with TOTP MFA +## Confirm sign-in with TOTP MFA If the next step is `CONFIRM_SIGN_IN_WITH_TOTP_CODE`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. -## Confirm signin with Email MFA +## Confirm sign-in with Email MFA If the next step is `CONFIRM_SIGN_IN_WITH_EMAIL_MFA_CODE`, Amplify Auth has sent the user a random code to their email address and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. Note: the signIn result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient. -## Continue signin with MFA Selection +## Continue sign-in with MFA Selection If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SELECTION`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. -## Continue signin with Email Setup +## Continue sign-in with Email Setup If the next step is `CONTINUE_SIGN_IN_WITH_EMAIL_MFA_SETUP`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. -## Continue signin with TOTP Setup +## Continue sign-in with TOTP Setup If the next step is `CONTINUE_SIGN_IN_WITH_TOTP_SETUP`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. Once the authenticator app is set up, the user can generate a TOTP code and provide it to the library to complete the sign in process. -## Continue signin with MFA Setup Selection +## Continue sign-in with MFA Setup Selection If the next step is `CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION`, the user must select the MFA method to setup. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. -## Confirm signin with custom challenge +## Confirm sign-in with custom challenge If the next step is `CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the Lambda trigger you setup when you configured a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. @@ -1704,7 +1706,7 @@ NotAuthorizedException{message=Failed since user is not authorized., cause=NotAu -## Confirm signin with new password +## Confirm sign-in with new password If you receive a `UserNotConfirmedException` while signing in, Amplify Auth requires a new password for the user before they can proceed. Prompt the user for a new password and pass it to the `confirmSignIn` API. @@ -2100,7 +2102,7 @@ func signIn(username: String, password: String) async { The `nextStep` property is of enum type `AuthSignInStep`. Depending on its value, your code should take one of the following actions: -## Confirm signin with SMS MFA +## Confirm sign-in with SMS MFA If the next step is `confirmSignInWithSMSMFACode`, Amplify Auth has sent the user a random code over SMS, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. Note: the signin result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial phone number of the SMS recipient. @@ -2161,7 +2163,7 @@ func confirmSignIn(confirmationCodeFromUser: String) -> AnyCancellable { -## Confirm signin with TOTP MFA +## Confirm sign-in with TOTP MFA If the next step is `confirmSignInWithTOTPCode`, you should prompt the user to enter the TOTP code from their associated authenticator app during set up. The code is a six-digit number that changes every 30 seconds. The user must enter the code before the 30-second window expires. @@ -2222,7 +2224,7 @@ func confirmSignIn(totpCode: String) -> AnyCancellable { -## Confirm signin with Email MFA +## Confirm sign-in with Email MFA If the next step is `confirmSignInWithOTP`, Amplify Auth has sent a random code to the user's email address, and is waiting to find out if the user successfully received it. To handle this step, your app's UI must prompt the user to enter the code. After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API. @@ -2288,7 +2290,7 @@ func confirmSignIn(confirmationCodeFromUser: String) -> AnyCancellable { -## Continue signin with MFA Selection +## Continue sign-in with MFA Selection If the next step is `continueSignInWithMFASelection`, the user must select the MFA method to use. Amplify Auth currently supports SMS, TOTP, and email as MFA methods. After the user selects an MFA method, your implementation must pass the selected MFA method to Amplify Auth using `confirmSignIn` API. @@ -2338,7 +2340,7 @@ func confirmSignInWithTOTPAsMFASelection() -> AnyCancellable { -## Continue signin with Email Setup +## Continue sign-in with Email Setup If the next step is `continueSignInWithEmailMFASetup`, then the user must provide an email address to complete the sign in process. Once this value has been collected from the user, call the `confirmSignIn` API to continue. ```swift @@ -2350,7 +2352,7 @@ case .continueSignInWithEmailMFASetup: // Then invoke `confirmSignIn` api with the email address ``` -## Continue signin with TOTP Setup +## Continue sign-in with TOTP Setup If the next step is `continueSignInWithTOTPSetup`, then the user must provide a TOTP code to complete the sign in process. The step returns an associated value of type `TOTPSetupDetails` which would be used for generating TOTP. `TOTPSetupDetails` provides a helper method called `getSetupURI` that can be used to generate a URI, which can be used by native password managers for TOTP association. For example. if the URI is used on Apple platforms, it will trigger the platform's native password manager to associate TOTP with the account. For more advanced use cases, `TOTPSetupDetails` also contains the `sharedSecret` that will be used to either generate a QR code or can be manually entered into an authenticator app. @@ -2423,7 +2425,7 @@ func confirmSignInWithTOTPSetup(totpCodeFromAuthenticatorApp: String) -> AnyCanc -## Continue signin with MFA Setup Selection +## Continue sign-in with MFA Setup Selection If the next step is `continueSignInWithMFASetupSelection`, the user must indicate which of the available MFA methods they would like to setup. After the user selects an MFA method to setup, your implementation must pass the selected MFA method to the `confirmSignIn` API. @@ -2473,7 +2475,7 @@ func continueSignInWithEmailMFASetupSelection() -> AnyCancellable { -## Confirm signin with custom challenge +## Confirm sign-in with custom challenge If the next step is `confirmSignInWithCustomChallenge`, Amplify Auth is awaiting completion of a custom authentication challenge. The challenge is based on the Lambda trigger you setup when you configured a [custom sign in flow](/[platform]/build-a-backend/auth/customize-auth-lifecycle/custom-auth-flows/#sign-in-a-user). To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API. @@ -2544,7 +2546,7 @@ Exception: notAuthorized{message=Failed since user is not authorized., cause=No -## Confirm signin with new password +## Confirm sign-in with new password If the next step is `confirmSignInWithNewPassword`, Amplify Auth requires a new password for the user before they can proceed. Prompt the user for a new password and pass it to the `confirmSignIn` API. From 97ec29135e7abb6608caa66ed5c7b4d49092c1be Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 30 Oct 2024 17:33:33 -0700 Subject: [PATCH 43/44] chore: update JS callouts for confirm sign-in to be same as other platforms --- .../auth/connect-your-frontend/multi-step-sign-in/index.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx index 504e96db5e5..eee41bf9520 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/multi-step-sign-in/index.mdx @@ -122,7 +122,7 @@ If the next step is `CONFIRM_SIGN_IN_WITH_SMS_CODE`, Amplify Auth has sent the u -The result includes `codeDeliveryDetails` with additional information about the code delivery, such as the partial phone number of the SMS recipient, which can be used to prompt the user on where to look for the code. +The result includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery, such as the partial phone number of the SMS recipient, which can be used to prompt the user on where to look for the code. @@ -190,7 +190,7 @@ If the next step is `CONFIRM_SIGN_IN_WITH_EMAIL_CODE`, Amplify Auth has sent the -The result includes `codeDeliveryDetails` with additional information about the code delivery, such as the partial email address of the recipient, which can be used to prompt the user on where to look for the code. +The result includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery, such as the partial email address of the recipient, which can be used to prompt the user on where to look for the code. @@ -488,7 +488,7 @@ See the [sign up](/[platform]/build-a-backend/auth/connect-your-frontend/sign-up -The result includes `codeDeliveryDetails` with additional information about the code delivery, such as the partial phone number of the SMS recipient, which can be used to prompt the user on where to look for the code. +The result includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery, such as the partial phone number of the SMS recipient, which can be used to prompt the user on where to look for the code. From dec47804b9352127ac58ec0e1fdbc142cb736045 Mon Sep 17 00:00:00 2001 From: Tyler Roach Date: Thu, 31 Oct 2024 14:40:10 -0400 Subject: [PATCH 44/44] Update versions.ts --- src/constants/versions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/constants/versions.ts b/src/constants/versions.ts index 9d46720b5a8..dacf5ba9a81 100644 --- a/src/constants/versions.ts +++ b/src/constants/versions.ts @@ -1,10 +1,10 @@ export const versions = { - ANDROID_VERSION: '2.19.1', + ANDROID_VERSION: '2.24.0', ANDROID_DEVPREVIEW: '1.36.5-dev-preview.0', ANDROID_V1_VERSION: '1.38.8', ANDROID_V1_GEO_VERSION: '1.0.1', ANDROID_V1_KOTLIN_VERSION: '0.22.8', ANDROID_SDK_VERSION: '2.76.0', - KOTLIN_SDK_VERSION: '1.2.8', - ANDROID_AUTHENTICATOR_VERSION: '1.2.0' + KOTLIN_SDK_VERSION: '1.3.31', + ANDROID_AUTHENTICATOR_VERSION: '1.4.0' };