Reputation: 1107
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 result
object 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.
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
Upvotes: 5
Views: 8597
Reputation: 1107
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
Upvotes: 11
Reputation: 5165
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.
Upvotes: 2