So we are using await/async calls, but the authenticateUser command provided by aws-amplify appears to use a callback. I am a python coder and have not coded with node in quite a while, so this may be a naive question!
I tried converting it to a promise like so:
function authenticateUserAsync(user, authDetails) {
return new Promise(function(resolve, reject, challenge) {
user.authenticateUser(authDetails, {
onSuccess: resolve,
onFailure: reject,
newPasswordRequired: challenge });
}).then(
function(result) {
return result;
});
}
and later
idToken = await authenticateUserAsync(user, authDetails,
function(result) {
console.log("Token: ");
console.log(result.idToken);
return result.idToken;
},
function(err) {
console.log(err);
this.setState({idToken: ''});
if (err.code == 'NotAuthorizedException') {
return 'not_authorized';
} else {
return 'unknown_error';
}
},
function(userAttrs, reqAttrs) {
return 'challenge';
}
);
But, no matter how I tweak it, the code flows right on by and then I get an unhandled promise rejection (in my test the auth fails at the moment)
Good on you for trying to implement a call to authenticateUser()
with modern-day Javascript constructs, but there are several issues with your approach. I'd be really curious to see the finished code.
The main issue is that Cognito authenticateUser()
needs three callbacks and promises only handle two. A dummy function can be passed for the newPasswordRequired
callback, if you never expect to hit that code-path. Another approach is to use the resolve
function for both the onSuccess
and the newPasswordRequired
callbacks.
A second issue is that your authenticateUserAsync()
only takes two parameters. You are trying to pass some additional callbacks to it. Those callbacks are ignored. That is why it flows right on by and you get an unhandled promise exception. The unnecessary .then()
doesn't help either.
My implementation ended up like this:
function asyncAuthenticateUser(cognitoUser, cognitoAuthenticationDetails) {
return new Promise(function(resolve, reject) {
cognitoUser.authenticateUser(cognitoAuthenticationDetails, {
onSuccess: resolve,
onFailure: reject,
newPasswordRequired: resolve
})
})
}
async signIn({ commit }, authData) {
let cognitoUserPool = new CognitoUserPool(config.poolDetails)
let cognitoAuthenticationDetails = new AuthenticationDetails(authData);
let userData = { Username: authData.Username, Pool: cognitoUserPool }
let cognitoUser = new CognitoUser(userData)
try {
let result =
await asyncAuthenticateUser(cognitoUser, cognitoAuthenticationDetails)
if ('idToken' in result) {
console.log('We have a token: ' + JSON.stringify(p));
}
else {
console.log('We need a new password.')
delete result.email_verified // Not accepted by the challenge call
delete result.phone_number_verified // Also not accepted
// Get a new password from the user then call
// cognitoUser.completeNewPasswordChallenge()
}
catch (error) {
// Probably a mis-typed password
console.log(error.message)
}
}
An alternative library to amazon-cognito-identity-js
, which uses common ES6 concepts, like async/await would be welcome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With