Issue: I am having difficulty implementing use case 27 from the amazon-cognito-identity-js library, specifically in trying to modify it to use a QR Code. I am able to receive the secret code from "associateSoftwareToken", translate it into a QR Code, and get a TOTP code from an authenticator app. However, I'm have difficulty passing the TOTP code as a challenge answer to "verifySoftwareToken" afterwards.
Goal: In the example the library provides, they pause the workflow using a "prompt" (which I've tried and it works) but I would like the user to be able to type the TOTP into a form/input field on the page itself rather than a popup window. Upon hitting "submit" on the form, I'd like to submit the TOTP input to "verifySoftwareToken", allowing the user to complete registration and be directed to the homepage.
I have tried breaking up the authentication flow in this manner, but it doesn't seem to work:
const [totpInput, setTotpInput] = useState(""); // controlled by an input field underneath the QR
// Initial login event handler, which contains the main auth flow
const onSubmit = (event) => {
const authDetails = new AuthenticationDetails({
Username: email,
Password: password
});
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
user.authenticateUser(authDetails, {
... success and error handling, as well as other callbacks
mfaSetup: (challengeName) => {
user.associateSoftwareToken({
onFailure: (err) => {
console.error(err);
},
associateSecretCode: (secretCode) => {
setQRCodeSecret(secretCode);
setQRCode(true); // renders the QR component on the page
// the example uses a prompt here and continues to verifySoftwareToken immediately
// after, which I'm trying to modify
}
});
}
}
// Runs when the QR form is submitted
const onSubmitTotp = (totpInput) => {
user = new CognitoUser({
Username: email,
Pool: UserPool
})
user.verifySoftwareToken(totpInput, 'cry5', {
onSuccess: (result) => {
console.log(result);
},
onFailure: (err) => {
console.log(err);
}
});
}
Errors I've encountered:
- The method above throws a network error when the form is submitted
- I've tried declaring "user" and "authDetails" in useState hooks so their values are maintained across renders, but that doesn't seem to work:
...globally:
const [user, setUser] = useState();
const [authDetails, setAuthDetails] = useState();
...at the start of onSubmit function:
setUser(new CognitoUser({
Username: email,
Pool: UserPool
}));
setAuthDetails(new AuthenticationDetails({
Username: email,
Password: password
}));