Do you want to request a feature or report a bug?
Feature
What is the current behavior?
The forgotPassword() function sends code through SMS, if users phone number is verified.
What is the expected behavior?
I can choose whether to send the code through SMS or Email.
Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions?
Current version, all browsers
Hi @guanzo,
You can set your preference for where you would want to receive the verification code on your user pool in the Cognito console.
You need to go to the Cognito User Pool console for your pool, and on the left pane click on MFA and Verifications. Then untick Phone Number for "Do you want to require verification of emails or phone numbers?" and save your changes.
Let me know if this works for you.
My app provides the option to setup Multi Factor Authentication with SMS. If the user chooses to do that, they must verify their phone number. According to https://github.com/aws/amazon-cognito-identity-js/issues/464, if their phone number is verified, cognito will always send verification codes through SMS.
Unfortunately unticking the Phone Number box didn't fix it. Cognito will only send codes to email, if phone number is unverified.
The linked issue mentioned it was marked as a feature request, any update on that?
We have a HOC in aws-amplify-react package to handle MFA using TOTP token. You can find the details of setting it up here in the Authentication guide: https://github.com/aws/aws-amplify/blob/b516278bff53addf856ef71efa37a4cb1b4baa70/docs/media/authentication_guide.md under the Enabling MFA section.
This should ensure that SMS is not set as the default option for forgotPassword.
Can you try it out?
Regarding the issue you have referenced, it's added to our backlog.
+1
+1
Any update on this? We were told to move to Amplify from the old module, but there are so many fiddly little things like this.
This is an issue on the Cognito service teams backlog where phone number is the preferred method IF both are enabled. If you don鈥檛 have sms enabled mfa will actually use email with forgot password and everything else. How did you create your user pool? If you use the amplify cli and use the default setup you will actually get this functionality (just email) out of the box.
The issue where Cognito uses sms by default is something they are aware of and is part of their backlog as well. I don鈥檛 know where it is in priorities but I will pass this issue link along as an addition to the +1鈥檚 for their prioritizations.
@mlabieniec Thanks for the response. Assuming this is in their private backlog? It would be good to get some transparency for timeline purposes. Also, creating either in UI or CLI results in the same outcome.
Once you have selected 'email' & 'mobile', removing mobile does not change anything, you still receive 'resets' and 'signup verification codes' via SMS. Also, you need to create a pool with 'mobile' ticked in order to have MFA as 'Required' (I found out the hard way). In my mind, this is definitely a bug and should be pretty high in their backlog. Essentially, users cannot at this point in time verify their email.
@mlabieniec Any updates on this issue from the Cognito team?
Hey guys, any update on this request for feature? I'm working on a project where we need to verify both, email and phone, but we want to keep the email as the main way to send these codes.
Guys, in case some1 need it, as a workaround we verify the phone and in the same call we verify, when it is success we "unverify it" by setting the attribute back to "false" and keep the record of phone_verified in our database, that way, people continue receiving the forgotpassword request via email.
Any update on this? Would really like to send the MFA code via email for the forgot password feature.
For anyone tracking this, I'd recommend opening a post on the Cognito AWS Forum
Or opening a AWS Support ticket
@jordanranz I have tweeted AWSSupport a number of times, specifically about this issue and, unfortunately, I also found their paid ticket support to be fairly average.
If this was an open-source repository, completely understand, but we pay to use Cognito, we were told to stop using the old repository where this worked and, to boot, this is maintained by employees (on top of the community...), so I think that this being an issue for almost a year with zero transparency on what the Cognito team is doing to be _pretty_ poor form. Talk about an 8th seat at the table! 馃檮
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This is not resolved, I don't think it should be closed.
The use case i'm working on could do with this too. Any updates?
Any updates on this please? This is a show stopper for us!
@leceal Could you share how do you "unverify" phone number?
I tried to set phone_number_verified attribute to false and then calling updateUserAttributes. Unfortunately, the phone remained verified.
This is a super bad solution, but I don't see an alternative if you want to send emails to people who have verified phone numbers. This should be considered a bug and not a feature request.
Don't use this as-is, it's just proof of concept. We are leaning towards cutting cognito MFA completely in favor of a legitimate solution. Since this is making multiple API calls, if you leave the phone number un-verified due to a rate limit error or other unexpected error, the user will be completely locked out
```
async resetUserPassword() {
let ctx = this
let cognitoUser = await this.getCognitoUser()
let phoneVerified = false
cognitoUser.UserAttributes.forEach((attr) => {
if (attr.Name === 'phone_number_verified' && attr.Value === 'true') {
console.log('User phone is verified, need to use alternate logic for sending message')
phoneVerified = true
}
})
console.log('Performing admin password reset on ', this.event.pathParameters.email)
let params = {
Username: this.event.pathParameters.email,
UserPoolId: process.env.COGNITO_USER_POOL_ID
}
if (!phoneVerified) {
ctx.doPasswordReset(params)
.then((data) => {
response.statusCode = 200
console.log('cognito response', data)
console.log('response', response)
ctx.callback(null, response)
})
.catch((err) => {
response.statusCode = 500
response.body = JSON.stringify(err)
console.log('response', response)
ctx.callback(null, response)
})
} else {
// Ugly workaround for sending emails for MFA users
console.log('using mfa workaround to send email')
this.doSetMfaSettings(false)
.then(() => {
ctx.doPasswordReset(params)
.then((data) => {
ctx.doSetMfaSettings(true)
.then(() => {
response.statusCode = 200
console.log('cognito response', data)
console.log('response', response)
ctx.callback(null, response)
})
})
.catch((err) => {
response.statusCode = 500
response.body = JSON.stringify(err)
console.log('response', response)
ctx.callback(null, response)
})
})
}
}
doPasswordReset(params) {
let ctx = this
return new Promise((resolve, reject) => {
ctx.cognitoIdentityServiceProvider.adminResetUserPassword(params, (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
doSetMfaSettings(status) {
let ctx = this
let params = {
UserAttributes: [{
Name: 'phone_number_verified',
Value: status.toString()
}],
Username: this.event.pathParameters.email,
UserPoolId: process.env.COGNITO_USER_POOL_ID
}
return new Promise((resolve, reject) => {
ctx.cognitoIdentityServiceProvider.adminUpdateUserAttributes(params, (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
getCognitoUser() {
let ctx = this
let params = {
Username: this.event.pathParameters.email,
UserPoolId: process.env.COGNITO_USER_POOL_ID
}
return new Promise((resolve, reject) => {
ctx.cognitoIdentityServiceProvider.adminGetUser(params, function(err, data) {
if (err) reject(err)
resolve(data)
})
})
}
```
Turns out, we found a pretty good workaround for this. The custom auth flow is a reasonable way to handle switching the phone_number_verified flag before a forgot password.
We liked this workaround because the login endpoint self rate-limits, so malicious users can't abuse it to set flags too badly. We use the same flow to "pre-auth" password login attempts, so users stuck with phone_number_verified still get their codes before logging in.
The drawback is that users could potentially get around phone number verification, but we don't add the phone number without verifying it anyway, so it's not a problem for us.
Hello, The Cognito team has launched an update to support this:
Relevant doc: https://docs.aws.amazon.com/cognito/latest/developerguide/how-to-recover-a-user-account.html
Announcement on forum: https://forums.aws.amazon.com/ann.jspa?annID=7293
Please let us know if this does not solve your use case or you feel this issue should be reopened.
Nearly 2 years later, I'm pleasantly surprised by this update. Thank you.
@mlabieniec Thanks for the update. It's a bit of a shame that the team/s weren't able to communicate what was happening. Will you be able to provide API usage docs for this library soon?
Most helpful comment
@jordanranz I have tweeted AWSSupport a number of times, specifically about this issue and, unfortunately, I also found their paid ticket support to be fairly average.
If this was an open-source repository, completely understand, but we pay to use Cognito, we were told to stop using the old repository where this worked and, to boot, this is maintained by employees (on top of the community...), so I think that this being an issue for almost a year with zero transparency on what the Cognito team is doing to be _pretty_ poor form. Talk about an 8th seat at the table! 馃檮