Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Cognito Authentication Returns Error - Javascript SDK

I am using AWS Cognito to authenticate users in a new app that I am building.

I am using the amazon-cognito-identity-js library in my project (link to Github: https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js). Since users in this particular user pool cannot sign themselves up - I sign them up manually - I know that I need "Use case 23" as stated in the README.md from Github.

So my code is as follows:

    ...
    const userPoolData = {
        UserPoolId: <MY_USER_POOL_ID>,
        ClientId: <MY_CLIENT_ID>
    };

    const userPool = new CognitoUserPool(userPoolData);

    const authenticationData = {
        Username: email,
        Password: tempPassword
    };
    const userData = {
        Username: email,
        Pool: userPool
    }

    const authenticationDetails = new AuthenticationDetails(authenticationData);
    const cognitoUser = new CognitoUser(userData);

    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: (result) => {
            console.log(result);
        },
        onFailure: (err) => {
            console.log("Error from cognito auth: ", err);
        },
        newPasswordRequired: (userAttributes) => {
            delete userAttributes.email_verified;
            cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
        }
    })
    ...

When I execute this code, I successfully confirm my user. I can see this in the AWS Cognito console. However, instead of receiving the result object, I get an error in the javascript console on the client that says:

Uncaught (in promise) TypeError: Cannot read property 'onFailure' of undefined
    at eval (CognitoUser.js:572)
    at eval (Client.js:108)

But when I attempt to sign in with the newPassword in place of the tempPassword previously sent, I am now able to successfully get the resultobject with the three tokens all present.

So I know that everything is kinda working, but isn't what I am expecting.

What is causing this error? How can I fix it? I want to receive the result object immediately when the user first signs in with the tempPassword and their newPassword so that they can start using the app.

EDIT:

Thinking that I had to retrieve the userAttributes myself was a mistake. The newPasswordRequired function passes them automatically. So I updated my code above to go with "Use case 23" as presented on Github.

But now I get a slightly different error than before:

Uncaught (in promise) TypeError: callback.onFailure is not a function
    at eval (CognitoUser.js:572)
    at eval (Client.js:108)

Everything still works as far as Cognito is concerned, but there must be something wrong with my onFailure function, which is very strange.

Any thoughts?

Thanks in advance

like image 638
Z_z_Z Avatar asked Sep 16 '18 02:09

Z_z_Z


2 Answers

Please update the line cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes); into cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this) Basically, this will make sure the callback function within the same object.

like image 30
sayboras Avatar answered Nov 12 '22 09:11

sayboras


Alright, I solved it. The issue was that I was using ES6 arrow functions. As Apolozeus pointed out, I needed to pass this into the cognitoUser.completeNewPasswordChallenge function. But due to the way ES6 behaves, this was returning undefined. So, changing my cognitoUser.authenticateUser function to the following solved everything:

  cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function (result) {
            resolve(result.getAccessToken().getJwtToken());
        },
        onFailure: function (err) {
            console.log("Error from cognito promise: ", err);
            reject(err);
        },
        newPasswordRequired: function (userAttributes) {
            delete userAttributes.email_verified;
            cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
        }
    })

I'm going to play around with the amazon-cognito-identity-js library a bit and see if I can get ES6 arrow functions to work here. It's really annoying to have to work around that.

Shout out to Apolozeus for the help

like image 67
Z_z_Z Avatar answered Nov 12 '22 10:11

Z_z_Z