Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Cognito completeNewPasswordChallenge calls onFailure method but the user is confirmed in AWS Console

I'm using AWS Cognito Javascript SDK in a react application. I have a user that was created in the AWS Console by an admin, and when the user is logged in for the first time they have to reset their password. I go through the newPasswordRequired flow, and when I call the completeNewPasswordChallenge function with the parameters, the onFailure callback is ran. When I log the error I get, {code: "UnknownError", message: "Unknown error"}. However, when I check the AWS Console, the user in the user pool is changed from FORCE_CHANGE_PASSWORD to CONFIRMED.

My code is:

class LoginScreenContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isInvalidForm: null,
      isFirstLogin: false,
      user: null,
      userAttr: null
    }
    this.onFormSubmission = this.onFormSubmission.bind(this);
    this.updatePassword = this.updatePassword.bind(this);
  }

  onFormSubmission = (username, password) => {
    const poolData = {
      UserPoolId : AWSConfig.cognito.USER_POOL_ID,
      ClientId : AWSConfig.cognito.APP_CLIENT_ID
    }

    const userPool = new CognitoUserPool(poolData);
    const userData = {
      Username: username,
      Pool: userPool
    }
    const cognitoUser = new CognitoUser(userData);

    const authenticationData = {
        Username : username,
        Password : password
    }
    const authenticationDetails = new AuthenticationDetails(authenticationData);

    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => {
        console.log(result);
      },
      onFailure: (err) => {
          console.log("Authenticate user failure");
          console.log(err);
          this.setState({ isInvalidForm: true });
     },
      newPasswordRequired: (userAttributes) => {
         delete userAttributes.email_verified;
         delete userAttributes.phone_number_verified;

        userAttributes.name = authenticationDetails.username;
        console.log(userAttributes);
        this.setState({
          isFirstLogin: true,
          user: cognitoUser,
          userAttr: userAttributes
        });
      }
    });
  }

  updatePassword = (newPassword) => {
    const cognitoUser = this.state.user;
    const userAttr = this.state.userAttr;
    cognitoUser.completeNewPasswordChallenge(newPassword, userAttr, {
      onSuccess: (result) => {
        console.log("NEW PASSWORD COMPLETED: ");
        console.log(result);
      },
      onFailure: (err) => {
        console.log(err);
      }
    });
  }

  render() {
    return (
      <div>
      {this.state.isFirstLogin ? (
        <NewPasswordForm updatePassword={this.updatePassword} />
      ) : (
        <LoginScreenComponent isInvalidForm={this.state.isInvalidForm} onFormSubmission={this.onFormSubmission}/>
      )}
      </div>
    );
  }
}
like image 561
Dylan Terrell Avatar asked Jul 10 '18 15:07

Dylan Terrell


People also ask

How do I authenticate someone on Cognito?

2.1. Go to AWS Cognito service and click “Manage Identity Pools”. 2. Enter “Identity pool name”, expand the “Authentication providers” section and select “Cognito” tab. This is where the Cognito authentication provider will be registered with the Identity pool.

How do you use the code returned from Cognito to get AWS credentials?

Simply, You can request the id/access/refresh tokens using the code and the Cognito clientId+hostname, then use the id and access token to identify the user in your API calls.

What is callback URL in AWS Cognito?

A callback URL indicates where the user will be redirected after a successful sign-in. Enter Sign out URL(s). A sign-out URL indicates where your user will be redirected after signing out. Select Authorization code grant to return an authorization code that is then exchanged for user pool tokens.

How do I use remembered devices in my Amazon Cognito user pool?

Set up remembered devices In the Amazon Cognito console, choose Manage user pools, and then choose your user pool. In the left navigation pane, under General settings, choose Devices. For Do you want to remember your user's devices, choose Always or User Opt In.


1 Answers

I believe you need to call completeNewPasswordChallenge within the newPasswordRequired callback.

newPasswordRequired: (userAttributes, requiredAttributes) => {
          delete userAttributes.email_verified

          cognitoUser.completeNewPasswordChallenge(newPw, userAttributes, {
            onSuccess: result => {
              AWS.config.credentials.refresh(err => {
                if (err) {
                  throw err
                } else {
                  // do something
                }
              })
            },
            newPasswordRequired: (userAttributes, requiredAttributes) => {
              delete userAttributes.email_verified
              // phone number as well

              cognitoUser.completeNewPasswordChallenge(newPw, userAttributes, this.newPasswordRequired)
            },
            onFailure: err => {
              throw err
            }
          })
        },
like image 141
Jonathan Avatar answered Oct 20 '22 00:10

Jonathan