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 users have to verify email every time they log in #2730

Closed
jeancochrane opened this issue Feb 19, 2019 · 14 comments
Closed

Cognito users have to verify email every time they log in #2730

jeancochrane opened this issue Feb 19, 2019 · 14 comments
Assignees
Labels
Cognito Related to cognito issues investigating This issue is being investigated React React related issues

Comments

@jeancochrane
Copy link

Describe the bug

When logging into an app using aws-amplify-react, the user is prompted to verify their email address every time they log in. This persists whether or not email verification is enabled in the user pool configuration.

To Reproduce

I'm not sure if there's an easy way to reproduce this. I stood up one version of the stack and it worked fine, but then when standing up another version with the same configuration I suddenly saw the problem. No amount of messing with the parameters so far has allowed me to fix the issue. It's possible this is a configuration issue on my end; if so I'd appreciate advice on how to further debug, since I feel like I'm up against a wall.

Here are the relevant user pool parameters (trimmed of any parameters that are just references to resource names):

{
    "allowUnauthenticatedIdentities": false,
    "thirdPartyAuth": false,
    "autoVerifiedAttributes": [
        "email"
    ],
    "mfaConfiguration": "OFF",
    "mfaTypes": [
        "SMS Text Message"
    ],
    "smsAuthenticationMessage": "Your authentication code is {####}",
    "smsVerificationMessage": "Your verification code is {####}",
    "emailVerificationSubject": "Your verification code",
    "emailVerificationMessage": "Your verification code is {####}",
    "defaultPasswordPolicy": true,
    "passwordPolicyMinLength": 8,
    "passwordPolicyCharacters": [],
    "requiredAttributes": [
        "email"
    ],
    "userpoolClientGenerateSecret": true,
    "userpoolClientRefreshTokenValidity": 30,
    "userpoolClientReadAttributes": [
        "email"
    ],
    "userpoolClientSetAttributes": false,
    "useDefault": "manual",
    "authSelections": "identityPoolAndUserPool",
}

Expected behavior

I'd expect that once a user has the attribute email_verified, they wouldn't have to verify their email again.

Desktop (please complete the following information):

  • OS: Ubuntu 18.04 and MacOS Mojave
  • Browser: Chrome 72.0.3626.109, Safari 12.0.1

Additional context
I don't know which service this bug might be appearing in. Here are the versions I have installed of all Amplify packages:

  • aws-amplify: 1.1.19
  • aws-amplify-react: 2.1.7
  • @aws-amplify/cli: 0.1.45

I recognize that some of these are now outdated, but I wanted to avoid upgrading them for fear of having to migrate the project.

@haverchuck
Copy link
Contributor

haverchuck commented Feb 19, 2019

@jeancochrane - To debug this, try setting a log level. In index.js or similar entry you can do: window.LOG_LEVEL = 'DEBUG';. This will turn on Amplify's logger. Then (after reproducing the issue), look for an entry like [DEBUG] 57:38.864 Authenticator - authenticator state change verifyContact. You can then see the CognitoUser data being used the component(s). There is a property called 'unverified' which contains the unverified attributes. What do you see there?

I'm just trying to isolate whether this is an issue with the response from Cognito or an issue with the component.

@haverchuck haverchuck added React React related issues investigating This issue is being investigated labels Feb 19, 2019
@haverchuck haverchuck self-assigned this Feb 19, 2019
@haverchuck haverchuck added the pending-close-response-required A response is required for this issue to remain open, it will be closed within the next 7 days. label Feb 20, 2019
@jeancochrane
Copy link
Author

Thanks for the debug instructions @haverchuck! Will give that a try when I have a free minute and let you know what the output says.

@jeancochrane
Copy link
Author

Interestingly, the CognitoUser object in the debug output says that the email address is unverified:

{
  "username": "jeancochrane",
  "unverified": {email: "${email}"} 
  "verified": {},
  ...
}

However, when I grab the userPoolId from the pool attribute and use the AWS CLI to list-users, the user has a truthy value for email_verified:

$ aws cognito-idp list-users --user-pool-id ${user_pool_id}
{
    "Users": [
        {
            "Username": "jeancochrane",
            "Attributes": [
                {
                    "Name": "sub",
                    "Value": "${sub}"
                },
                {
                    "Name": "email_verified",
                    "Value": "true"
                },
                {
                    "Name": "phone_number_verified",
                    "Value": "true"
                },
                {
                    "Name": "phone_number",
                    "Value": "${phone}"
                },
                {
                    "Name": "email",
                    "Value": "${email}"
                }
            ],
            "UserCreateDate": 1550509449.43,
            "UserLastModifiedDate": 1550511030.237,
            "Enabled": true,
            "UserStatus": "CONFIRMED"
        },
       ...
    ]
}

@haverchuck
Copy link
Contributor

haverchuck commented Feb 21, 2019

@jeancochrane - This does look like some sort of configuration issue. Could you please:

a) Post the client code you are using for authentication (unless you are just using an unmodified version of the aws-amplify-react Authenticator component)
b) a screen shot of your user pool settings in the Cognito console (feel free to redact senstive values)
c) your aws-exports key/values (again, with anything sensitive redacted)

This will help us dig into it further.

@jeancochrane
Copy link
Author

Sure thing! I've replaced potentially sensitive values with ${variable_notation} below.

a) Post the client code you are using for authentication (unless you are just using an unmodified version of the aws-amplify-react Authenticator component)

I believe this is the component in question:

import withAuthenticator from './components/with-authenticator'

const ConnectedApplication = withAuthenticator(withRouter(
  connect(mapStateToProps, actions)(Application)), true,
[
  <CustomSignIn override={SignIn} />,
  <ConfirmSignIn />,
  <ConfirmSignUp />,
  <ForgotPassword />,
  <Loading />,
  <RequireNewPassword />,
  <TOTPSetup />,
  <VerifyContact />
], null, CustomAuthenticatorTheme)

Here's a gist containing the implementation of withAuthenticator: https://gist.github.com/jeancochrane/4bcc7faeaa6b615e5f4e52619a77fc4f

There are a few custom components passed in here that mostly adjust styling. I can post code for any of them that seem like they might be possible culprits. My colleague who's handling the frontend code believes that it isn't a frontend configuration issue, however, since authentication works as expected for the staging stack but not the production stack.

b) a screen shot of your user pool settings in the Cognito console (feel free to redact senstive values)

I'll do you one better, here's the output of describe-user-pool:

{
    "UserPool": {
        "Id": "${user_pool_id}",
        "Name": "${user_pool_name}",
        "Policies": {
            "PasswordPolicy": {
                "MinimumLength": 8,
                "RequireUppercase": false,
                "RequireLowercase": false,
                "RequireNumbers": false,
                "RequireSymbols": false
            }
        },
        "LambdaConfig": {},
        "LastModifiedDate": 1550510694.585,
        "CreationDate": 1550257417.659,
        "SchemaAttributes": [
            {
                "Name": "sub",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": false,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "1",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "given_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "family_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "middle_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "nickname",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "preferred_username",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "profile",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "picture",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "website",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "email",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "email_verified",
                "AttributeDataType": "Boolean",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false
            },
            {
                "Name": "gender",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "birthdate",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "10",
                    "MaxLength": "10"
                }
            },
            {
                "Name": "zoneinfo",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "locale",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "phone_number",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "phone_number_verified",
                "AttributeDataType": "Boolean",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false
            },
            {
                "Name": "address",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "updated_at",
                "AttributeDataType": "Number",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "NumberAttributeConstraints": {
                    "MinValue": "0"
                }
            }
        ],
        "SmsVerificationMessage": "Your verification code is {####}",
        "EmailVerificationMessage": "Your verification code is {####}",
        "EmailVerificationSubject": "Your verification code",
        "VerificationMessageTemplate": {
            "SmsMessage": "Your verification code is {####}",
            "EmailMessage": "Your verification code is {####}",
            "EmailSubject": "Your verification code",
            "DefaultEmailOption": "CONFIRM_WITH_CODE"
        },
        "MfaConfiguration": "OPTIONAL",
        "EstimatedNumberOfUsers": 3,
        "EmailConfiguration": {},
        "SmsConfiguration": {
            "SnsCallerArn": "${sns_rol_arn}",
            "ExternalId": "${role_external_id}"
        },
        "UserPoolTags": {},
        "AdminCreateUserConfig": {
            "AllowAdminCreateUserOnly": true,
            "UnusedAccountValidityDays": 7
        },
        "Arn": "${user_pool_arn}"
    }
}

c) your aws-exports key/values (again, with anything sensitive redacted)

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_cognito_identity_pool_id": "us-east-1:${id_pool_uuid}",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": "us-east-1_${user_pool_id}",
    "aws_user_pools_web_client_id": "${user_pool_client_id}",
    "aws_user_files_s3_bucket": "${s3_bucket_name}",
    "aws_user_files_s3_bucket_region": "us-east-1"
};

Let me know if you need any more info to help debug!

@haverchuck
Copy link
Contributor

haverchuck commented Feb 25, 2019

@jeancochrane I'm working on trying to reproduce this (so far without luck). You say that this works on your staging stack but not on your production stack. Are you using the Amplify CLI and/or console to manage these environments? Do you see any differences between the two user pools?

Also - were these users created via self registration and the SignUp component, or were they created by an admin in the Cognito console? If the latter, which options were selected on the creation modal?

@jeancochrane
Copy link
Author

Are you using the Amplify CLI and/or console to manage these environments? Do you see any differences between the two user pools?

We're using Amplify CLI to manage both environments. As far as I can tell, the user pools are close to identical -- the only differences are A) some minor differences in the password requirements and B) users in the production stack (the one seeing the unexpected behavior) cannot create their own accounts, while users in the staging stack can.

Were these users created via self registration and the SignUp component, or were they created by an admin in the Cognito console? If the latter, which options were selected on the creation modal?

I've tried creating users both ways, with no luck. Here's what the options look like in the creation modal:

screen shot 2019-02-25 at 4 48 04 pm

I'm working on trying to reproduce this (so far without luck).

Thanks for giving it a try! I understand if you can't reproduce -- part of my frustration is that the working stack is essentially identical to the malfunctioning stack in terms of its exposed configs, so I expected that reproducing would be difficult. Mostly I was wondering if you had any idea of further things I could try to inspect. If not, I think the next step for us is to tear down and recreate the production stack from scratch and see if we get the same behavior.

@elorzafe elorzafe removed the pending-close-response-required A response is required for this issue to remain open, it will be closed within the next 7 days. label Feb 25, 2019
@elorzafe
Copy link
Contributor

@jeancochrane I tried to reproduce the problem using withAuthenticator component like this.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Amplify from 'aws-amplify';
import { withAuthenticator } from 'aws-amplify-react';
import config from './aws-exports';

Amplify.configure(config);
Amplify.Logger.LOG_LEVEL = 'DEBUG';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
}

export default withAuthenticator(App, true);

When I created the user without confirming the email, I see the Account recovery requires verified contact information screen. By selecting the email radio button and verifying the code that is sent to the email change the status of the user and never ask for that again.

I think the problem could be on the userPoolId, can you double check the userPoolId that is on CognitoUser object.

@elorzafe elorzafe added the Cognito Related to cognito issues label Feb 26, 2019
@jeancochrane
Copy link
Author

@elorzafe The user pool ID in the CognitoUser object matches the one I'm expecting to see in the console, and when I run aws congito-idp list-users with the pool ID I can confirm that the attribute email_verified for my user is set to "true".

I'll give it a try using the component that you posted, just to rule out that it's a frontend issue.

I tried to stand up a new version of the stack and unfortunately was able to reproduce this problem. What version of the CLI are you using? Take note that we're pinned to 0.1.45 since we didn't want to incur the breaking changes in 1.x.

@jeancochrane
Copy link
Author

Finally got to the bottom of this! Turns out it was a configuration error on my end -- during the CLI wizard, I neglected to set UserPoolClient.ReadAttributes to include email_verified. In the CLI, this corresponds to the following steps in amplify add auth:

? Do you want to specify the user attributes this app can read and write? Yes
? Specify read attributes: (Press <space> to select, <a> to toggle all, <i> to invert selection)
 ◯ Updated At
 ◯ Website
 ◯ Zone Info
❯◯ Email Verified?
 ◯ Phone Number Verified?
 ◯ Address
 ◯ Birthdate
(Move up and down to reveal more choices)

Thanks for your debugging assistance @haverchuck and @elorzafe, I appreciate it!

@elorzafe
Copy link
Contributor

@jeancochrane I am glad you issue was solved. Good catch!

@zfarrell
Copy link

zfarrell commented Jun 3, 2019

I just got hit with this. For those that need to fix this:

  1. open up amplify/backend/auth/$cognitofolder/parameters.json
  2. find userpoolClientReadAttributes array and add email_verified
  3. run amplify push

Is there a use case where the *_verified attributes shouldn't be returned? At the least, it seems like the CLI wizard should try and talk you out of disabling them as read attributes (and describe the consequences).

@jkeys-ecg-nmsu
Copy link

Related issue? #3607

@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Cognito Related to cognito issues investigating This issue is being investigated React React related issues
Projects
None yet
Development

No branches or pull requests

5 participants