---
title: "Multi-step sign-in"
section: "frontend/auth"
platforms: ["android", "angular", "flutter", "javascript", "nextjs", "react", "react-native", "swift", "vue"]
gen: 2
last-updated: "2026-03-25T17:40:00.000Z"
url: "https://docs.amplify.aws/react/frontend/auth/multi-step-sign-in/"
---

<!-- Platform: angular, javascript, nextjs, react, react-native, vue -->
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_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({
		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 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.

<Callout>

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.

</Callout>

```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': {
			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;
		}
	}
}

async function confirmMfaCode(mfaCode: string) {
	const result = await confirmSignIn({ challengeResponse: mfaCode });

	return handleSignInResult(result);
}

```

## 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.

```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': {
			// 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 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.

<Callout>

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.

</Callout>

```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': {
			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;
		}
	}
}

async function confirmMfaCode(mfaCode: string) {
	const result = await confirmSignIn({ challengeResponse: mfaCode });

	return handleSignInResult(result);
}

```

## 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.

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
import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth';

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 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.

```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': {
			// 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 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.

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
import { type SignInOutput, confirmSignIn } from '@aws-amplify/auth';

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 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.

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
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': {
			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 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.

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': {
			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);
}
```

> **Warning:** **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 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]/frontend/auth/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';

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;
		}
	}
}

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
import {
	type ResetPasswordOutput,
	type SignInOutput,
	resetPassword,
} from '@aws-amplify/auth';

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 [sign up](/[platform]/frontend/auth/sign-up/) docs for more information.

<Callout>

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.

</Callout>

```ts
import {
	type SignInOutput,
	confirmSignUp,
	resendSignUpCode,
} from '@aws-amplify/auth';

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;
		}
	}
}

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
import { type SignInOutput } from '@aws-amplify/auth';

async function handleSignInResult(result: SignInOutput) {
	switch (result.nextStep.signInStep) {
		case 'DONE': {
			// `result.isSignedIn` is `true`
			console.log(`Sign in is complete.`);
			break;
		}
	}
}

```
<!-- /Platform -->

<!-- Platform: flutter -->
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.

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 in the signin result.

> **Warning:** *New enumeration values*
> 
> When Amplify adds a new enumeration value (e.g., a new enum class entry or sealed class subtype in Kotlin, or a new enum value in Swift/Dart/Kotlin), it will publish a new minor version of the Amplify Library. Plugins that switch over enumeration values should include default handlers (an else branch in Kotlin or a default statement in Swift/Dart/Kotlin) to ensure that they are not impacted by new enumeration values.

The `Amplify.Auth.signIn` API returns a `SignInResult` object which indicates whether the sign-in flow is
complete or whether additional steps are required before the user is signed in.

To see if additional signin steps are required, inspect the sign in result's `nextStep.signInStep` property.
- If the sign-in step is `done`, the flow is complete and the user is signed in.
- If the sign-in step is not `done`, one or more additional steps are required. These are explained in detail below.

<Callout>

The `signInStep` property is an enum of type `AuthSignInStep`. Depending on its value, your code should take one of the actions mentioned on this page.

</Callout>

```dart
Future<SignInResult> signInWithCognito(
  String username,
  String password,
) async {
  final SignInResult result = await Amplify.Auth.signIn(
    username: username, 
    password: password,
  );
  return _handleSignInResult(result);
}

Future<void> _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.confirmSignInWithOtpCode:
      // Handle email MFA case
    case AuthSignInStep.continueSignInWithTotpSetup:
      // Handle TOTP setup case
    case AuthSignInStep.confirmSignInWithTotpMfaCode:
      // Handle TOTP MFA case
    case AuthSignInStep.confirmSignInWithSmsMfaCode:
      // Handle SMS MFA case
    case AuthSignInStep.confirmSignInWithNewPassword:
      // Handle new password case
    case AuthSignInStep.confirmSignInWithCustomChallenge:
      // Handle custom challenge case
    case AuthSignInStep.resetPassword:
      // Handle reset password case
    case AuthSignInStep.confirmSignUp:
      // Handle confirm sign up case
    case AuthSignInStep.done:
      safePrint('Sign in is complete');
  }
}
```
## 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.

<Callout>

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.

</Callout>

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    case AuthSignInStep.confirmSignInWithSmsMfaCode:
      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<void> 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}');
  }
}
```

## 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.

After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API.

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.confirmSignInWithTotpMfaCode:
      safePrint('Enter a one-time code from your registered authenticator app');
    // ···
  }
}

// Then, pass the TOTP code to `confirmSignIn`

Future<void> confirmTotpUser(String totpCode) async {
  try {
    final result = await Amplify.Auth.confirmSignIn(
      confirmationValue: totpCode,
    );
    return _handleSignInResult(result);
  } on AuthException catch (e) {
    safePrint('Error confirming TOTP code: ${e.message}');
  }
}
```

## 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.

<Callout>

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.

</Callout>

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    case AuthSignInStep.confirmSignInWithOtpCode:
      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<void> 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 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.

The MFA types which are currently supported by Amplify Auth are:

- `MfaType.sms`
- `MfaType.totp`
- `MfaType.email`

```dart
Future<void> _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<MfaType> _promptUserPreference(Set<MfaType> allowedTypes) async {
  // ···
}

Future<void> _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}');
  }
}
```

## 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.

```dart
Future<void> _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<void> confirmEmailUser(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 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.

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.

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.continueSignInWithTotpSetup:
      final totpSetupDetails = result.nextStep.totpSetupDetails!;
      final setupUri = totpSetupDetails.getSetupUri(appName: 'MyApp');
      safePrint('Open URI to complete setup: $setupUri');
    // ···
  }
}

// Then, pass the TOTP code to `confirmSignIn`

Future<void> confirmTotpUser(String totpCode) async {
  try {
    final result = await Amplify.Auth.confirmSignIn(
      confirmationValue: totpCode,
    );
    return _handleSignInResult(result);
  } on AuthException catch (e) {
    safePrint('Error confirming TOTP code: ${e.message}');
  }
}
```

## 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:

- `MfaType.sms`
- `MfaType.totp`
- `MfaType.email`

```dart
Future<void> _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<MfaType> _promptUserPreference(Set<MfaType> allowedTypes) async {
  // ···
}

Future<void> _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 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).

For example, your custom challenge Lambda may pass a prompt to the frontend which requires the user to enter a secret code.

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ...
    case AuthSignInStep.confirmSignInWithCustomChallenge:
      final parameters = result.nextStep.additionalInfo;
      final hint = parameters['hint']!;
      safePrint(hint); // "Enter the secret code"
    // ...
  }
}
```

To complete this step, you should prompt the user for the custom challenge answer, and pass the answer to the `confirmSignIn` API.

```dart
Future<void> confirmCustomChallenge(String answer) async {
  try {
    final result = await Amplify.Auth.confirmSignIn(
      confirmationValue: answer,
    );
    return _handleSignInResult(result);
  } on AuthException catch (e) {
    safePrint('Error confirming custom challenge: ${e.message}');
  }
}
```

> **Warning:** **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 `Amplify.Auth.signIn` again.

## 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.

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ...
    case AuthSignInStep.confirmSignInWithNewPassword:
      safePrint('Please enter a new password');
    // ...
  }
}
```

```dart
Future<void> confirmNewPassword(String newPassword) async {
  try {
    final result = await Amplify.Auth.confirmSignIn(
      confirmationValue: newPassword,
    );
    return _handleSignInResult(result);
  } on AuthException catch (e) {
    safePrint('Error confirming new password: ${e.message}');
  }
}
```

## 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.

See the [reset password](/[platform]/build-a-backend/auth/manage-users/manage-passwords/) docs for more information.

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ...
    case AuthSignInStep.resetPassword:
      final resetResult = await Amplify.Auth.resetPassword(
        username: username,
      );
      await _handleResetPasswordResult(resetResult);
    // ...
  }
}

Future<void> _handleResetPasswordResult(ResetPasswordResult result) async {
  switch (result.nextStep.updateStep) {
    case AuthResetPasswordStep.confirmResetPasswordWithCode:
      final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!;
      _handleCodeDelivery(codeDeliveryDetails);
    case AuthResetPasswordStep.done:
      safePrint('Successfully reset password');
  }
}

void _handleCodeDelivery(AuthCodeDeliveryDetails codeDeliveryDetails) {
  safePrint(
    'A confirmation code has been sent to ${codeDeliveryDetails.destination}. '
    'Please check your ${codeDeliveryDetails.deliveryMedium.name} for the code.',
  );
}
```
## 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.

See the [confirm sign up](/[platform]/frontend/auth/sign-up/#confirm-sign-up) docs for more information.

<Callout>

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.

</Callout>

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ...
    case AuthSignInStep.confirmSignUp:
      // Resend the sign up code to the registered device.
      final resendResult = await Amplify.Auth.resendSignUpCode(
        username: username,
      );
      _handleCodeDelivery(resendResult.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<void> confirmSignUp({
  required String username,
  required String confirmationCode,
}) async {
  try {
    await Amplify.Auth.confirmSignUp(
      username: username,
      confirmationCode: confirmationCode,
    );
  } on AuthException catch (e) {
    safePrint('Error confirming sign up: ${e.message}');
  }
}
```

Once the sign up is confirmed, call `Amplify.Auth.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`.

```dart
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ...
    case AuthSignInStep.done:
      // Could also check that `result.isSignedIn` is `true`
      safePrint('Sign in is complete');
  }
}
```
<!-- /Platform -->

<!-- Platform: android -->
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. 

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 in the signin result.

> **Warning:** *New enumeration values*
> 
> When Amplify adds a new enumeration value (e.g., a new enum class entry or sealed class subtype in Kotlin, or a new enum value in Swift/Dart/Kotlin), it will publish a new minor version of the Amplify Library. Plugins that switch over enumeration values should include default handlers (an else branch in Kotlin or a default statement in Swift/Dart/Kotlin) to ensure that they are not impacted by new enumeration values.

When called successfully, the signin APIs will return an `AuthSignInResult`. Inspect the `nextStep` property in the result to see if additional signin steps are required.
The `nextStep` property is of enum type `AuthSignInStep`. Depending on its value, your code should take one of the following actions:

#### [Java]

```java
try {
    Amplify.Auth.signIn(
        "hello@example.com",
        "password",
        result ->
        {
            AuthNextSignInStep nextStep = result.getNextStep();
            switch (nextStep.getSignInStep()) {
                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_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: {
                    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
                    // Then invoke `confirmSignIn` api with the MFA type
                    break;
                }
                case CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION: {
                    Log.i("AuthQuickstart", "Available authentication factors for this user: " + result.getNextStep().getAvailableFactors());
                    // Prompt the user to select which authentication factor they want to use to sign-in
                    // Then invoke `confirmSignIn` api with that selection
                    break;
                }
                case CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE: {
                    Log.i("AuthQuickstart", "SMS code sent to " + nextStep.getCodeDeliveryDetails().getDestination());
                    Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo());
                    // Prompt the user to enter the SMS MFA code they received
                    // Then invoke `confirmSignIn` api with the code
                    break;
                }
                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 OTP MFA code they received
                    // Then invoke `confirmSignIn` api with the code
                    break;
                }
              	case CONFIRM_SIGN_IN_WITH_PASSWORD: {
                		Log.i("AuthQuickstart", "Received next step as confirm sign in with password");
                		// Prompt the user to enter their password
                		// Then invoke `confirmSignIn` api with that password
                		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
                    // Then invoke `confirmSignIn` api with the answer
                    break;
                }
                case CONFIRM_SIGN_IN_WITH_NEW_PASSWORD: {
                    Log.i("AuthQuickstart", "Sign in with new password, additional info: " + nextStep.getAdditionalInfo());
                    // Prompt the user to enter a new password
                    // Then invoke `confirmSignIn` api with new password
                    break;
                }
                case DONE: {
                    Log.i("AuthQuickstart", "SignIn complete");
                    // User has successfully signed in to the app
                    break;
                }
            }
        },
        error -> {
            if (error instanceof UserNotConfirmedException) {
                // User was not confirmed during the signup process.
                // Invoke `confirmSignUp` api to confirm the user if
                // they have the confirmation code. If they do not have the
                // confirmation code, invoke `resendSignUpCode` to send the
                // code again.
                // After the user is confirmed, invoke the `signIn` api again.
                Log.i("AuthQuickstart", "Signup confirmation required" + error);
            } else if (error instanceof PasswordResetRequiredException) {
                // User needs to reset their password.
                // Invoke `resetPassword` api to start the reset password
                // flow, and once reset password flow completes, invoke
                // `signIn` api to trigger signIn flow again.
                Log.i("AuthQuickstart", "Password reset required" + error);
            } else {
                Log.e("AuthQuickstart", "SignIn failed: " + error);
            }
        }
    );
} catch (Exception error) {
    Log.e("AuthQuickstart", "Unexpected error occurred: " + error);
}
```

#### [Kotlin - Callbacks]

```kotlin
try {
    Amplify.Auth.signIn(
        "hello@example.com",
        "password",
        { result ->
            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
                }
                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.allowedMFATypes}")
                    // 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}")
                    // 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_SELECTION -> {
                    Log.i("AuthQuickstart", "Received next step as continue sign in by selecting MFA type")
                    Log.i("AuthQuickstart", "Allowed MFA types ${nextStep.allowedMFATypes}")
                    // Prompt the user to select the MFA type they want to use
                    // Then invoke `confirmSignIn` api with the MFA type
                }
                AuthSignInStep.CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION -> {
                    Log.i("AuthQuickstart", "Available authentication factors for this user:  ${result.nextStep.availableFactors}")
                    // Prompt the user to select which authentication factor they want to use to sign-in
                    // Then invoke `confirmSignIn` api with that selection
                }
                AuthSignInStep.CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE -> {
                    Log.i("AuthQuickstart", "SMS code sent to ${nextStep.codeDeliveryDetails?.destination}")
                    Log.i("AuthQuickstart", "Additional Info ${nextStep.additionalInfo}")
                    // 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_PASSWORD -> {
                    Log.i("AuthQuickstart", "Received next step as confirm sign in with password")
                    // Prompt the user to enter their password
                    // Then invoke `confirmSignIn` api with that password
                }
                AuthSignInStep.CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE -> {
                    Log.i("AuthQuickstart","Custom challenge, additional info: ${nextStep.additionalInfo}")
                    // Prompt the user to enter custom challenge answer
                    // Then invoke `confirmSignIn` api with the answer
                }
                AuthSignInStep.CONFIRM_SIGN_IN_WITH_NEW_PASSWORD -> {
                    Log.i("AuthQuickstart", "Sign in with new password, additional info: ${nextStep.additionalInfo}")
                    // Prompt the user to enter a new password
                    // Then invoke `confirmSignIn` api with new password
                }
                AuthSignInStep.DONE -> {
                    Log.i("AuthQuickstart", "SignIn complete")
                    // User has successfully signed in to the app
                }
            }

        }
    ) { error ->
        when (error) {
            is UserNotConfirmedException -> {
                // User was not confirmed during the signup process.
                // Invoke `confirmSignUp` api to confirm the user if
                // they have the confirmation code. If they do not have the
                // confirmation code, invoke `resendSignUpCode` to send the
                // code again.
                // After the user is confirmed, invoke the `signIn` api again.
                Log.e("AuthQuickstart", "Signup confirmation required", error)
            }
            is PasswordResetRequiredException -> {
                // User needs to reset their password.
                // Invoke `resetPassword` api to start the reset password
                // flow, and once reset password flow completes, invoke
                // `signIn` api to trigger signIn flow again.
                Log.e("AuthQuickstart", "Password reset required", error)
            }
            else -> {
                Log.e("AuthQuickstart", "Unexpected error occurred: $error")
            }
        }
    }
} catch (error: Exception) {
    Log.e("AuthQuickstart", "Unexpected error occurred: $error")
}
```

#### [Kotlin - Coroutines]

```kotlin
try {
    val result = Amplify.Auth.signIn(
        "hello@example.com",
        "password"
    )
    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
        }
        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.allowedMFATypes}")
            // 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}")
            // 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_SELECTION -> {
            Log.i("AuthQuickstart", "Received next step as continue sign in by selecting MFA type")
            Log.i("AuthQuickstart", "Allowed MFA types ${nextStep.allowedMFATypes}")
            // Prompt the user to select the MFA type they want to use
            // Then invoke `confirmSignIn` api with the MFA type
        }
        AuthSignInStep.CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION -> {
            Log.i("AuthQuickstart", "Available authentication factors for this user:  ${result.nextStep.availableFactors}")
            // Prompt the user to select which authentication factor they want to use to sign-in
            // Then invoke `confirmSignIn` api with that selection
        }
        AuthSignInStep.CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE -> {
            Log.i("AuthQuickstart", "SMS code sent to ${nextStep.codeDeliveryDetails?.destination}")
            Log.i("AuthQuickstart", "Additional Info ${nextStep.additionalInfo}")
            // 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_PASSWORD -> {
            Log.i("AuthQuickstart", "Received next step as confirm sign in with password")
            // Prompt the user to enter their password
            // Then invoke `confirmSignIn` api with that password
        }
        AuthSignInStep.CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE -> {
            Log.i("AuthQuickstart","Custom challenge, additional info: ${nextStep.additionalInfo}")
            // Prompt the user to enter custom challenge answer
            // Then invoke `confirmSignIn` api with the answer
        }
        AuthSignInStep.CONFIRM_SIGN_IN_WITH_NEW_PASSWORD -> {
            Log.i("AuthQuickstart", "Sign in with new password, additional info: ${nextStep.additionalInfo}")
            // Prompt the user to enter a new password
            // Then invoke `confirmSignIn` api with new password
        }
        AuthSignInStep.DONE -> {
            Log.i("AuthQuickstart", "SignIn complete")
            // User has successfully signed in to the app
        }
    }
} catch (error: Exception) {
    when (error) {
        is UserNotConfirmedException -> {
            // User was not confirmed during the signup process.
            // Invoke `confirmSignUp` api to confirm the user if
            // they have the confirmation code. If they do not have the
            // confirmation code, invoke `resendSignUpCode` to send the
            // code again.
            // After the user is confirmed, invoke the `signIn` api again.
            Log.e("AuthQuickstart", "Signup confirmation required", error)
        }
        is PasswordResetRequiredException -> {
            // User needs to reset their password.
            // Invoke `resetPassword` api to start the reset password
            // flow, and once reset password flow completes, invoke
            // `signIn` api to trigger signIn flow again.
            Log.e("AuthQuickstart", "Password reset required", error)
        }
        else -> {
            Log.e("AuthQuickstart", "Unexpected error occurred: $error")
        }
    }
}
```

#### [RxJava]

```java
RxAmplify.Auth.signIn("hello@example.com", "password").subscribe(
    result ->
    {
        AuthNextSignInStep nextStep = result.getNextStep();
        switch (nextStep.getSignInStep()) {
            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_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: {
                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
                // Then invoke `confirmSignIn` api with the MFA type
                break;
            }
            case CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION: {
                Log.i("AuthQuickstart", "Available authentication factors for this user: " + result.getNextStep().getAvailableFactors());
                // Prompt the user to select which authentication factor they want to use to sign-in
                // Then invoke `confirmSignIn` api with that selection
                break;
            }
            case CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE: {
                Log.i("AuthQuickstart", "SMS code sent to " + nextStep.getCodeDeliveryDetails().getDestination());
                Log.i("AuthQuickstart", "Additional Info :" + nextStep.getAdditionalInfo());
                // Prompt the user to enter the SMS MFA code they received
                // Then invoke `confirmSignIn` api with the code
                break;
            }
            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 OTP MFA code they received
                // Then invoke `confirmSignIn` api with the code
                break;
            }
            case CONFIRM_SIGN_IN_WITH_PASSWORD: {
                Log.i("AuthQuickstart", "Received next step as confirm sign in with password");
                // Prompt the user to enter their password
                // Then invoke `confirmSignIn` api with that password
                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
                // Then invoke `confirmSignIn` api with the answer
                break;
            }
            case CONFIRM_SIGN_IN_WITH_NEW_PASSWORD: {
                Log.i("AuthQuickstart", "Sign in with new password, additional info: " + nextStep.getAdditionalInfo());
                // Prompt the user to enter a new password
                // Then invoke `confirmSignIn` api with new password
                break;
            }
            case DONE: {
                Log.i("AuthQuickstart", "SignIn complete");
                // User has successfully signed in to the app
                break;
            }
        }
    },
    error -> {
        if (error instanceof UserNotConfirmedException) {
            // User was not confirmed during the signup process.
            // Invoke `confirmSignUp` api to confirm the user if
            // they have the confirmation code. If they do not have the
            // confirmation code, invoke `resendSignUpCode` to send the
            // code again.
            // After the user is confirmed, invoke the `signIn` api again.
            Log.i("AuthQuickstart", "Signup confirmation required" + error);
        } else if (error instanceof PasswordResetRequiredException) {
            // User needs to reset their password.
            // Invoke `resetPassword` api to start the reset password
            // flow, and once reset password flow completes, invoke
            // `signIn` api to trigger signIn flow again.
            Log.i("AuthQuickstart", "Password reset required" + error);
        } else {
            Log.e("AuthQuickstart", "SignIn failed: " + error);
        }
    }
);
```

## 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.

<Callout>

**Note:** The result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial phone number of the SMS recipient.

</Callout>

#### [Java]

```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 - Callbacks]

```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 - Coroutines]

```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")
}
```

#### [RxJava]

```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)
        );
```

## 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 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.

<Callout>

**Note:** The result also includes an `AuthCodeDeliveryDetails` member. It includes additional information about the code delivery such as the partial email address of the recipient.

</Callout>

## Confirm sign-in with OTP

If the next step is `CONFIRM_SIGN_IN_WITH_OTP`, Amplify Auth has sent the user a random code to the medium of the user's choosing (e.g. SMS or email) 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.

<Callout>

**Note:** 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.

</Callout>

## 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 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 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 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.

## Continue sign-in with First Factor Selection

If the next step is `CONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTION`, the user must select an authentication factor to use either because they did not specify one or because the one they chose is not supported (e.g. selecting SMS when they don't have a phone number registered to their account). Amplify Auth currently supports SMS, email, password, and webauthn as authentication factors. After the user selects an authentication method, your implementation must pass the selected authentication method to Amplify Auth using `confirmSignIn` API.

Visit the [sign-in documentation](/[platform]/frontend/auth/sign-in/#sign-in-with-passwordless-methods) to see examples on how to call the `confirmSignIn` API.

## 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.

#### [Java]

```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)
    );
} catch (Exception error) {
    Log.e("AuthQuickstart", "Unexpected error: " + error);
}
```

#### [Kotlin - Callbacks]

```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")
    }
} catch (error: Exception) {
    Log.e("AuthQuickstart", "Unexpected error: $error")
}
```

#### [Kotlin - Coroutines]

```kotlin
try {
    val result = Amplify.Auth.confirmSignIn(
        "challenge answer"
    )
    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")
}
```

#### [RxJava]

```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)
);
```

> **Warning:** **Special Handling on `confirmSignIn`**
> 
> During a confirmSignIn call if `failAuthentication=true` is returned by the Lambda the session of the request gets invalidated by cognito, a NotAuthorizedException is returned and a new signIn call is expected via Amplify.Auth.signIn
> 
> ```java
NotAuthorizedException{message=Failed since user is not authorized., cause=NotAuthorizedException(message=Invalid session for the user.), recoverySuggestion=Check whether the given values are correct and the user is authorized to perform the operation.}
```

## 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.

#### [Java]

```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 - Callbacks]

```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}")
              }
          }
      ) { error ->
          Log.e("AuthQuickstart", "Confirm sign in failed: $error")
      }
} catch (error: Exception) {
    Log.e("AuthQuickstart", "Unexpected error: $error")
}
}
```

#### [Kotlin - Coroutines]

```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}")
    }
} catch (error: Exception) {
    Log.e("AuthQuickstart", "Unexpected error: $error")
}
```

#### [RxJava]

```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());
                    }
                },
                error -> Log.e("AuthQuickstart", "Confirm sign in failed: " + error)
        );
```

## 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.

#### [Java]

```java
try {
    Amplify.Auth.resetPassword(
            "username",
            result -> Log.i("AuthQuickstart", "Reset password succeeded"),
            error -> Log.e("AuthQuickstart", "Reset password failed : " + error)
    );
} catch (Exception error) {
    Log.e("AuthQuickstart", "Unexpected error: " + error);
}
```

#### [Kotlin - Callbacks]

```kotlin
try {
      Amplify.Auth.resetPassword(
          "username",
          {
              Log.i("AuthQuickstart", "Reset password succeeded")
          }
      ) { error ->
          Log.e("AuthQuickstart", "Reset password failed : $error")
      }
} catch (error: Exception) {
    Log.e("AuthQuickstart", "Unexpected error: $error")
}
```

#### [Kotlin - Coroutines]

```kotlin
try {
    Amplify.Auth.resetPassword("username")
    Log.i("AuthQuickstart", "Reset password succeeded")
} catch (error: Exception) {
    Log.e("AuthQuickstart", "Unexpected error: $error")
}
```

#### [RxJava]

```java
RxAmplify.Auth.resetPassword(
        "username").subscribe(
        result -> Log.i("AuthQuickstart", "Reset password succeeded"),
        error -> Log.e("AuthQuickstart", "Reset password failed : " + error)
);
```

## 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.

#### [Java]

```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 - Callbacks]

```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 - Coroutines]

```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")
}
```

#### [RxJava]

```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)
);
```

## 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.

<Callout>
**Note:** An empty string will be assigned to userId and/or username, if the values are not present in the accessToken.
</Callout>

#### [Java]

```java
 try {
    Amplify.Auth.getCurrentUser(
           result -> Log.i("AuthQuickstart", "Current user details are:" + result.toString(),
           error -> Log.e("AuthQuickstart", "getCurrentUser failed with an exception: " + error)
    );
 } catch (Exception error) {
    Log.e("AuthQuickstart", "unexpected error: " + error);
 }
```

#### [Kotlin - Callbacks]

```kotlin
Amplify.Auth.getCurrentUser({
    Log.i("AuthQuickStart", "Current user details are: $it")},{
    Log.e("AuthQuickStart", "getCurrentUser failed with an exception: $it")
})
```

#### [Kotlin - Coroutines]

```kotlin
try {
    val result = Amplify.Auth.getCurrentUser()
    Log.i("AuthQuickstart", "Current user details are: $result")
} catch (error: Exception) {
    Log.e("AuthQuickstart", "getCurrentUser failed with an exception: $error")
}
```

#### [RxJava]

```java
  RxAmplify.Auth.getCurrentUser().subscribe(
        result -> Log.i("AuthQuickStart getCurrentUser: " + result.toString()),
        error -> Log.e("AuthQuickStart", error.toString())
 );
```

## 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`.
<!-- /Platform -->

<!-- Platform: swift -->
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. 

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 in the signin result.

> **Warning:** *New enumeration values*
> 
> When Amplify adds a new enumeration value (e.g., a new enum class entry or sealed class subtype in Kotlin, or a new enum value in Swift/Dart/Kotlin), it will publish a new minor version of the Amplify Library. Plugins that switch over enumeration values should include default handlers (an else branch in Kotlin or a default statement in Swift/Dart/Kotlin) to ensure that they are not impacted by new enumeration values.

When called successfully, the signin APIs will return an `AuthSignInResult`. Inspect the `nextStep` property in the result to see if additional signin steps are required.

```swift
func signIn(username: String, password: String) async {
    do {
        let signInResult = try await Amplify.Auth.signIn(username: username, password: password)
        switch signInResult.nextStep {
        case .confirmSignInWithSMSMFACode(let deliveryDetails, let info):
            print("SMS code sent to \(deliveryDetails.destination)")
            print("Additional info \(String(describing: info))")

            // Prompt the user to enter the SMSMFA code they received
            // Then invoke `confirmSignIn` api with the code

        case .confirmSignInWithTOTPCode:
            print("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

        case .confirmSignInWithOTP(let deliveryDetails):
            print("Email code sent to \(deliveryDetails.destination)")

            // Prompt the user to enter the Email MFA code they received
            // Then invoke `confirmSignIn` api with the code

        case .continueSignInWithFirstFactorSelection(let allowedFactors):
            print("Received next step as continue sign in by selecting first factor")
            print("Allowed factors \(allowedFactors)")

            // Prompt the user to select the first factor they want to use
            // Then invoke `confirmSignIn` api with the factor

        case .confirmSignInWithPassword:
            print("Received next step as confirm sign in with password")

            // Prompt the user to enter the password
            // Then invoke `confirmSignIn` api with the password
        
        case .continueSignInWithTOTPSetup(let setUpDetails):
            print("Received next step as continue sign in by setting up TOTP")
            print("Shared secret that will be used to set up TOTP in the authenticator app \(setUpDetails.sharedSecret)")
            
            // 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)")
            
            // Prompt the user to select the MFA type they want to use
            // Then invoke `confirmSignIn` api with the MFA type
        
        case .confirmSignInWithCustomChallenge(let info):
            print("Custom challenge, additional info \(String(describing: info))")
            
            // Prompt the user to enter custom challenge answer
            // Then invoke `confirmSignIn` api with the answer
        
        case .confirmSignInWithNewPassword(let info):
            print("New password additional info \(String(describing: info))")
            
            // Prompt the user to enter a new password
            // Then invoke `confirmSignIn` api with new password
        
        case .resetPassword(let info):
            print("Reset password additional info \(String(describing: info))")
            
            // User needs to reset their password.
            // Invoke `resetPassword` api to start the reset password
            // flow, and once reset password flow completes, invoke
            // `signIn` api to trigger signin flow again.
        
        case .confirmSignUp(let info):
            print("Confirm signup additional info \(String(describing: info))")
            
            // User was not confirmed during the signup process.
            // Invoke `confirmSignUp` api to confirm the user if
            // they have the confirmation code. If they do not have the
            // confirmation code, invoke `resendSignUpCode` to send the
            // code again.
            // After the user is confirmed, invoke the `signIn` api again.
        case .done:
            
            // Use has successfully signed in to the app
            print("Signin complete")
        }
    } catch let error as AuthError{
        print ("Sign in failed \(error)")
    } catch {
        print("Unexpected error: \(error)")
    }
}
```

The `nextStep` property is of enum type `AuthSignInStep`. Depending on its value, your code should take one of the following actions:

## 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.

#### [Async/Await]

```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)")
    }
}
```

#### [Combine]

```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.
            }
        }
}
```

## 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.

After the user enters the code, your implementation must pass the value to Amplify Auth `confirmSignIn` API.

#### [Async/Await]

```swift
func confirmSignIn(totpCode: String) async {
    do {
        let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: totpCode)
        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 {
        print("Confirm sign in failed \(error)")
    }
}
```

#### [Combine]

```swift
func confirmSignIn(totpCode: String) -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.confirmSignIn(challengeResponse: totpCode)
        }.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.
            }
        }
}
```

## 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.

> **Info:** **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.

#### [Async/Await]

```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)")
    }
}
```

#### [Combine]

```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 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.

#### [Async/Await]

```swift
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)")
    }
}
```

#### [Combine]

```swift
func confirmSignInWithTOTPAsMFASelection() -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.confirmSignIn(
            challengeResponse: MFAType.totp.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")
        }
    }
}
```

## 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 
// 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 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.

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.

```swift 
// Confirm sign in with TOTP setup
case .continueSignInWithTOTPSetup(let setUpDetails):
    
    /// appName parameter will help distinguish the account in the Authenticator app
    let setupURI = try setUpDetails.getSetupURI(appName: "<Your_App_Name>>") 
    
    print("TOTP Setup URI: \(setupURI)")
```

#### [Async/Await]

```swift
func confirmSignInWithTOTPSetup(totpCodeFromAuthenticatorApp: String) async {
    do {
        let signInResult = try await Amplify.Auth.confirmSignIn(
            challengeResponse: totpCodeFromAuthenticatorApp)

         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 {
        print("Confirm sign in failed \(error)")
    }
}
```

#### [Combine]

```swift
func confirmSignInWithTOTPSetup(totpCodeFromAuthenticatorApp: String) -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.confirmSignIn(
            challengeResponse: totpCodeFromAuthenticatorApp)
        }.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 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.

#### [Async/Await]

```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)")
    }
}
```

#### [Combine]

```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 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.

#### [Async/Await]

```swift
func confirmSignIn(challengeAnswerFromUser: String) async {
    do {
        let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: challengeAnswerFromUser)
        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)")
    }
}
```

#### [Combine]

```swift
func confirmSignIn(challengeAnswerFromUser: String) -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.confirmSignIn(challengeResponse: challengeAnswerFromUser)
        }.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.
            }
        }
}
```

> **Warning:** **Special Handling on `confirmSignIn`**
> 
> During a confirmSignIn call if `failAuthentication=true` is returned by the Lambda function the session of the request gets invalidated by cognito, a NotAuthorizedException is returned and a new signIn call is expected via Amplify.Auth.signIn
> 
> ```swift
Exception:  notAuthorized{message=Failed since user is not authorized., cause=NotAuthorizedException(message=Invalid session for the user.), recoverySuggestion=Check whether the given values are correct and the user is authorized to perform the operation.}
```

## 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.

#### [Async/Await]

```swift
func confirmSignIn(newPasswordFromUser: String) async {
    do {
        let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: newPasswordFromUser)
        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)")
    }
}
```

#### [Combine]

```swift
func confirmSignIn(newPasswordFromUser: String) -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.confirmSignIn(challengeResponse: newPasswordFromUser)
        }.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.
            }
        }
}
```

## 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.

#### [Async/Await]

```swift
func resetPassword(username: String) async {
    do {
        let resetPasswordResult = try await Amplify.Auth.resetPassword(for: username)
        print("Reset password succeeded.")
        print("Next step: \(resetPasswordResult.nextStep)")
    } catch let error as AuthError {
        print("Reset password  failed \(error)")
    } catch {
        print("Unexpected error: \(error)")
    }
}
```

#### [Combine]

```swift
func resetPassword(username: String) -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.resetPassword(for: username)
        }.sink {
            if case let .failure(authError) = $0 {
                print("Reset password  failed \(authError)")
            }
        }
        receiveValue: { resetPasswordResult in
            print("Reset password succeeded.")
            print("Next step: \(resetPasswordResult.nextStep)")
        }
}
```

## 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.

#### [Async/Await]

```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)")
    }
}
```

#### [Combine]

```swift
func confirmSignUp(for username: String, with confirmationCode: String) -> AnyCancellable {
    Amplify.Publisher.create {
        try await Amplify.Auth.confirmSignUp(for: username, confirmationCode: confirmationCode)
        }.sink {
            if case let .failure(authError) = $0 {
                print("An error occurred while confirming sign up \(authError)")
            }
        }
        receiveValue: { _ in
            print("Confirm signUp succeeded")
        }
}
```

## 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`.
<!-- /Platform -->
