Do you want to request a feature or report a bug?
reporting a bug
What is the current behavior?
Our cognito pools are set up so that users can log in with their email. We also utilize attribute verification so that once a user signs up, they will need to verify their email address. Where we get stuck is when a user needs to update their email address. We call updateAttributes and pass their email, which will then send the user a verification email with the confirmation code. There are however states where the user is unauthenticated and needs to verify email with the confirmation code. If they are in an unauthenticated state, they need to authenticate. However, cognito doesn't allow users to log back in with neither their old or new email address. Instead, they need to sign up for an account again. This is a huge issue for us since it leaves users in this limbo state.
What is the expected behavior?
The expected behavior would be for users to log in with the email address that has been verified in prior to attempting to change the email, which would then allow the user to verify the new email address.
Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions?
This has never worked
I entered the same issue against the old amazon-cognito-identity-js SDK:
Gap in change email flow when alias exclusively used for sign-in
Even though it's still open I think it got forgotten when the old SDK was retired. I can see how this happened since most of the issues were probably related to the old SDK, not the Cognito back-end. But it's really a Cognito back-end issue. Since there isn't a GitHub project for Cognito itself, the front-end is the only place to enter issues.
@clintfoster thanks for confirming I'm not crazy! Was really losing my sanity over this.
@yuntuowang what is the best way to communicate this to the backend team? I understand the security reasonings behind this, but definitely feels like a flaw in the overall design. I know it may take a while to get this fixed, but do you think it's worth documenting here for now: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html?
@danielgeri I'm having the same issue with the exception of one of your problems. I can change a user's email address, log out, and can now only log in with the new unverified email. The user is now unable to log in with the old email.
So where this personally has problems is say a user mistakenly enters the wrong email during the change email process, they are now locked out of their account if they sign out and don't remember their mis-entered email. Given that Cognito has no baked in account recovery or forgot username tools, the user is forced to contact a system admin to fix the issue.
It seems to me that Cognito shouldn't be updating the user's email/phone until _after_ the verification process has happened. It would seem to solve both of our issues, provide a more secure system, and not be all that confusing for a user to figure out.
@sloansparger sorry to hear :( Your scenario seems super odd since that is a major security flaw. Regardless of the mechanics of the issue I would recommend the following:
@danielgeri Interesting idea, I'm going to look into option 2 until we hear some feedback from the Cognito team. Thanks 馃憤
@sloansparger np! if you end up implementing, can you let us know how it goes? I am super curious to see if it's a viable workaround
@danielgeri Unfortunately this doesn't seem to work as I'm getting this error: { code: "InvalidParameterException", name: "InvalidParameterException", message: "Invalid email address format." }.
After a little digging, this page in the docs seem to explain why:
If email is selected as an alias, a username cannot match a valid email format. Similarly, if phone number is selected as an alias, a username that matches a valid phone number pattern is not accepted by the service for that user pool.
Using the aliases in Cognito user pool, only a verified email can sign in. Unfortunately, updating email removes the old verified email and leave the new email not verified. I want to keep the old email in preferred username to continue login before new email verified, but got above error @sloansparger mentioned. As @danielgeri said, which leaves users in a limbo state. Really hope the Cognito team can give an update about this issue.
Also experiencing this issue. Cognito, please advise.
Experiencing the same issue. Is there any solution for this case?
I ended up leaving this issue for my application. However, I supposed you could build your own email verification for the change email (don't change email when users submits to change, instead pass it to your own system). Send them a custom made verification link to the new email and let them verify. Once they click the link your API will need manually update their email using the CognitoIdentityServiceProvider.adminUpdateUserAttributes method in the aws-sdk package. Obviously a load of added work to get around this, but pretty sure this would work.
Is there any update on that issue?
Has anyone opened up this issue with the Cognito service center support?
@daneprime8 @lazharichir We ended up building our own email verification process.
@jordanranz I have not. I've had other core cognito issues (not related to aws amplify) and don't know where to go to reach out to the core cognito team. Mind advising on how to approach this (i.e. where is the cognito service support center)?
@danielgeri I think you'd start on the Cognito forum page.
or submit a claim by opening a case in the AWS Support Center
Also experiencing this, please respond Cognito.
I dug into this a bit more and here's what I decided to do in case it's helpful for anyone else. My Cognito is set up so that email is considered the username.
Currently, a user can sign up for a new account which requires them to confirm their email. This sets their account status to CONFIRMED and email verified to true. However, the flaw is that afterwards the user can then change their email but then not verify that email and technically still be considered an authenticated user and sign in freely. Their account status is still CONFIRMED but email verified is false.
What if the email they changed to was inputted incorrectly? Also, for security reasons I don't want any accounts where users haven't verified their email since my app deals with a lot of personal data.
Ideally, Cognito wouldn't change a user's actual email until it's been verified.
This is what I ended up doing:
Auth.currentAuthenticatedUser(). Otherwise, it'll show the old email. Also, I wasn't able to figure out based on the Auth API how to refresh the user other than signing them out and back in.email_verified attributes. If it's set to false, I put them into an email confirmation flow similar to sign up and prevent them from logging in. Previously, even if email_verified was false Cognito would still sign you in.It's not 100% perfect, but working within the constraints of Cognito it solves some of the issues. Would love to hear what others think.
Any news? I am experiencing the same problem. Users can change their email address without confirming it, and then log in using the new email address without it ever having been verified.
Kind of ridiculous this issue has been open for almost a year and no response from Cognito/Amplify team...I am also curious about this.
After using Cognito for a couple of years now and finding it to be reliable and well-designed overall, I would say this is one of the biggest problems with it, bordering on rendering the email alias feature unusable for production. Although it's a serious issue that is certain to leave some percentage of users locked out of their accounts, unless you've dealt with it first-hand, it's hard to describe in a way that really brings home what's happening. I did my best in my description here almost 2 years ago (now archived). At that time it was acknowledged as a "service issue" (meaning it's happening in the cloud, not the client SDK) and marked as a "feature request". Meanwhile, the GitHub issue got archived when the Cognito JS SDK was replaced with Amplify. So the SDK team has apparently washed their hands of it, and it's unclear how to get the service team to look at it.
I assume Amazon isn't "dog-fooding" Cognito since they already had a user management facility before it existed. If they were, this problem would have been addressed by now since dealing with angry users who have been locked out of their accounts has a way of making you look more carefully at an issue that might be hard to describe, but is clearly capable of happening to real users.
@Susan123456789 @cameronb23 @clintfoster the Amplify team responded but it might have not been clear that @jordanranz is a member of the team. As he and others stated this is a request for the Cognito service team and something that Amplify client libraries or tooling are unable to resolve.
For clarity Amplify is an Open Source project for development of mobile and web applications and not run by the Cognito team or any specific AWS service team. We have raised this to their attention internally, however we do recommend you post feedback directly to that team via official channels, either using your support account or the Cognito forums.
I'm also experiencing the issue of having _blocked_ users when they update their email and logout before validating the new email with the verification code.
In addition to that, I'm facing another dangerous behavior with email updates. A user is able to change his email to an email that is already linked to another account without cognito returning an error. I don't know what is the exact state of the cognito database resulting to this action but it seems that the latter account is replaced by the one "stealing" its email address.
The expected behavior would be cognito returning an error such as "email already in use" when a user try to change its email address to an email address of an existing account.
@sChupin There's a discussion about the email capturing behavior here (unrelated to this issue).
Experiencing the same issue, as an already confirmed account email address can be updated via user attributes and even though the verification code is sent via email, no verification is required prior to start using the new email address.
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.
not stale
not stale
Per the following response to my original report against the old Cognito SDK, this is a known service-side issue. If someone at AWS is reading this would it be possible to check on that issue...?
https://github.com/amazon-archives/amazon-cognito-identity-js/issues/515#issuecomment-350145613
If you follow my steps 1, 2, 3 in the original report you can reproduce the problem. It's hard to get the gist of it just reading the descriptions.
The goal is keeping the attributes unchanged until they are verified. In my case there is a sign in with phone number only and users can update their phone number and logout without verifying.
If anyone is interested here is how I did it STEP BY STEP --->
I introduce another attribute (called custom:validated_phone) and a cognito custom message lambda trigger for CustomMessage_UpdateUserAttribute
When user wants to update their phone number client sends the current (already validated
) phone number in custom:validated_phone in updateUserAttributes function.
const result = await Auth.updateUserAttributes(cognitoUser, {
phone_number: NEW_PHONE_NUMBER,
'custom:validated_phone': CURRENTLY_VALIDATED_OLD_NUMBER,
});
So cognito changes the phone_number attribute with the new one. This is something I dont want, because it isn't validated yet
Here comes the sneaky trick. Before cognito sends user a verification code it triggers a lambda to customize the message. In this lambda I look at the attribute custom:validated_phone and as an admin I update phone_number attribute back to original one (validated one). So until there is verified phone number the old one will be the still only one the in the system
if (event.triggerSource === 'CustomMessage_UpdateUserAttribute') {
const validated_number = event.request.userAttributes['custom:validated_phone'];
const params: AdminUpdateUserAttributesRequest = {
UserAttributes: [
{
Name: 'phone_number_verified',
Value: 'true',
},
{
Name: 'phone_number',
Value: validated_number,
},
],
UserPoolId: event.userPoolId,
Username: event.userName,
};
const result = await cognitoIdServiceProvider.adminUpdateUserAttributes(params).promise();
if (validated_number === event.request.userAttributes.phone_number) {
throw new Error('failed to prevent sending unnecessary verification code');
}
}
After STEP 2 user still gets a verification code to his new number. The client then verifies the code. If the verification is successful then this time I again call updateUserAttributes with new number as custom:validated_phone. Because its now verified
const result = await Auth.verifyUserAttributeSubmit(cognitoUser, 'phone_number', code);
if (result === 'SUCCESS') {
const result2 = await Auth.updateUserAttributes(cognitoUser, {
phone_number: NEW_PHONE_NUMBER,
'custom:validated_phone': NEW_PHONE_NUMBER,
});
}
Now again my lambda trigger but this time both attributes are equal to each other, therefore after updating this real phone_number attribute I fail lambda intentionally so another verification code isn't sent again
if (validated_number === event.request.userAttributes.phone_number) {
throw new Error('failed to prevent sending unnecessary verification code');
}
I know its tricky but much better than setting up your own verification method with DynamoDB etc... Hope it helps.
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 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 isn't stale. I would like to mark amplify-js as stale since there are few issues most people suffer for literally years and still no improvement.
Could someone on the Cognito team try reproducing this with the three steps I outlined in the same issue against the original Cognito JS SDK almost two years ago...?
Gap in change email flow when alias exclusively used for sign-in
You have to wait until the verification code expires to see it (step 2). But this is a scenario that commonly happens with real users. They get distracted and they don't enter the code right away. Then they are _locked out_ because they cannot sign in with their old email alias, nor can they sign in with the new one.
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.
Hi all,
I'm on the Cognito team and apologize that we haven't commented on this thread sooner. We have been hearing the feedback. Lots of points to touch on here.
As you may know, there are two basic ways to allow users to sign in with an email address with Cognito User Pools. The originally supported way involved requiring separate usernames and email addresses for users, and once the email address was verified, it could be used in place of the username for signing in the user. In the Cognito Console on the Attributes tab, this approach is described as "Username - Users can use a username and optionally multiple alternatives to sign up and sign in." One of the issues with that method (as clintfoster did describe) is that users can no longer sign in via email if they change their email and don't verify it. They can still sign in by username, but users may not know their username. The crux here is that email addresses can only be used to sign in once they have been verified. We built it that way so someone else cannot claim an email address that does not belong to them. They can create an account entering someone else's email address, but they won't be able to sign in with it, and it won't prevent the real email owner from creating an account and verifying and then using his/her email address.
Due to that issue with changed but unverified email addresses, and because often there is no need for a separate username, we added a second approach for signing in via email (or phone number). With this second approach, you don't use separate usernames and email addresses, and instead you provide the email address as the username, and Cognito uses it as an email address. In the Cognito Console on the Attributes tab, this approach is described as "Email address or phone number - Users can use an email address or phone number as their "username" to sign up and sign in." With this approach users can still sign in with their email address after they have changed it even if it has not been verified.
Some description of these two approaches in here in the Cognito User Guide.
We also recognize that, as has also been called out, it would be an improvement to not change the email address until after it is verified. We do have that on a list of issues to address, but I don't have any timing I can share.
Lastly, I want to clarify the distinction between account confirmation and email/phone verification. When a user first signs up, account confirmation and email verification typically happen at the same time, unless you have a Lambda trigger customizing the behavior. That is, when users first verify an email (or phone), their account is confirmed at the same time that the email (or phone) is marked as verified. When users change their email or phone, their email/phone is marked as not verified, but their account stays confirmed. Thus they can still sign in if they know the right credentials, e.g., a separate username and their password.
I hope all that helps explain the situation. Thanks for the questions and feedback.
Regards,
Tim
Finally solved this issue with a sneaky workaround and only few lines of code !! 馃帀馃帀
The goal is keeping the attributes unchanged until they are verified. In my case there is a sign in with phone number only and users can update their phone number and logout without verifying.
If anyone is interested here is how I did it STEP BY STEP --->
STEP 0: Custom attribute and lambda trigger for Custom Message
I introduce another attribute (called
custom:validated_phone) and a cognito custom message lambda trigger forCustomMessage_UpdateUserAttributeSTEP 1: Updating user attributes with new phone number
When user wants to update their phone number client sends the current (already validated
) phone number incustom:validated_phoneinupdateUserAttributesfunction.const result = await Auth.updateUserAttributes(cognitoUser, { phone_number: NEW_PHONE_NUMBER, 'custom:validated_phone': CURRENTLY_VALIDATED_OLD_NUMBER, });So cognito changes the
phone_numberattribute with the new one. This is something I dont want, because it isn't validated yetHere comes the sneaky trick. Before cognito sends user a verification code it triggers a lambda to customize the message. In this lambda I look at the attribute
custom:validated_phoneand as an admin I update phone_number attribute back to original one (validated one). So until there is verified phone number the old one will be the still only one the in the systemif (event.triggerSource === 'CustomMessage_UpdateUserAttribute') { const validated_number = event.request.userAttributes['custom:validated_phone']; const params: AdminUpdateUserAttributesRequest = { UserAttributes: [ { Name: 'phone_number_verified', Value: 'true', }, { Name: 'phone_number', Value: validated_number, }, ], UserPoolId: event.userPoolId, Username: event.userName, }; const result = await cognitoIdServiceProvider.adminUpdateUserAttributes(params).promise(); if (validated_number === event.request.userAttributes.phone_number) { throw new Error('failed to prevent sending unnecessary verification code'); } }STEP 2: Verifying new phone number
After STEP 2 user still gets a verification code to his new number. The client then verifies the code. If the verification is successful then this time I again call
updateUserAttributeswith new number ascustom:validated_phone. Because its now verifiedconst result = await Auth.verifyUserAttributeSubmit(cognitoUser, 'phone_number', code); if (result === 'SUCCESS') { const result2 = await Auth.updateUserAttributes(cognitoUser, { phone_number: NEW_PHONE_NUMBER, 'custom:validated_phone': NEW_PHONE_NUMBER, }); }Now again my lambda trigger but this time both attributes are equal to each other, therefore after updating this real phone_number attribute I fail lambda intentionally so another verification code isn't sent again
if (validated_number === event.request.userAttributes.phone_number) { throw new Error('failed to prevent sending unnecessary verification code'); }Conclusion:
I know its tricky but much better than setting up your own verification method with DynamoDB etc... Hope it helps.
Thanks a lot for this trick. It's really helpful. We need to verify both email and phone number. I am not sure if we can do this trick for both email and phone number simultaneously as in custom lambda message trigger, we won't know if email is being updated or phone number. Or probably we throw exception when all new/old numbers match.
Also, I believe we can not implement Resend Verification code in this case as the actual attribute never gets changed? What can we do to make it work?
Got answers:
1) In case of email and phone number both need verification, throw exception when all new and old phone number and email matches
2) For Resend Verification, call UpdateUserAttribute again
Our solution was to capture email address changes as they happen and then delete and recreate the user with the new email address, therefore forcing them to verify their new email address. It seems like a silly workaround, but it was probably the most straightforward.
On another note, it seems to me that this issue shouldn't even be an issue long past its discovery (in this case 2 years+) and should be a fundamental part of the flow.
It's absolutely crazy to me that a company as large as Amazon is unable to find the resources to fix what seems to be a pretty large flaw in their auth 'solution'... 馃槙
As @clintfoster said earlier, this borders on rendering the email as username feature unusable.
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.
not stale
Cognito team or I rather say zombie team, any updates on this? i think it will be very easy to fix.
Also i think you should add a paragraph to your cognito getting started guide and name it 1000 reasons why cognito will not suit your business use case and maybe a warning: We are usually not fixing issues, use it at your own risk.
cc @timwhunt
We ended up with our own implementation.
@Can-Sahin
In the solution you describe, what's to stop a user from scripting a call themselves like so:
const result = await Auth.updateUserAttributes(cognitoUser, {
phone_number: GARBAGE_PHONE_NUMBER,
'custom:validated_phone': NEW_PHONE_NUMBER_I_WANT_BUT_CANT_VERIFY,
});
If I'm reading correctly, the custom message handler will drop that NEW_PHONE_NUMBER_I_WANT_BUT_CANT_VERIFY in the phone number field, and mark it verified. Does this allow users to get around verification?
I think you're right @mfogel, the solution @Can-Sahin proposed opens a way for a user to set any phone number as verified without actually verifying it. However, this is the only working work-around that I've found so maybe we just have to accept this security hole to be able to offer users a consistent way to verify a new phone / email.
Really hoping AWS to change the behavior so that changing phone/email attribute is postponed until it's really verified 馃檹 馃檹
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.
How about we don't call this one stale until we hear some real answers?
Just started using Cognito and ran into this problem. It's crazy that this problem has gone unfixed for nearly 2 years. I ended up having to prevent users from changing their emails to avoid security holes.
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.
not stale
For those who don't yet have their user pool in production this comment from Cognito team member @timwhunt last fall may be helpful: https://github.com/aws-amplify/amplify-js/issues/987#issuecomment-531025897
Unfortunately we have a user pool that was created the "old way" with email aliases, rather than the new technique where the email address is literally the username. I would be curious to hear how this is working out for anyone who has tried it. I'd also love to hear any ideas for migrating an existing pool.
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.
/// Looks like there isn't a condition YET to break the loop :(
while(true) {
notStale();
}
New to using Cognito / Amplify and ran into this issue as well.
Nothing new on my part to add to the discussion, just wanted to show the Cognito team that we're many facing this issue.
This can be done by using two steps (I've used lambda functions). You can send a code and then set the email back to the original email until the code is confirmed.
I've put some example code here:
@jordizle Good write up, but the problem isn't that this issue can't be worked around.
(In my opinion) plenty of the people who have commented here will be able to work around it without much help... fundamentally the problem is that the service shouldn't have such a glaring issue it in that has been open for 2 years now with no solid resolution.
Any number of work arounds exist to fix the problem as well, the problem you create in doing so is that that (for example at a larger corporate company) these workarounds become hidden knowledge to other developers and hidden knowledge of a problem is inevitably prone to create issues down the road for implementations or be lost with staff turnover and then no one can maintain it. There's also the additional problem that workarounds can be extremely flaky and small changes to the Cognito could render then inoperative or completely broken with no notice.
It is unbelievably frustrating that something like this can be left unaddressed for such a long time in such a core AWS product - additionally without it being documented, closed or fixed officially by the AWS team.
Zombie Team,
Here is a simple solution to this issue, introduce UpdateAfterVerification parameter to update_user_attributes(...) with "False" as default value for backward compatibility.
And when set to "True" you should just send the email with verification code. and during verify_user_attribute(...) you can update the attribute if verification succeeded.
response = client.update_user_attributes(
UserAttributes=[
{
'Name': 'email',
'Value': '[email protected]',
},
],
UpdateAfterVerification='True',
AccessToken='token==',
)
Hi team. Do you have any idea of solute this problem?
Changing the email address is important to us as it is a basic user management system. Is there another way to safely change my email address?
If you have the ability to do so, I would go with user pool Option 2, as described here in this same issue by Cognito team member @timwhunt last fall.
As Tim described, the Cognito team solved this problem (sort of) by allowing the username to literally be the email address (instead of having a separate username with an email "alias"). Per the Cognito docs, when you set up a new user pool there are now two choices:
Having said that, as many here have pointed out, there is a straightforward service-side fix for Option 1. Tim alluded to this as well:
We also recognize that, as has also been called out, it would be an improvement to not change the email address until after it is verified. We do have that on a list of issues to address, but I don't have any timing I can share.
AWS should implement this fix if Option 1 is still supported. They should also consider those of us who have deployed large user pools with active customers who cannot easily migrate to Option 2 without requiring all users to create new accounts. The number of people still chiming in here after almost 3 years is surely sufficient evidence that this is a significant problem.
It seems doubtful that AWS is working on this, but It's hard to know since the service component of Cognito does not have a GitHub project where discussion can take place. Everyone is talking about it here because it's the only option.
For reference, here is the old issue that was archived when the old Cognito JS SDK was deprecated.
@clintfoster
Thank you for your advice. I'll consider to use user name instead of email address.
@clintfoster
It depends on the use case and what you want the user to sign in with.
I still prefer user pools with aliases and i'm not willing to use user pool with usernames even even for fresh user pool because the users can sign in with their verified email and verified phone number and preferred username.
We can't have this luxury when using user pools with usernames.
I think AWS should fix this as soon as possible, Cognito is a good service, i just don't know why AWS does not fix Cognito issues.
They just say we are aware of the issue and is in our roadmap, three years later the issue still not fixed.
Urgh what roadmap you are referring to? you are doing no effort to fix issues. this is really frustrating.
@kodless Good point. Modern apps should allow signing in with either phone number or email, which you can only do with Option 1. For example, I heard the author of whatsapp say one of the keys to its viral growth was allowing people to sign up & sign in by phone number.
If you have the ability to do so, I would go with user pool Option 2, as described here in this same issue by Cognito team member @timwhunt last fall.
As Tim described, the Cognito team solved this problem (sort of) by allowing the username to literally be the email address (instead of having a separate username with an email "alias"). Per the Cognito docs, when you set up a new user pool there are now two choices:
- Option 1 (original way): Email as sign-in _alias_: With this option the username _cannot_ be an email address. But the email address can be used as an alias for sign-in, once verified. As many people have found after they go to production (sadly), this option will cause some users to be locked out when they change their email address and do not verify it in time. It has no straightforward solution (though many hacks have been discussed in this thread over the years).
- Option 2 (new way): Email as username When signing up, the user is literally allowed to specify their email address as their username. If you did not choose this option when creating your user pool, you're stuck with the hacks for Option 1 unless you have the luxury of re-creating your user pool from scratch and choosing Option 2.
Having said that, as many here have pointed out, there is a straightforward service-side fix for Option 1. Tim alluded to this as well:
We also recognize that, as has also been called out, it would be an improvement to not change the email address until after it is verified. We do have that on a list of issues to address, but I don't have any timing I can share.
AWS should implement this fix if Option 1 is still supported. They should also consider those of us who have deployed large user pools with active customers who cannot easily migrate to Option 2 without requiring all users to create new accounts. The number of people still chiming in here after almost 3 years is surely sufficient evidence that this is a significant problem.
It seems doubtful that AWS is working on this, but It's hard to know since the service component of Cognito does not have a GitHub project where discussion can take place. Everyone is talking about it here because it's the only option.
For reference, here is the old issue that was archived when the old Cognito JS SDK was deprecated.
Is the below what Option 2 looks like? If so, we're still haing the same issue:

@jiwabob If you're still having the issue with Option 2, I wonder if it's a different problem?
Consider this Option 1 example:
NedFlanders (or could be something like a generated UUID)[email protected]To reproduce the specific problem described here, you would change the email address and fail to confirm it in time. Now you can't sign in with either the old or new email _alias_. However, you can still sign in with the username, assuming you know it.
With Option 2 the username actually is the email address. I haven't tried it since we're stuck with Option 1, but are you saying with Option 2 if you change your username/email and don't confirm it, neither the old or new email can be used for sign-in?
@clintfoster What we've seen is that if the user changes their email address (which IS the username as you say), but doesn't confirm it, their email is updated, and they are able to log in with the new email address regardless of the new email's confirmation status. This becomes an issue if the user entered the _wrong_ email address, as they would no longer be able to log in. What I believe should happen is that until the user verifies the new email address, the email address is NOT updated (when Option 2 anyway, where the email address is the username).
@jiwabob If I'm understanding correctly there seems to be a pattern here with both Option 1 (email is _alias_ for username) and Option 2 (email _is_ username): Allowing an email address change to proceed in any way on the service side before the user has confirmed it is a bad idea. This harkens back to my earlier quote from @timwhunt:
We also recognize that, as has also been called out, it would be an improvement to not change the email address until after it is verified. We do have that on a list of issues to address, but I don't have any timing I can share.
Thinking like a programmer, I'm guessing the original service implementation never fully accounted for an intermediate state before the email or phone is confirmed. Doing it properly would require an additional field in the DB to store both the old and new values. I don't see this issue being properly solved until the service team undertakes the necessary foundational work.
It must be frustrating for the client SDK team to see all the appeals here since there apparently isn't much they can do to get the service team to look at long-standing problems with large volumes of ongoing activity from many different customers spanning all SDKs.
Same issue as @jiwabob.
This would be very confusing for any user to experience.
The solution as in the quote posted from @clintfoster would be to have the email attribute updated only after it was verified.
Can we get any update on the status
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.
not stale
Not stale...
Allowing a user to change their email address, .esp when their email address is used for sign in, without first confirming the address, seems to me to be a major security flaw. I could be wrong.
At present, a user, if logged on, can change their email address, using Auth.updateUserAttributes, if given the opportunity in the client, after which, there is no control as to whether or not that email address can login or not based on whether or not it as been confirmed.
I've written code to allow the user to input the verification code that gets sent by cognito, so as to verify the email address, but it doesn't matter if the user can log in when the email_verified attribute is false.
It's not token related either, as I've waited an hour for tokens to expire.
Problem: the user can log in, with the new email, when email_verified === false in the user pool.
While this can be programmed around, client-side, I would rather rely on Cognito to prevent this behavior in the first place, as it is inherently insecure.
Prove me wrong, so that we can get a good solution here, please.
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.
LoL 656 issues are open right now and stale bot is a nice way to get away from the things they ignore
not stale!
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.
NOT STALE
Not Stale!
@AdamiHamza thanks for mentioning the UpdateAfterVerification trick.
I am struggling to understand how that parameter can be passed to Amplify's
Auth.updateUserAttributes()
(Python dev here)
Any hints? Thanks and apologies in advance for the dumb question!
@marcelloromani I think that it was just an example to show how to resolve the problem to the Cognito team, I don't think that UpdateAfterVerification exists.
Still waiting for the fix :(
Following up with the Cognito service team. Thank you everyone for your patience!
Thanks for the feedback on this everyone. As @harrysolovay has mentioned above, we are raising this to the Amazon Cognito team internally. As others have called out above, we, Amplify are an Open Source project for development of mobile and web applications and not run by the Amazon Cognito team or any specific AWS service team. Can anyone provide the AWS Forums post for this issue? In the meantime, we will provide an update on this once we have one from the service team. Thanks!
Most helpful comment
Finally solved this issue with a sneaky workaround and only few lines of code !! 馃帀馃帀
The goal is keeping the attributes unchanged until they are verified. In my case there is a sign in with phone number only and users can update their phone number and logout without verifying.
If anyone is interested here is how I did it STEP BY STEP --->
STEP 0: Custom attribute and lambda trigger for Custom Message
I introduce another attribute (called
custom:validated_phone) and a cognito custom message lambda trigger forCustomMessage_UpdateUserAttributeSTEP 1: Updating user attributes with new phone number
When user wants to update their phone number client sends the current (already validated
) phone number in
custom:validated_phoneinupdateUserAttributesfunction.So cognito changes the
phone_numberattribute with the new one. This is something I dont want, because it isn't validated yetHere comes the sneaky trick. Before cognito sends user a verification code it triggers a lambda to customize the message. In this lambda I look at the attribute
custom:validated_phoneand as an admin I update phone_number attribute back to original one (validated one). So until there is verified phone number the old one will be the still only one the in the systemSTEP 2: Verifying new phone number
After STEP 2 user still gets a verification code to his new number. The client then verifies the code. If the verification is successful then this time I again call
updateUserAttributeswith new number ascustom:validated_phone. Because its now verifiedNow again my lambda trigger but this time both attributes are equal to each other, therefore after updating this real phone_number attribute I fail lambda intentionally so another verification code isn't sent again
Conclusion:
I know its tricky but much better than setting up your own verification method with DynamoDB etc... Hope it helps.