From a456563b12acebb06d741762cf07bb30f283497f Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 27 Nov 2024 10:32:27 -0800 Subject: [PATCH 1/7] add additional detail to switching auth flows page --- .../switching-authentication-flows/index.mdx | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx index 5c82f2da750..141e78461e3 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx @@ -171,18 +171,9 @@ await signIn({ ## USER_AUTH flow -The `USER_AUTH` sign in flow will support the following methods of first factor authentication: `WEB_AUTHN`, `EMAIL_OTP`, `SMS_OTP`, `PASSWORD`, and `PASSWORD_SRP`. +The `USER_AUTH` sign in flow supports the following methods as first factors for authentication: `WEB_AUTHN`, `EMAIL_OTP`, `SMS_OTP`, `PASSWORD`, and `PASSWORD_SRP`. -```ts -type AuthFactorType = - | "WEB_AUTHN" - | "EMAIL_OTP" - | "SMS_OTP" - | "PASSWORD" - | "PASSWORD_SRP"; -``` - -If the desired first factor is known before the sign in flow is initiated it can be passed to the initial sign in call. +If the desired first factor is known when authentication is initiated it can be passed to the `signIn` API as the `preferredChallenge` to initiate the corresponding authentication flow. ```ts // PASSWORD_SRP / PASSWORD @@ -199,9 +190,9 @@ const { nextStep } = await signIn({ // WEB_AUTHN / EMAIL_OTP / SMS_OTP // sign in with preferred passwordless challenge -// no user input required at this step +// no additional user input required at this step const { nextStep } = await signIn({ - username: "passwordless@mycompany.com", + username: "hello@example.com", options: { authFlowType: "USER_AUTH", preferredChallenge: "WEB_AUTHN" // or "EMAIL_OTP" or "SMS_OTP" @@ -209,9 +200,35 @@ const { nextStep } = await signIn({ }); ``` -If the desired first factor is not known, the flow will continue to select an available first factor. +If the desired first factor is not known or you would like to provide users with available options, it can be omitted from the initial `signIn` API call to discover which authentication first factors are available for a user via the `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION` step. + +```ts +const { nextStep: signInNextStep } = await signIn({ + username: '+15551234567', + options: { + authFlowType: 'USER_AUTH', + }, +}); + +if ( + signInNextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION' +) { + // present user with list of available challenges + console.log(`Available Challenges: ${signInNextStep.availableChallenges}`); + + // respond with user selection using `confirmSignIn` API + const { nextStep: nextConfirmSignInStep } = await confirmSignIn({ + challengeResponse: 'SMS_OTP', // or 'EMAIL_OTP', 'WEB_AUTHN', 'PASSWORD', 'PASSWORD_SRP' + }); +} + +``` +Also, note that if the `preferredChallenge` passed to the initial `signIn` API call is unavailable for the user, Amplify will also respond with the `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION` next step. + -> For more information about determining a first factor, and signing in with passwordless authorization factors, please visit the [concepts page for passwordless](/[platform]/build-a-backend/auth/concepts/passwordless/) + +For more information about determining a first factor, and signing in with passwordless authentication factors, please visit the [Passwordless](/[platform]/build-a-backend/auth/concepts/passwordless/) concepts page. + ## USER_PASSWORD_AUTH flow From 8e52a2ed999d4a9421f567472425923688558c82 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 27 Nov 2024 11:23:08 -0800 Subject: [PATCH 2/7] expand autosignin examples --- .../connect-your-frontend/sign-up/index.mdx | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) 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 436ce634a0e..19c135a7ad7 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 @@ -543,7 +543,7 @@ Your application's users can also sign up using passwordless methods. To learn m ```typescript // Sign up using a phone number const { nextStep: signUpNextStep } = await signUp({ - username: 'james', + username: 'hello', options: { userAttributes: { phone_number: '+15555551234', @@ -566,7 +566,7 @@ if (signUpNextStep.signUpStep === 'CONFIRM_SIGN_UP') { // Confirm sign up with the OTP received const { nextStep: confirmSignUpNextStep } = await confirmSignUp({ - username: 'james', + username: 'hello', confirmationCode: '123456', }); @@ -691,10 +691,10 @@ func confirmSignUp(for username: String, with confirmationCode: String) -> AnyCa ```typescript // Sign up using an email address const { nextStep: signUpNextStep } = await signUp({ - username: 'james', + username: 'hello', options: { userAttributes: { - email: 'james@example.com', + email: 'hello@example.com', }, }, }); @@ -714,7 +714,7 @@ if (signUpNextStep.signUpStep === 'CONFIRM_SIGN_UP') { // Confirm sign up with the OTP received const { nextStep: confirmSignUpNextStep } = await confirmSignUp({ - username: 'james', + username: 'hello', confirmationCode: '123456', }); @@ -837,19 +837,44 @@ func confirmSignUp(for username: String, with confirmationCode: String) -> AnyCa ```typescript -// Confirm sign up with the OTP received and auto sign in +// Call `signUp` API with `USER_AUTH` as the authentication flow type for `autoSignIn` +const { nextStep: signUpNextStep } = await signUp({ + username: 'hello', + options: { + userAttributes: { + email: 'hello@example.com', + phone_number: '+15555551234', + }, + autoSignIn: { + authFlowType: 'USER_AUTH', + }, + }, +}); + +if (signUpNextStep.signUpStep === 'CONFIRM_SIGN_UP') { + console.log( + `Code Delivery Medium: ${signUpNextStep.codeDeliveryDetails.deliveryMedium}`, + ); + console.log( + `Code Delivery Destination: ${signUpNextStep.codeDeliveryDetails.destination}`, + ); +} + +// Call `confirmSignUp` API with the OTP received const { nextStep: confirmSignUpNextStep } = await confirmSignUp({ - username: 'james', + username: 'hello', confirmationCode: '123456', }); if (confirmSignUpNextStep.signUpStep === 'COMPLETE_AUTO_SIGN_IN') { + // Call `autoSignIn` API to complete the flow const { nextStep } = await autoSignIn(); if (nextStep.signInStep === 'DONE') { console.log('Successfully signed in.'); } } + ``` From b325d1c68f901411cce995e8ba548d4f11133040 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 27 Nov 2024 11:53:56 -0800 Subject: [PATCH 3/7] clarify language --- .../switching-authentication-flows/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx index 141e78461e3..ab9fbb60c29 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx @@ -200,7 +200,7 @@ const { nextStep } = await signIn({ }); ``` -If the desired first factor is not known or you would like to provide users with available options, it can be omitted from the initial `signIn` API call to discover which authentication first factors are available for a user via the `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION` step. +If the desired first factor is not known or you would like to provide users with available options, `preferredChallenge` can be omitted from the initial `signIn` API call to discover which authentication first factors are available for a user via the `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION` step. ```ts const { nextStep: signInNextStep } = await signIn({ From cadb0cb0a1a06bdf2a9a0dbc792e013355a5fdac Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 27 Nov 2024 12:11:19 -0800 Subject: [PATCH 4/7] fix wording --- .../switching-authentication-flows/index.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx index ab9fbb60c29..0b68e9f6d2b 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx @@ -200,7 +200,9 @@ const { nextStep } = await signIn({ }); ``` -If the desired first factor is not known or you would like to provide users with available options, `preferredChallenge` can be omitted from the initial `signIn` API call to discover which authentication first factors are available for a user via the `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION` step. +If the desired first factor is not known or you would like to provide users with the available options, `preferredChallenge` can be omitted from the initial `signIn` API call. + +This allows you to discover which authentication first factors are available for a user via the `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION` step. You can then present the available options to the user and use the `confirmSignIn` API to respond with the user's selection. ```ts const { nextStep: signInNextStep } = await signIn({ From 014b30583795518103fc85ec7fc4312fbede37ae Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 27 Nov 2024 14:32:15 -0800 Subject: [PATCH 5/7] add passwordless steps to multistep sign in page --- .../multi-step-sign-in/index.mdx | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) 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 4604f7441da..4870a407b79 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 @@ -80,6 +80,21 @@ if (nextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_TOTP_SETUP') { }); } +if (nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_PASSWORD') { + // collect password from user + await confirmSignIn({ + challengeResponse: 'hunter2', + }); +} + +if (nextStep.signInStep === 'CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION') { + // present nextStep.availableChallenges to user + // collect user selection + await confirmSignIn({ + challengeResponse: 'SMS_OTP', // or 'EMAIL_OTP', 'WEB_AUTHN', 'PASSWORD', 'PASSWORD_SRP' + }); +} + if (nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE') { // collect custom challenge answer from user await confirmSignIn({ @@ -361,6 +376,78 @@ async function handleMfaSelection(mfaType: MfaType) { ``` +## Confirm sign-in with Password + +If the next step is `CONFIRM_SIGN_IN_WITH_PASSWORD`, the user must provide their password as the first factor authentication method. To handle this step, your implementation should prompt the user to enter their password. After the user enters the password, pass the value 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_PASSWORD': { + // Prompt user to enter their password + console.log(`Please enter your password.`); + break; + } + } +} + +async function confirmWithPassword(password: string) { + const result = await confirmSignIn({ challengeResponse: password }); + + return handleSignInResult(result); +} +``` + +## Continue sign-in with First Factor Selection + +If the next step is `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION`,the user must select a first factor method for authentication. After the user selects an option, your implementation should pass the selected method to the `confirmSignIn` API. + +The first factor types which are currently supported by Amplify Auth are: +- `SMS_OTP` +- `EMAIL_OTP` +- `WEB_AUTHN` +- `PASSWORD` +- `PASSWORD_SRP` + +Depending on your configuration and what factors the user has previously setup, not all options may be available. Only the available options will be presented in `availableChallenges` for selection. + +Once Amplify receives the users selection, you can expect to handle a follow up `nextStep` corresponding with the selected factor type: + +- If `SMS_OTP` is selected, you can expect to receive `CONFIRM_SIGN_IN_WITH_SMS_CODE` as the next step. +- If `EMAIL_OTP` is selected, you can expect to receive `CONFIRM_SIGN_IN_WITH_EMAIL_CODE` as the next step. +- If `WEB_AUTHN` is selected, Amplify will initiate the authentication ceremony on the user's device. If successful, the next step will be `DONE`. +- If `PASSWORD` or `PASSWORD_SRP` is selected, `CONFIRM_SIGN_IN_WITH_PASSWORD` 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_FIRST_FACTOR_SELECTION': { + const { availableChallenges } = result.nextStep; + // Present available first factor options to user + // Prompt for selection + console.log( + `There are multiple first factor options available for sign in.`, + ); + console.log( + `Select a first factor type from the availableChallenges list.`, + ); + break; + } + } +} + +async function handleFirstFactorSelection(firstFactorType: string) { + const result = await confirmSignIn({ challengeResponse: firstFactorType }); + + return handleSignInResult(result); +} + +``` + ## 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. From b313965275d62908980f3b362fd2502247283bb4 Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Wed, 27 Nov 2024 14:57:22 -0800 Subject: [PATCH 6/7] tweak language --- .../multi-step-sign-in/index.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 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 4870a407b79..0bac7d6a920 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 @@ -402,7 +402,7 @@ async function confirmWithPassword(password: string) { ## Continue sign-in with First Factor Selection -If the next step is `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION`,the user must select a first factor method for authentication. After the user selects an option, your implementation should pass the selected method to the `confirmSignIn` API. +If the next step is `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION`, the user must select a first factor method for authentication. After the user selects an option, your implementation should pass the selected method to the `confirmSignIn` API. The first factor types which are currently supported by Amplify Auth are: - `SMS_OTP` @@ -413,12 +413,12 @@ The first factor types which are currently supported by Amplify Auth are: Depending on your configuration and what factors the user has previously setup, not all options may be available. Only the available options will be presented in `availableChallenges` for selection. -Once Amplify receives the users selection, you can expect to handle a follow up `nextStep` corresponding with the selected factor type: - -- If `SMS_OTP` is selected, you can expect to receive `CONFIRM_SIGN_IN_WITH_SMS_CODE` as the next step. -- If `EMAIL_OTP` is selected, you can expect to receive `CONFIRM_SIGN_IN_WITH_EMAIL_CODE` as the next step. -- If `WEB_AUTHN` is selected, Amplify will initiate the authentication ceremony on the user's device. If successful, the next step will be `DONE`. +Once Amplify receives the user's selection via the `confirmSignIn` API, you can expect to handle a follow up `nextStep` corresponding with the first factor type selected: +- If `SMS_OTP` is selected, `CONFIRM_SIGN_IN_WITH_SMS_CODE` will be the next step. +- If `EMAIL_OTP` is selected, `CONFIRM_SIGN_IN_WITH_EMAIL_CODE` will be the next step. - If `PASSWORD` or `PASSWORD_SRP` is selected, `CONFIRM_SIGN_IN_WITH_PASSWORD` will be the next step. +- If `WEB_AUTHN` is selected, Amplify Auth will initiate the authentication ceremony on the user's device. If successful, the next step will be `DONE`. + ```ts import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth'; From 300cec2701acfe76ce0040fc87b754072c363dcf Mon Sep 17 00:00:00 2001 From: James Jarvis Date: Mon, 2 Dec 2024 10:10:25 -0800 Subject: [PATCH 7/7] Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx Co-authored-by: Parker Scanlon <69879391+scanlonp@users.noreply.github.com> --- .../switching-authentication-flows/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx index 0b68e9f6d2b..309db5c742b 100644 --- a/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx +++ b/src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx @@ -173,7 +173,7 @@ await signIn({ The `USER_AUTH` sign in flow supports the following methods as first factors for authentication: `WEB_AUTHN`, `EMAIL_OTP`, `SMS_OTP`, `PASSWORD`, and `PASSWORD_SRP`. -If the desired first factor is known when authentication is initiated it can be passed to the `signIn` API as the `preferredChallenge` to initiate the corresponding authentication flow. +If the desired first factor is known when authentication is initiated, it can be passed to the `signIn` API as the `preferredChallenge` to initiate the corresponding authentication flow. ```ts // PASSWORD_SRP / PASSWORD