Resending phone_number attribute verification code in AWS Cognito - amazon-web-services

Is there a way in AWS SDK CognitoIdentityServiceProvider to resend a phone_number attribute change verification code for a CONFIRMED user?
I have set phone_number attribute to be verified in Cognito. adminUpdateUserAttributes() sends the verification code. But I have failed to find a way of resending the verification code. This is a necessity in the use case i am working on.
So far I have tried doing a adminUpdateUserAttributes() with the same phone number. It doesn't seem like it resend the verification code. With a new number, it does.
I cant do a deleteUserAttributes() and an update again, as the pool configuration sets the phone number as required.
Not sure if its relevant; but note that I have to pretty much use the CognitoIdentityServiceProvider admin APIs as Sign UP is also disabled in the User pool.
To sum it up, I am looking for a solution where I can resend the verification code for phone_number attribute in a confirmed user in Cognito User Pool.

This is the method in AWS Api reference that resends OTP code for this flow:
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUserAttributeVerificationCode.html
Then in my service, using AWS Java SDK, I call it:
public void resendCodeAttributeVerification(String accessToken) {
cognitoClient.getUserAttributeVerificationCode(new GetUserAttributeVerificationCodeRequest()
.withAttributeName(PHONE_NUMBER)
.withAccessToken(accessToken));
}

Related

Custom phone verification in AWS Cognito?

AWS Cognito SDK provides two methods:
GetUserAttributeVerificationCode
VerifyUserAttribute
The first one generates a 4-digit code for the provided attribute (email or phone) and the second one verifies the provided attribute with the provided code.
I want to use my own service for sending SMS verification codes. Unfortunately, AWS doesn't seem to provide an API, where I can manually set a 4-digit code on a cognito user awaiting confirmation inside something like a custom attribute phone_code_verification and then call VerifyUserAttribute to verify that code.
Is there a way to achieve this ?
Also, AWS Cognito throws LimitExceededException, TooManyRequestsException and other useful errors, so I would like the proposed method to be wrapped in the same AWS logic and not have to implement rate limit or request limits myself.

AWS Cognito sign up without password to get email confirmation link

I want to make a simple flow for registration app.
User sign up with only email -> The verification/registration link is sent to the email -> People register (putting in their password) on that link
I've googled anything but haven't found any way to make it with AWS Cognito.
Looks like Cognito is forcing users to sign up with at least email AND password to get the confirmation link
You can sign up users with adminCreateUser API call. They will receive an email with temporary passwords. This approach is configurable.
See: https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminCreateUser.html
Use: AdminCreateUser
Create a new user profile by using the AWS Management Console or by calling the AdminCreateUser API. Specify the temporary password(will be your user's password) or allow Amazon Cognito to automatically generate one.
Specify whether provided email addresses and phone numbers are marked as verified for new users.
Specify custom SMS and email invitation messages for new users via the AWS Management Console.
Specify whether invitation messages are sent via SMS, email, or both.
After successful user creation,
1. authenticate user using same user credentials
Use: SDK calls InitiateAuth(Username, USER_SRP_AUTH)
2. After success of initateAuth, amazon Cognito returns the PASSWORD_VERIFIER challenge with Salt & Secret block.
3. Use RespondToAuthChallenge(Username, <SRP variables>, PASSWORD_VERIFIER
4. Amazon Cognito returns the NEW_PASSWORD_REQUIRED challenge along with the current and required attributes.
5. The user is prompted and enters a new password and any missing values for required attributes.
6. Call RespondToAuthChallenge(Username, <New password>, <User attributes>).
7. After successful password change user can be able to login using same credentials added by you.
Short answer
- In that case, you can specify the temporary password(will allow Amazon Cognito to automatically generate one.).
- all user users will be forced to change their password only at first login.

AWS Cognito - run another lambda after migration lambda has run

Cognito has a migration lambda that allows us to confirm a user in our db. They send the email and PW to Cognito, the lambda fires, we verify matches, and the user is entered into Cognito.
At this point - behind the scenes - Cognito generates a username of some kind (UUID). The problem is, I need a way to get this username into our existing database, because our systems going forward will no longer rely on email and instead rely on this username.
Ideal flow:
Sign In
Migration Succeeds
Cognito generates username
Username is sent to our server.
Now because we have email set to auto-verified, no post-confirmation lambda can be called. The only way I see to do this with Cognito as-is is to either:
Ask users who already exist in our system to confirm their email again. This is a non-starter
Create a post-auth lambda, check user login count through a custom attribute, and if 0 (or if not already registered with the service, etc.) migrate the username to the new service.
If there is any other way to do this, please let me know.
After the user migration lambda is called your pre sign-up lambda will be called, assuming you have implemented it. The parameters received by your lambda will include username with the value being the UID you referenced. Parameters will also include user attributes containing email. You can use this information to update your database.
I did not want to add the PreSignup trigger, its a complicated way of doing it if you already rely on PostConfirmation, and if the majority of new users won't be migrations. My use case has a frontend initiate the signup process as well, which I use here.
Instead, I set a Cognito attribute on the new user during the UserMigration trigger. It could be 'user_migration': <oldUserSub>, or however you want to mark it. Just make sure you allow this property within the Cognito user pool settings.
When the UserMigration trigger returns, this information is now accessible through verifying the IdToken, or found in the JWT on the frontend if you're using that. So, when the user is migrated into Cognito and the response gets back to the Cognito client on the frontend, I can now recognize this user needs to be migrated into my personal database. Seeing this, I'll call a new endpoint on my backend to handle this. This new endpoint does exactly what PostConfirmation would typically do.
Then just delete the 'user_migration' property from the Cognito user, return the new user data to the frontend and everything should be set up.
You can use Pre sign-up trigger. In order to detect if the trigger event came from your migration trigger, you can check at the trigger_source value from the event object. In my case (i'm using migration trigger) the value is PreSignUp_AdminCreateUser. By knowing the value of trigger_source you can differentiate if it was migrated or regular user. You can also check the user attributes to know whether the email or phone is verified or not.
Here's my sample code on python:
def lambda_handler(event, context):
trigger_source = event.get('triggerSource')
user_attributes = request.get('userAttributes')
email_verified = user_attributes.get('email_verified')
if trigger_source == 'PreSignUp_AdminCreateUser' and email_verified == 'true':
# create user on db

AWS Cognito - resendConfirmationCode 'User is already confirmed.'

We have a scenario where a user forgets their username or password and can click on a 'Forgot password' link, receiving a confirmation code in an SMS (via Cognito's ForgotPassword).
If, for some reason, the user doesn't receive the SMS, they can click on 'Resend code' link which will execute Cognito's ResendConfirmationCode.
The result from the POST request is a 400 containing the following:
{"__type":"InvalidParameterException","message":"User is already confirmed."}
How can the user be confirmed when they have requested their confirmation code? Any clarification into the cause of this issue would be much appreciated.
Not sure if this is the best approach, but managed to get another SMS sent to Cognito user by simply resubmitting ForgotPassword instead of using ResendConfirmationCode.

AWS Cognito - Confirmation Code not received

I created an user pool with AWS Cognito. It works good but many email servers (providers like FreeTelecom our Orange in France) never received the Confirmation Code (in order to validate an email address and activate a user account). I found nothing in the AWS Documentation. Please someone could help me ?
Image url:
Please do find the image url and open it for reference.
While creating your user pool you have to enable MFA (Multi-Factor Authentication) on aws console.
Do verify 1. whether you have Marked MFA as required field. 2.Which second factors do you want to enable? Enable an option OTP or SMS 3.Do you want to require verification of emails or phone numbers? Check the field both Email and Phone Number