Question:
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
... const userPoolData = { UserPoolId: ClientId: }; 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:
1 2 3 4 |
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.
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:
1 2 3 4 |
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
Answer:
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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