Hello, we’ve migrated from rules to actions where we had conditional MFA enabled for certain users.
This however is causing OTP Auth Failed errors for users which have had MFA enabled before the migration. Manually deleting the MFA and having the users setup MFA again solves the issue.
How can I make this migration/transition uninterrupting for our users?
This is our action code used
const domainNeedsMFA = (userEmail) => {
const domainsWithMFA = [
'@example.com',
];
// check if the specific user needs MFA
return domainsWithMFA.some((domain)=>{
if (userEmail.endsWith(domain)){
return true;
}
return false;
});
}
/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
/**
* The following code block will skip this Action if Rule "MFA enforcement"
* was previously executed in the transaction in order to avoid duplication
* of logic.
*/
if (api.rules.wasExecuted("rul_XXXXXXXXX")) {
return;
}
// check if the specific user needs MFA
const mfaRequired = domainNeedsMFA(event.user.email)
if (!mfaRequired) {
return;
}
// bypass mfa for refresh token requests
// see https://auth0.com/docs/secure/multi-factor-authentication/customize-mfa#bypass-mfa-for-refresh-token-requests
if (event.transaction?.protocol === 'oauth2-refresh-token') {
return;
}
// force the user to setup MFA
const enrolledFactors = event.user.multifactor || [];
const mfaProvider = event.user.multifactor[0] || 'any'
if (enrolledFactors.length === 0) {
// The user has not enrolled in any MFA factor yet, trigger an MFA enrollment
api.multifactor.enable('any', { allowRememberBrowser: false });
}
else {
// check if session already did a MFA
// if the array of authentication methods is valid and contains a method named 'mfa', mfa has been done in this session already
if (
!event.authentication ||
!Array.isArray(event.authentication.methods) ||
!event.authentication.methods.find((method) => method.name === 'mfa')
) {
api.multifactor.enable(
mfaProvider,
{
// optional, defaults to true. Set to false to force authentication every time.
// See https://auth0.com/docs/secure/multi-factor-authentication/customize-mfa#change-frequency-of-mfa-prompts for details
allowRememberBrowser: false
}
);
}
}
};
Thanks for reviewing the code and confirming that its not an obvious error.
Both test-users facing issues had setup multifactor on 2021-08-12T07:45:42.915Z and use guardian type. Have there been any changes to MFA/2FA in recent years at auth0?
Or is there any option/field within auth0 which would “reset” the MFA/2FA for all users somehow?
Following a redacted tenant log of a failed auth which just says OTP is invalid.
AFAIK, there have been no changes to MFA/2FA in recent years. I don’t believe there is any option that enforces an MFA/2FA reset for all users, so this shouldn’t be possible. However, you can delete (reset) a user’s MFA enrollments through the Management API’s delete an authenticator endpoint.
Judging from the error log you shared, it looks to be an issue with the OTP being invalid.
There might be issues with the Guardian app being out of sync. Usually, in this case, you would need to re-enroll in MFA to resolve this issue.
Now, you mentioned previously that this issue originated after migrating from Rules to Actions.
Could you double-check if your test users can log in as usual if you disable your Action script? I am checking to see if back-tracking your changes addresses this issue.
Additionally, you can monitor your Rules/Action script success/failure using the Real-time Webtask Logs Extension with console.log() statements.
Thank you for your hints and validating that the code works as intended.
I now double checked the code with real customers and it indeed works as you had confirmed. Something must be wrong with our test users and I will thus reset their MFA.