35

So in my app I obviously want to provide the means for users to reset their passwords. The issue I'm having though is that the new documentation for User Pools is pretty ambiguous on this topic. Here is what they tell you to do for a Forgot Password flow, and the link you may find it at:

cognitoUser.forgotPassword({
        onSuccess: function (result) {
            console.log('call result: ' + result);
        },
        onFailure: function(err) {
            alert(err);
        },
        inputVerificationCode() {
            var verificationCode = prompt('Please input verification code ' ,'');
            var newPassword = prompt('Enter new password ' ,'');
            cognitoUser.confirmPassword(verificationCode, newPassword, this);
        }
    });

http://docs.aws.amazon.com/cognito/latest/developerguide/using-amazon-cognito-user-identity-pools-javascript-examples.html

However when I drop this code into my project where a cognitoUser is defined and signed in, nothing seems to happen. I understand I need to somehow integrate this code with sending a verification code to the user, and asking them for a new password, but can't find anything on how to do this. Thoughts?

Thanks

Mark Keane
  • 984
  • 2
  • 11
  • 26
  • 1
    @ToddHoff have you by chance run into an issue having your users authenticate with User Pools from mobile when they are on the website? Both these questions are driving me crazy. – Mark Keane Jul 01 '16 at 18:52
  • 1
    Sorry, no authentication works for me from a website.What's the issue? I may have run into it? I also have a question on the amazon forum and they've been pretty good about answering. This is a holiday so it may be a bit slow. – Todd Hoff Jul 02 '16 at 16:07
  • 2
    @ToddHoff the issues is that my Javascript website that implements Cognito User Pools works fine from a computer but when I go on it from mobile and try and log in it just gets stuck on the authentication attempt and never calls onSuccess or onFailure. I may have to try the aws forums :( thanks! – Mark Keane Jul 02 '16 at 17:46

6 Answers6

67

AWS' docs are terrible on this topic (Cognito). You basically need to setup cognitoUser, then call forgotPassword

export function resetPassword(username) {
    // const poolData = { UserPoolId: xxxx, ClientId: xxxx };
    // userPool is const userPool = new AWSCognito.CognitoUserPool(poolData);

    // setup cognitoUser first
    cognitoUser = new AWSCognito.CognitoUser({
        Username: username,
        Pool: userPool
    });

    // call forgotPassword on cognitoUser
    cognitoUser.forgotPassword({
        onSuccess: function(result) {
            console.log('call result: ' + result);
        },
        onFailure: function(err) {
            alert(err);
        },
        inputVerificationCode() { // this is optional, and likely won't be implemented as in AWS's example (i.e, prompt to get info)
            var verificationCode = prompt('Please input verification code ', '');
            var newPassword = prompt('Enter new password ', '');
            cognitoUser.confirmPassword(verificationCode, newPassword, this);
        }
    });
}

// confirmPassword can be separately built out as follows...  
export function confirmPassword(username, verificationCode, newPassword) {
    cognitoUser = new AWSCognito.CognitoUser({
        Username: username,
        Pool: userPool
    });

    return new Promise((resolve, reject) => {
        cognitoUser.confirmPassword(verificationCode, newPassword, {
            onFailure(err) {
                reject(err);
            },
            onSuccess() {
                resolve();
            },
        });
    });
}
user1322092
  • 4,020
  • 7
  • 35
  • 52
  • 3
    hi, I get the following error when I try change password, "InvalidParameterType: Expected params.Username to be a string" – Gaurav Ram Jul 14 '17 at 21:15
22

Resetting the password with forgot password flow has two steps:

  1. Start the process by requesting for a verification code from the service. A code will be delivered to the user's phone/email.
  2. Set the new password using the delivered verification code.

Use these two functions to perform the above steps and reset the password:

  1. cognitoUser.forgotPassword(): This will start the forgot password process flow. The service generates a verification code and sends it to the user. The "data", returned through callback.inputVerificationCode(data), indicates where the verification code was sent.

  2. cognitoUser.confirmPassword(): Use the delivered verification code with this function to set a new password.

jiri.hofman
  • 127
  • 1
  • 3
  • 10
M Reddy
  • 761
  • 5
  • 5
  • 1
    This didn't work for me. I got an error back saying the user was already confirmed. Is there another call to invalidate the confirmation first? – Todd Hoff Jul 23 '16 at 17:31
  • 2
    “Start the process by requesting for a verification code from the service. A code will be delivered to the user's phone/email.” How does it know where to send if the username/email isn’t included? – Brandon Durham Sep 21 '19 at 19:07
7

I had this same issue. Was able to work through it by using confirmPassword() in the following way.

//validation of input from form
req.checkBody('email', 'Username is required').notEmpty();
req.checkBody('password', 'Password is required').notEmpty();
req.checkBody('confirmationcode', 'Confirmation Code is required').notEmpty();


var confirmationCode = req.body.confirmationcode;
var password = req.body.password;
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);


var userData = {
    Username: req.body.email,
    Pool: userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

cognitoUser.confirmPassword(confirmationCode, password, {
    onFailure(err) {
        console.log(err);
    },
    onSuccess() {
        console.log("Success");
    },
});
gabriel
  • 79
  • 1
  • 1
2

If as me, you find how to handle this case with amplify

import { Auth } from 'aws-amplify';

// Send confirmation code to user's email
Auth.forgotPassword(username)
    .then(data => console.log(data))
    .catch(err => console.log(err));

// Collect confirmation code and new password, then
Auth.forgotPasswordSubmit(username, code, new_password)
    .then(data => console.log(data))
    .catch(err => console.log(err));

See https://docs.amplify.aws/lib/auth/manageusers/q/platform/js#forgot-password

Quentin
  • 481
  • 6
  • 13
0

So Even I faced a same issue, Even in AWS cognito documentation it was not clear, basically the process involves two steps.

  1. call cognitoUser.forgotPassword() this will start forgot password process flow, and the user will receive a verification code.
  2. then call cognitoUser.confirmPassword() which will reset the password verifying the code send to the email of user.

Below I have given a cognitoUserClass(Typescript) which has static methods forgotPassword() and confirmPassword() methods which implements those two steps.

import * as AmazonCognitoIdentity from 'amazon-cognito-identity-js'

class cognitoUserClass {
    static cognitouser: AmazonCognitoIdentity.CognitoUser
    static userPool = new AmazonCognitoIdentity.CognitoUserPool({
        UserPoolId: 'your pool id',
        ClientId: 'your client id',
    })
    static forgotPassword(userName: string): void {
        const userData = {
            Username: userName,
            Pool: cognitoUserClass.userPool,
        }
        cognitoUserClass.cognitouser = new AmazonCognitoIdentity.CognitoUser(
            userData
        )

        cognitoUserClass.cognitouser.forgotPassword({
            onSuccess: (data) => {
                console.log(data)
            },
            onFailure: (err) => {
                console.log('ERR:', err)
            },
        })
    }
    static confirmPassword(
        verificationCode: string,
        newPassword: string
    ): void {
        cognitoUserClass.cognitouser.confirmPassword(
            verificationCode,
            newPassword,
            {
                onFailure(err) {
                    console.log(err)
                },
                onSuccess(data) {
                    console.log(data)
                },
            }
        )
    }
}

export { cognitoUserClass }
0

After you've got the verification code, using aws-amplify it's as easy as follows

import { Auth } from "aws-amplify";

Auth.forgotPasswordSubmit(email, verificationCode, newPassword)
    .then(() => {
        //redirect to sign-in page
    })
    .catch(error => {
        //error logic
    })
Ahmet Firat Keler
  • 2,603
  • 2
  • 11
  • 22