Skip to content

Commit

Permalink
docs(js): expand passwordless examples for multistep sign in, autosig…
Browse files Browse the repository at this point in the history
…n in, and switching flows (#8138)

* add additional detail to switching auth flows page

* expand autosignin examples

* clarify language

* fix wording

* add passwordless steps to multistep sign in page

* tweak language

* Update src/pages/[platform]/build-a-backend/auth/connect-your-frontend/switching-authentication-flows/index.mdx

Co-authored-by: Parker Scanlon <[email protected]>

---------

Co-authored-by: Parker Scanlon <[email protected]>
  • Loading branch information
jjarvisp and scanlonp authored Dec 9, 2024
1 parent af8d6f3 commit dce8c9a
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -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 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';

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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
});

Expand Down Expand Up @@ -852,10 +852,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',
},
},
});
Expand All @@ -875,7 +875,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',
});

Expand Down Expand Up @@ -1158,19 +1158,44 @@ func confirmSignUp(for username: String, with confirmationCode: String) -> AnyCa
<InlineFilter filters={["angular", "javascript", "nextjs", "react", "react-native", "vue"]}>

```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: '[email protected]',
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.');
}
}

```
</InlineFilter>
<InlineFilter filters={["android"]}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,18 +148,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
Expand All @@ -176,19 +167,47 @@ 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"
},
});
```

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 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({
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/)
<Callout>
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.
</Callout>

## USER_PASSWORD_AUTH flow

Expand Down

0 comments on commit dce8c9a

Please sign in to comment.