Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 150 additions & 11 deletions src/fragments/lib/auth/js/emailpassword.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,55 @@ Based on the two parameters returned in the user object, you can then call the c

If the user has SMS Multi-Factor Authentication (MFA) enabled, Cognito responds with a challenge that requires the user to provide an SMS verification code. This is where you can trigger `Auth.confirmSignIn()` and pass in the code provided by the user. Amplify will then verify with Cognito that the SMS code is valid and complete the sign in process via Cognito returning access, ID, and refresh tokens that are all handled by Amplify internally.

```javascript
<BlockSwitcher>
<Block name="TypeScript">

```ts
import { Auth } from 'aws-amplify';

type ConfirmSignInWithMFAParameters = {
username: string;
password: string;
};

type MFAType = 'SMS_MFA' | 'SOFTWARE_TOKEN_MFA';

export async function signInWithMFA({ username, password }: ConfirmSignInWithMFAParameters) {
try {
const user = await Auth.signIn(username, password);
if (user.challengeName === 'SMS_MFA' || user.challengeName === 'SOFTWARE_TOKEN_MFA') {
// You need to get the code from the UI inputs
// and then trigger the following function with a button click.
const code: string = await getCodeFromUserInput();
const mfaType: MFAType = await getMFATypeFromUserInput();
// If MFA is enabled, sign-in should be confirmed with the confirmation code
const loggedUser = await Auth.confirmSignIn(
user, // Return object from Auth.signIn()
code, // Confirmation code
mfaType // MFA Type e.g. SMS_MFA, SOFTWARE_TOKEN_MFA
);
console.log(loggedUser);
} else {
// The user directly signs in
console.log(user);
}
} catch (error) {
console.log(`error signing in`, error);
}
}

async function getCodeFromUserInput(): Promise<string> {
// fetch code using a user form input
}
async function getMFATypeFromUserInput(): Promise<MFAType> {
// fetch MFA type from user form input
}
```
</Block>
<Block name="JavaScript">

```javascript
import { Auth } from 'aws-amplify';

async function signInWithMFA() {
try {
Expand Down Expand Up @@ -319,64 +365,157 @@ async function signInWithMFA() {
}
};
```
</Block>
</BlockSwitcher>

### Confirm sign in with custom challenge

If you have implemented custom challenges within your authentication flow, Cognito will respond to a sign in attempt with a `challengeName` and `challengeParam`. Once again, Cognito will validate the the user's response and provide the necessary tokens if successful and resolves the `Auth.signIn()` promise.

<BlockSwitcher>
<Block name="TypeScript">

```ts
import { Auth } from 'aws-amplify';

type ConfirmSignInWithCustomChallenge = {
username: string;
password: string;
};

export async function signInWithCustomChallenge({
username,
password,
}: ConfirmSignInWithCustomChallenge) {
try {
const user = await Auth.signIn(username, password);
if (user.challengeName === 'CUSTOM_CHALLENGE') {
const challengeResponse = await getChallengeResponseFromUserInput();
// to send the answer of the custom challenge
const loggedUser = await Auth.sendCustomChallengeAnswer(user, challengeResponse);
console.log(loggedUser);
} else {
console.log(user);
}
} catch (err) {
console.log(err);
}
}

async function getChallengeResponseFromUserInput(): Promise<string> {
// fetch challenge response from user form input
}
```
</Block>
<Block name="JavaScript">

```javascript
import { Auth } from 'aws-amplify';

async function signInWithCustomChallenge() {
try {
const user = await Auth.signIn(username, password)
const user = await Auth.signIn(username, password);
if (user.challengeName === 'CUSTOM_CHALLENGE') {
const challengeResponse = getChallengeResponseFromUserInput();
// to send the answer of the custom challenge
const loggedUser = await Auth.sendCustomChallengeAnswer(user, challengeResponse)
console.log(loggedUser)
const loggedUser = await Auth.sendCustomChallengeAnswer(user, challengeResponse);
console.log(loggedUser);
} else {
console.log(user);
}
} catch(err => console.log(err));
} catch (err) {
console.log(err);
}
}
```

</Block>
</BlockSwitcher>

### Confirm sign in with new password

New users can be created from the [Cognito console](https://console.aws.amazon.com/cognito/home) for your app, which then forces the user to input a new password and any "required attributes" that may have been optionally configured to complete the sign in flow. If the user object returned by `Auth.signIn()` contains the `NEW_PASSWORD_REQUIRED` for the `challengeName`, you can submit the data using the `Auth.completeNewPassword()` method as well.

<BlockSwitcher>
<Block name="TypeScript">

```ts
import { Auth } from 'aws-amplify';

type ConfirmSignInWithNewPassword = {
username: string;
password: string;
};

type UserInput = {
username: string;
email: string;
phone_number: string;
newPassword: string;
};

export async function signInWithNewPassword({ username, password }: ConfirmSignInWithNewPassword) {
try {
const user = await Auth.signIn(username, password);
if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {
// Required attributes are OPTIONAL, but if they were configured
// you need to get these in addition to new password from UI inputs
const { requiredAttributes } = user.challengeParam;
// Example if email and phone_number were required attributes
const { email, phone_number, newPassword } = await getInfoFromUserInput();
const loggedUser = await Auth.completeNewPassword(
user, // the Cognito User Object
newPassword, // the new password
// OPTIONAL, the required attributes
{
email,
phone_number,
}
);
console.log(loggedUser);
}
} catch (error) {
console.log('Error confirming sign in with new password', error);
}
}

async function getInfoFromUserInput(): Promise<UserInput> {
// fetch user inputs like username, email and phoneNumber
}
```
</Block>
<Block name="JavaScript">

```javascript
import { Auth } from 'aws-amplify';

async function signInWithNewPassword() {
try {
const user = await Auth.signIn(username, password);
if (user.challengeName === 'NEW_PASSWORD_REQUIRED`) {
// Required attributes are OPTIONAL, but if they were configured
if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {
// Required attributes are OPTIONAL, but if they were configured
// you need to get these in addition to new password from UI inputs
const { requiredAttributes } = user.challengeParam;
// Example if email and phone_number were required attributes
const { username, email, phone_number } = getInfoFromUserInput();
const { email, phone_number, newPassword } = getInfoFromUserInput();

const loggedUser = await Auth.completeNewPassword(
user, // the Cognito User Object
newPassword, // the new password
// OPTIONAL, the required attributes
{
email,
phone_number
phone_number,
}
);
console.log(loggedUser)
console.log(loggedUser);
}
} catch (error) {
console.log('Error confirming sign in with new password', error);
}
}
```
</Block>
</BlockSwitcher>

For further examples of Authentication using MFA, custom challenges, or custom validation data for AWS Lambda Triggers, refer to the [advanced use cases](/lib/auth/mfa/q/platform/js/#advanced-use-cases).

Expand Down