Cognito custom flow sign-in sends a confirm code via email
Tags: cognito, aws, lambda, javascript
Published: 2024-03-29 08:54:46

Hi every one!!!

Emotional conversation between boss and employee
```
Boss: Do you know about Cognito?
Employee: I know a lot about it so what do you need?
Boss: I need to develop more on the login page about 2fa confirmation codes via email & email only, customers need it urgently.
Employee: I think Cognito has all the support so no need to worry. I talked to my boss about it and assured me that I could do everything.
Boss: Does it take a long time?
Employee: I'm a master at this so it'll be quick.
```
So then he discovered the flow login feature only supports mfa with TOTP & SMS

OMGGGGGGG ●█▀█▄ ●█▀█▄ ●█▀█▄ ●█▀█▄

Please read this article it will help you ＼ʕ •ᴥ•ʔ／

**AWS**
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html

**Flow basic**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azmayd24wqykjlc517ul.jpg)

**Prepare:**
> Cognito create user pool
> Create 3 lambda function: 2faDefine.js, 2faCreate.js, 2faVerify.js

-------------------

**Cognito user pool**
> Note: User pool ID & App client ID

1./ Tab User: create user
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scnt8mjlfy0aq9ecnjf7.png)

The newly created user has confirmation status is `Force change password`, now you need to run the script below to update `confirmation status` from `Force change password` to `Confirmed`.
```
aws cognito-idp admin-set-user-password --user-pool-id {user pool ID} --username {username} --password {password} --permanent 
```

2./ Tab Sign-up experience
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bycxnziel17w2si4ke4.png)

Add custom attributes `authChallenge`, so after saving it will automatically add the prefix `custom:`, ouput `custom:authChallenge`.

This custom attribute contains a confirmation code and expiration time information when the end user submits a login.

3./ Tab App integration
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1lt8w7docw5qsqtao2u.png)

You find `App client list`, so click `Client your app`.

> This custom attribute `custom:authChallenge` must have read and write permissions.

> Option `Authentication flow session duration` has a value equal to the expiration time of the confirm-code.

> Option `Authentication flows` has a value `ALLOW_ADMIN_USER_PASSWORD_AUTH, ALLOW_CUSTOM_AUTH, ALLOW_REFRESH_TOKEN_AUTH, ALLOW_USER_PASSWORD_AUTH, ALLOW_USER_SRP_AUTH`.

4./ Tab User pool properties
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgsx127pl15qe8i4kp45.png)

Add Lambda trigger with trigger type 
> Custom authentication

Custom authentication
> Choose `Define auth challenge` mapping to lambda function `2faDefine`.
> Choose `Create auth challenge` mapping to lambda function `2faCreate`.
> Choose `Verify auth challenge response` mapping to lambda function `2faVerify`.

-------------------


**Lambda deploy with code**
1./ Function 2faDefine
https://bitbucket.org/main-28/cognito-sign-in-confirm-code-via-email/src/main/2faDefine.js

2./ Function 2faCreate
https://bitbucket.org/main-28/cognito-sign-in-confirm-code-via-email/src/main/2faCreate.js

Tab Configuration > General configuration
> Change value of the option timeout up 5 minute because `nodemailer` send email not working.

Tab Configuration > Environment variables
> CUSTOM_ATTRIBUTES = custom:authChallenge
> EMAIL_FROM_ADDRESS = xxxxx@xxxxxxxxx.xxx
> USER_POOL_ID = xxxxxxxxx

3./ Function 2faVerify
https://bitbucket.org/main-28/cognito-sign-in-confirm-code-via-email/src/main/2faVerify.js

Tab Configuration > Environment variables
> CONFIRM_CODE_TIMEOUT = 15
> CUSTOM_ATTRIBUTES = custom:authChallenge

-------------------

**Frontend Angular**
- Libary `[amazon-cognito-identity-js](https://www.npmjs.com/package/amazon-cognito-identity-js)`, `[angular-code-input](https://www.npmjs.com/package/angular-code-input)`

- Git: https://bitbucket.org/main-28/cognito-sign-in-confirm-code-via-email/src/main/login.component.ts

> Form login: when the end user clicks submit, it will call the function `onSubmitLogin`.
> Form confirm code: when the end user enters the confirm-code, it will call the function `onCodeCompleted`.

-------------------

Note: 
> If you want to refactor code, make sure the code example works first.
> Please comment any issues you encounter and I will try to answer you.