Hey,
I’m trying to force MFA enrollment in a post login action. I’m able to successfully challenge users that are already enrolled in MFA, but when I try to enroll users into MFA, it’s sending the user straight through authentication successfully without asking them to enroll.
This is the code I have in my action:
exports.onExecutePostLogin = async (event, api) => {
api.user.setUserMetadata("login_location", event.request.geoip.cityName);
api.user.setUserMetadata("last_login_date", Date.now());
// If user has enrolled in MFA...
if (event.user.enrolledFactors.length) {
// If login location has changed, require MFA.
if (event.user.user_metadata.login_location != event.request.geoip.cityName) {
api.multifactor.enable("any");
}
// If last login date is > than 30 days ago, require MFA.
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
if (event.user.user_metadata.last_login_date < Date.now() - 1000) {
api.multifactor.enable("any");
}
}
// If user not enrolled in MFA...
else {
api.authentication.enrollWithAny([{type: 'webauthn-roaming'}, {type: 'otp'}]);
}
}
My expectation from the above code is as follows:
If the user has previously enrolled in MFA and they meet either of the two requirements needed for MFA (location change or last login date > 30 days ago - they are challenged with the MFA.
If the user hasn’t previously enrolled then they should be sent to the screen where they can scan a QR code for authenticator app and enroll with MFA.
As it stands, the api.authentication.enrollWithAny([{type: 'webauthn-roaming'}, {type: 'otp'}]);
line isn’t doing anything. The user is authenticated without any MFA challenge or enrollment.
I am having a very similar issue. Any help would be much appreciated!
Hey Alex,
I’ve managed to get this working eventually using the following:
exports.onExecutePostLogin = async (event, api) => {
api.user.setUserMetadata("login_location", event.request.geoip.cityName);
api.user.setUserMetadata("last_login_date", Date.now());
// If user has enrolled in MFA...
if (event.user.enrolledFactors.length) {
// If login location has changed, require MFA.
if (event.user.user_metadata.login_location !== event.request.geoip.cityName) {
api.multifactor.enable("all");
}
// If last login date is > than 30 days ago, require MFA.
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
if (event.user.user_metadata.last_login_date < Date.now() - THIRTY_DAYS) {
api.multifactor.enable("all");
}
}
// If user not enrolled in MFA...
else {
api.multifactor.enable('any');
api.authentication.enrollWithAny([{type: 'webauthn-roaming'}, {type: 'otp'}]);
}
}
I couldn’t see this documented anywhere, but it looks like you also need to enable multifactor before trying to force enrolling. So adding this line is what fixed it for me:
api.multifactor.enable('any');
Note that this requires the MFA option in the Auth0 settings to be set to “Never”.
Hope this helps!
Hey Luke,
Thanks for your reply!
For some reason when I try this, no matter what I do, I receive an SMS code. I can’t seem to enroll in any ‘new’ MFA methods if I already have one set up. Not sure if you ran into this same problem but any advise would be much appreciated!