kndt84 / passport-cognito

Passport strategy for AWS Cognito User Pools
https://www.npmjs.com/package/passport-cognito
MIT License
78 stars 30 forks source link

FORCE_CHANGE_PASSWORD #26

Open NealWalters opened 5 years ago

NealWalters commented 5 years ago

When I added a new test user on Cognito, it's status is "FORCE_CHANGE_PASSWORD". I think, because of that, when I try to login, it's always failing.

I have the standard standard code but put in my two pages:

app.post('/auth/cognito',
  passport.authenticate('cognito', {
    successRedirect: 'http://localhost:8081/home.html',
    failureRedirect: 'http://localhost:8081/login.html'
}));

Based on what I read here: https://docs.aws.amazon.com/cognito/latest/developerguide/using-amazon-cognito-identity-user-pools-javascript-example-authenticating-admin-created-user.html thought maybe something like the code below might work, but it hasn't yet:

app.post('/auth/cognito',
  passport.authenticate('cognito', {
    successRedirect: 'http://localhost:8081/home.html',
    failureRedirect: 'http://localhost:8081/login.html',
    newPasswordRequired: 'http://localhost:8081/newpass.html'
}));

I'm logging the URLS and post/parms as follows, so it looks the redirect is working to the login.html page only:

08/16/2019 14:39:35: POST: Request URL:/auth/cognito { username: 'Test1', password: 'b#*5arNdESHrqtBk' } 08/16/2019 14:39:35: GET: Request URL:/login.html

Is there some other error we can send back to the client on the AJAX call that tell us what the issue is, for example, that he needs to change his password? Is there any type of console.log I can do in the code above to help debug further?

Any idea where to find code to change the password in NodeJS? That would be outside of Passport correct?

Thanks, Neal

XenorPLxx commented 4 years ago

Inside aws-amplify, when you trigger authenticateUser you can provide a callback to for that occasion.

        newPasswordRequired: function(userAttributes, requiredAttributes) {
          // User was signed up by an admin and must provide new
          // password and required attributes, if any, to complete
          // authentication.

          // the api doesn't accept this field back
          delete userAttributes.email_verified;
          delete userAttributes.phone_number_verified;

          // store userAttributes on global variable
          // sessionUserAttributes = userAttributes;

          if (!new_password) {
            // go to change password page
          }

          newUser.completeNewPasswordChallenge(new_password, userAttributes, {
            onSuccess: result => {
              return newUser.changePassword(password, new_password, function(
                err,
                result,
              ) {
                if (err) {
                  console.log(err.message || JSON.stringify(err));
                  reject(err);
                } else {
                  resolve(result);
                }
              });
            },
            onFailure: err => {
              reject(err);
            },
          });
        },

I didn't figure out how to do it using passport-cognito yet.

EDIT: I'm still fighting with my NestJS integration, but from what I understand without NestJS you should be able to catch HTTP 412 error and redirect to change password page manually and if you supply newpassword then it will be changed.

Here's relevant code from passport-cognito:

 var newPassword = req.body.newpassword;
      if (newPassword) {
        var attributesData = [];
        requiredAttributes.map(function(att) {
          attributesData[att] = req.body[att];
        });

        console.log("newPasswordRequired2 ", attributesData, requiredAttributes);
        //Try to validate user
        return cognitoUser.completeNewPasswordChallenge(newPassword, attributesData, this);
      } else {
        return self.fail({ message: options.badRequestMessage || 'New Password Required' }, 412);
      }