Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cognito: cannot verify Email with link after update(userAttribute) #1017

Closed
mohaalsouli opened this issue Jan 13, 2021 · 19 comments
Closed

Cognito: cannot verify Email with link after update(userAttribute) #1017

mohaalsouli opened this issue Jan 13, 2021 · 19 comments
Labels
auth Issues related to the Auth category feature-request Request a new feature

Comments

@mohaalsouli
Copy link

Hi,

Background: we have a User Pool set up to verify the users both phone numbers and emails. The SMS template for phone number verification is the default template, while the email template is set to send a Link, instead of a Code. This seems fine following the documentation.

The problem: in our mobile app, when we sign up a user for the first time, we sign them up with the phone number only at first which triggers Cognito to send an SMS with the verification code. The app then captures the code and verifies it with Cognito. Once verified, the app then signs the user in and asks them for their email address and name. We send those to Cognito using the updateAttribute() function. This update triggers Email verification but we receive a code in the email instead of the expected link configured in the User Pool's templates.

Upon further digging, we suspect that this behaviour is due to the API unconditionally calling the confirmAttributeWithCode function or specifically the GetUserAttributeVerificationCode() API.
So, whether this is a bug or a missing feature, could you please suggest a solution or add support to verifying emails with a link upon calling the updateAttribute() function?

Thank you.

@wooj2
Copy link
Contributor

wooj2 commented Jan 13, 2021

Hi @mohaalsouli ,

Thanks for reaching out. I have not yet tried to reproduce this, nor can I confirm this is a bug or feature request. I'm just trying to confirm my understanding at this point.

To summarize your request:

Steps to reproduce:

  1. Setup a user pool that can both verify via phone numbers and emails
  2. Setup the user pool so that the sms template for phone number verification is default (which is a code)
  3. Setup the user pool so that the email template is a link instead of a code (can you provide us with how you are setting this up?)
  4. Run the iOS application, and sign up a new user with a phone number
  5. Upon signing in, receive a SMS confirmation code on the phone number you provided in step 4, and pass this SMS code to cognito using the confirmSignUp() api.
  6. Present an UI which takes in the email and name, and use updateAttribute function.

Observed behavior:
The contents of the email after executing step 6, sends a code to the email

Expected behavior:
The contents of the email after executing step 6 should be a link, which is configured in the user pool's templates

  1. Can you provide which version of Amplify you are using?
  2. Can you provide some relevant screenshots of how Cognito is configured? (please redact any sensitive information)
  3. Provide any relevant sample code for:
    a. How your app is calling confirmSignUp()
    b. How your app is calling updateAttribute()
    c. Anything else you think is relevant in reproducing this issue. (also please redact any sensitive information)

@wooj2 wooj2 added auth Issues related to the Auth category pending-community-response Issue is pending response from the issue requestor labels Jan 13, 2021
@mohaalsouli
Copy link
Author

Hi @wooj2,
Thanks for the reply. The steps to reproduce and the summary are correct. Thanks.

To answer your questions:

  • We set up the user pool email template by choosing Link Verification Type as in the screenshot below:
    image

  • We have also tried (with and without) adding a Cognito Domain in case that is required for the user pool to generate a link. See the screenshot below:
    image

  • Our user pool only has standard settings, nothing custom besides the above email template and an extra attribute, see a screenshot of the general settings below:
    image

  • Amplify version should be the latest since we've just started development in Nov-Dec 2020 and we follow the standard code from Amplify documentation. Having said that, I will confirm the version number and code snippets with our engineers and get back to you shortly.

Thank you.

@mohaalsouli
Copy link
Author

Further details:

  • We use Amplify version: 1.4.1
  • Code snippets (it's a POC work so excuse the static values, variables, and error handling):
private func signUp(phoneNumber: String) -> AnyPublisher<Void, Error> {
        Future { promise in
            let userAttributes = [AuthUserAttribute(.email, value: Constants.emailAddress) , AuthUserAttribute(.name, value: Constants.appName)]
            let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
            _ = Amplify.Auth.signUp(username: phoneNumber, password: Constants.userPassword, options: options) { result in
                switch result {
                    case .success:
                        print("SignUp successful")
                        promise(.success(()))
                    case let .failure(error):
                        //expected error for users who already exist
                        if error.userExists() {
                            print("SignUp user exists \(phoneNumber)")
                            promise(.failure(Errors.UserExist()))
                            //promise(.success(()))
                        } else {
                            print("SignUp error: \(error)")
                            promise(.failure(error))
                        }
                }
            }
        }
        .eraseToAnyPublisher()
    }
func verifyConfirmSignUpCode(username: String , code: String) -> AnyPublisher<Void, Error> {
        Future<Void, Error> { promise in
            _ = Amplify.Auth.confirmSignUp(for: username, confirmationCode: code) { result in
                switch result {
                    case .success:
                        print("ConfirmSignUp successful")
                        let kcw = KeychainWrapper()
                        do {
                            try kcw.deleteUserData(key: userMobileNumber)
                            try kcw.saveUserData(key: userMobileNumber, value: username)
                        } catch let error as KeychainWrapperError {
                            print("Exception setting phoneNumber: \(error.message ?? "no message")")
                        } catch {
                            print("An error occurred setting the phoneNumber.")
                        }
                        promise(.success(()))
                    case let .failure(error):
                        print("ConfirmSignUp error: \(error)")
                        switch error {
                            case .validation:
                                promise(.failure(Errors.ConfirmationCodeIncorrect()))
                            default:
                                promise(.failure(error))
                        }
                }
            }
        }
        .eraseToAnyPublisher()
    }
func updateUserAttribute(email : String) -> AnyPublisher<Void, Error> {
        Future { promise in
            _ = Amplify.Auth.update(userAttribute: AuthUserAttribute(.email, value: email)) { result in
                switch result {
                    case .success(let updateResult):
                        switch updateResult.nextStep {
                            case .confirmAttributeWithCode( _, _):
                                print("Update Email Done with code")
                                promise(.success(()))
                            case .done:
                                print("Update Email Done.")
                                promise(.success(()))
                        }
                        print("Update Email Done.")
                        promise(.success(()))
                    case .failure(let error):
                        promise(.failure(error))
                }
            }
        }
        .eraseToAnyPublisher()
    }

Looking forward to a workaround or a proper solution. Thank you.

@wooj2 wooj2 added follow up Requires follow up from maintainers and removed pending-community-response Issue is pending response from the issue requestor labels Jan 14, 2021
@mohaalsouli
Copy link
Author

FYI, a similar issue was also raised for Amplify Android. It's the exact same issue. Just thought to share this here as this might actually not be a bug but a missing feature across all Amplify SDKs (or the downstream API).

@mohaalsouli mohaalsouli changed the title Cognito: cannot verify Email with link after updateAttribute() Cognito: cannot verify Email with link after update(userAttribute) Jan 14, 2021
@palpatim
Copy link
Member

We need to investigate to find out the correct Cognito API to call for this use case. For example, GetUserAttributeVerificationCode looks promising. :)

Once we have verified that calling that API will in fact send a link rather than a code, we need to see if AWSMobileClient (which underlies Amplify Auth) is invoking that API correctly, or what it would take to get it to invoke that API.

@palpatim palpatim added the investigating This issue is being investigated label Jan 29, 2021
@ruiguoamz
Copy link
Contributor

Hi, @mohaalsouli

I have confirmed with Cognito that they only supports links for initial verification but not for email updates.

@ruiguoamz ruiguoamz added work in progress Issues was triaged and investigation done and removed follow up Requires follow up from maintainers investigating This issue is being investigated labels Feb 3, 2021
@mohaalsouli
Copy link
Author

Thanks @ruiguoamz
So, where do we go from here? Should I raise a feature request with AWS support for Cognito?

@ruiguoamz
Copy link
Contributor

ruiguoamz commented Feb 4, 2021

Before raising a feature request on behalf of you. Do you mind telling us the reason of this specific use case? Because the auth flow you describe in this issue is actually a normal use case.

@ruiguoamz
Copy link
Contributor

But feel free to raise a feature request with AWS support for Cognito

@mohaalsouli
Copy link
Author

mohaalsouli commented Feb 5, 2021

Hi @ruiguoamz, this signup flow is actually not complicated. It's common for mobile apps to sign up new users with phone number first, then capture their further details like name, email, etc.

Also, according to Cognito documentation:

If a user signs up with both a phone number and an email address, and your user pool settings require verification of both attributes, a verification code is sent via SMS to the phone. The email address is not verified, so your app needs to call GetUser to see if an email address is awaiting verification. If it is, the app should call GetUserAttributeVerificationCode to initiate the email verification flow and then submit the verification code by calling VerifyUserAttribute.

So, if we sign up a user with both email and phone at the same time, the user will not get a verification email automatically. Hence, we sign up with the phone number first, then update the user email so the verification process is invoked automatically inside Amplify.Auth.update().
On the other hand, if we want to trigger the verification process manually, using the Amplify.Auth.confirm() for example, the only available option is through code, not link.

Code verification for emails is not an ideal workflow for mobile users. It can work, but it's not ideal like with simply clicking a link. That is the reason we raised this issue.

Thanks

@ruiguoamz
Copy link
Contributor

Thanks for the elaboration. Sorry to say that's the limitation of current Cognito auth flow. Feel free to raise a feature request through AWS Support so that Cognito puts it in their backlog.

@mohaalsouli
Copy link
Author

No worries and thank you for the investigation @ruiguoamz.

I've raised a feature request to AWS Support (Cased ID: 7971079261) explaining that this is very limiting for mobile apps in the following scenarios:

  • if the app signs up users with phone number and email at the same time, you can't verify the email with Link because your app will have have to call GetUserAttributeVerificationCode API for email verification; or
  • if the app allows email attribute updates post signup, you can't verify the new email through Link as you're limited to the GetUserAttributeVerificationCode API call.

I believe this ticket should be parked until the feature is available in Cognito API, then it can be made available through Amplify SDK too.

Cheers

@palpatim palpatim added feature-request Request a new feature and removed work in progress Issues was triaged and investigation done labels Feb 9, 2021
@palpatim
Copy link
Member

palpatim commented Feb 9, 2021

Flagging as a feature request, and as @mohaalsouli notes, we'll leave this as an open issue until we get a disposition on their request to the service team.

@github-actions
Copy link
Contributor

This issue is stale because it has been open for 14 days with no activity. Please, provide an update or it will be automatically closed in 7 days.

@github-actions github-actions bot added closing soon This issue will be closed in 7 days unless further comments are made. and removed closing soon This issue will be closed in 7 days unless further comments are made. labels Jun 19, 2021
@Chesong-Lee-Hospii
Copy link

Bumping since we need this as well.

@thisisabhash
Copy link
Member

Hello @mohaalsouli, Thank you for your message.
Have you received any updates on the support ticket yet?

@AssenDimitrov
Copy link

Same here, have someone implemented any workaround?

@harsh62
Copy link
Member

harsh62 commented Sep 24, 2024

I believe this ticket should be parked until the feature is available in Cognito API, then it can be made available through Amplify SDK too.

Closing the ticket, since this is not something supported by the service. Please reach out to AWS support for further updates with regards to this feature.

@harsh62 harsh62 closed this as completed Sep 24, 2024
Copy link
Contributor

This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues related to the Auth category feature-request Request a new feature
Projects
None yet
Development

No branches or pull requests

8 participants