I am attempting to setup MFA for users after they reset their passcode. The code runs smoothly until I hit mfaSetup, specifically the line user.associateSoftwareToken(). When I pass in ‘this’ instead of user, I get the following error:
Uncaught (in promise) TypeError: callback is undefined
When I pass in user I get Uncaught (in promise) TypeError: callback.onFailure is not a function
I am truly at a loss of what to do and would appreciate any help.
Code below:
const onSubmit = (event) => {
event.preventDefault();
const authDetails = new AuthenticationDetails({
Username: email,
Password: password
});
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
user.authenticateUser(authDetails, {
onSuccess: (data) => {
console.log('onSuccess:', data);
if (location.pathname === '/') {
// navigate('dashboard');
}
},
onFailure: (err) => {
console.error('onFailure:', err);
},
newPasswordRequired: (data) => {
console.log(data);
setNewPasscodeRequired(true);
},
mfaRequired: (data) => {
console.log('mfa required');
},
mfaSetup: (challengeName, challengeParameters) => {
console.log('in mfa setup');
console.log(user.Session);
user.associateSoftwareToken(user, {
onFailure: (err) => {
console.error('onFailure', err);
},
onSuccess: (result) => {
console.log(result);
}
});
},
selectMFAType: (challengeName, challengeParameters) => {
console.log(challengeName, challengeParameters);
user.sendMFASelectionAnswer('SOFTWARE_TOKEN_MFA', this);
},
totpRequired: (secretCode) => {
console.log(secretCode);
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
},
associateSecretCode: (secretCode) => {
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.verifySoftwareToken(challengeAnswer, 'My TOTP device', this);
}
});
};
const onSubmitPasscode = (event) => {
event.preventDefault();
if (passwordFirst !== passwordSecond) {
alert('the two inputs provided are not the same');
} else {
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
const authDetails = new AuthenticationDetails({
Username: email,
Password: password
});
user.authenticateUser(authDetails, {
onFailure: (err) => {
console.error('onFailure:', err);
},
onSuccess: (result) => {
console.log(result);
},
newPasswordRequired: (userAttributes, requiredAttributes) => {
console.log(userAttributes);
console.log(requiredAttributes);
delete userAttributes.email_verified;
delete userAttributes.phone_number_verified;
delete userAttributes.phone_number;
console.log(userAttributes);
user.completeNewPasswordChallenge(passwordFirst, userAttributes, {
onFailure: (err) => {
console.error('onFailure:', err);
},
onSuccess: (result) => {
console.log('call result: ', result);
},
mfaSetup: (challengeName, challengeParameters) => {
console.log('in mfa setup');
console.log(user.Session);
user.associateSoftwareToken(this, {
onFailure: (err) => {
console.error('onFailure', err);
},
onSuccess: (result) => {
console.log(result);
}
});
},
selectMFAType: (challengeName, challengeParameters) => {
console.log(challengeName, challengeParameters);
user.sendMFASelectionAnswer('SOFTWARE_TOKEN_MFA', this);
},
totpRequired: (secretCode) => {
console.log(secretCode);
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
},
associateSecretCode: (secretCode) => {
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.verifySoftwareToken(challengeAnswer, 'My TOTP device', this);
}
});
}
});
}
};
const onMFASetup = () => {
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
const authDetails = new AuthenticationDetails({
Username: email,
Password: passwordFirst
});
console.log(email);
console.log(passwordFirst);
user.authenticateUser(authDetails, {
onFailure: (err) => {
console.error('onFailure:', err);
},
onSuccess: (result) => {
console.log(result);
},
mfaSetup: (challengeName, challengeParameters) => {
user.associateSoftwareToken(this);
},
selectMFAType: (challengeName, challengeParameters) => {
user.sendMFASelectionAnswer('SOFTWARE_TOKEN_MFA', this);
},
totpRequired: (secretCode) => {
const challengeAnswer = prompt('Please input the TOTP code.', '');
user.sendMFACode(challengeAnswer, this, 'SOFTWARE_TOKEN_MFA');
},
mfaRequired: (codeDeliveryDetails) => {
const verificationCode = prompt('Please input verification code', '');
user.sendMFACode(verificationCode, this);
}
});
};
const sendVerificationPin = (event) => {
event.preventDefault();
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
user.forgotPassword({
onSuccess: (result) => {
console.log('call result: ', result);
},
onFailure: (err) => {
alert(err);
}
});
};
const onResetPassword = (event) => {
event.preventDefault();
console.log('in reset');
const user = new CognitoUser({
Username: email,
Pool: UserPool
});
console.log('user made');
if (passwordFirst !== passwordSecond) {
alert('the two inputs provided are not the same');
} else {
console.log('inputs are the same');
user.confirmPassword(pin, passwordSecond, {
onSuccess() {
console.log('Password confirmed!');
window.location.reload(true);
},
onFailure(err) {
console.log('Password not confirmed!');
console.log(err);
}
});
}
};
return (
<div>
{!newPasscodeRequired && !forgotPassword && !setupMFA && (
<div>
<form onSubmit={onSubmit}>
<input type="text" required value={email} onChange={(e) => setEmail(e.target.value)} />
<input
type="text"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Login</button>
</form>
<button onClick={(e) => setForgotPassword(true)}>
<Typography sx={{ paddingX: 5 }}>Forgot password?</Typography>
</button>
</div>
)}
{newPasscodeRequired && (
<div>
<form onSubmit={onSubmitPasscode}>
<Typography>New Password</Typography>
<input type="text" required onChange={(e) => setPasswordFirst(e.target.value)} />
<Typography>New Password Again</Typography>
<input type="text" required onChange={(e) => setPasswordSecond(e.target.value)} />
<Typography>New Password Requirements</Typography>
<Typography>
At least 8 characters long, requiring upper and lower case letters, numbers, and
special characters
</Typography>
<button type="submit">Submit new passcode</button>
</form>
</div>
)}
{forgotPassword && !newPasscodeRequired && (
<div>
<form onSubmit={sendVerificationPin}>
<Typography>Please input the email for the account</Typography>
<input type="text" required onChange={(e) => setEmail(e.target.value)} />
<button type="submit">Send verification pin</button>
</form>
<form onSubmit={onResetPassword}>
<Typography>Input the verification pin sent to your email below</Typography>
<input type="text" required onChange={(e) => setPin(e.target.value)} />
<Typography>New Password</Typography>
<input type="text" required onChange={(e) => setPasswordFirst(e.target.value)} />
<Typography>New Password Again</Typography>
<input type="text" required onChange={(e) => setPasswordSecond(e.target.value)} />
<Typography>New Password Requirements</Typography>
<Typography>
At least 8 characters long, requiring upper and lower case letters, numbers, and
special characters
</Typography>
<button type="submit">Reset Password</button>
</form>
</div>
)}
{setupMFA && (
<div>
<div>SetupMFA</div>
<button onClick={(e) => onMFASetup()}>Generate QR Code</button>
</div>
)}
</div>
);
};