I’m working on a custom Action to provide step-up MFA when a user logs in from a new device. This works by passing in the deviceId as a query parameter and when it doesnt match the deviceId in the user metadata, (or first time login) they are pushed into the MFA flow. Upon completion, their metadata is updated and can log in from the known devices stored in their user profile.
The issue I’m having is verifying that they completed MFA before the metadata updated. I’m trying to reference the event.authentication.methods object for this but the Action is executed before event.authentication can be updated. Is there a way to verify MFA has been completed in the login flow before completing some task?
See example below:
exports.onExecutePostLogin = async (event, api) => {
//Pull request_id and visitor_id from query string
let device = event.request.query.device
var array = device.split(" ");
const vid = array[0]
const rid = array[1]
//confirm vid and rid values
let metadata = event.user.app_metadata
//Capture device info in Auth0 user profile
//If user does not have an existing device_id
if(!metadata.device_id){
api.multifactor.enable('any')
}
//force MFA on users logging in from new device
if (metadata.device_id && !event.user.app_metadata.device_id.includes(vid)) {
api.multifactor.enable('any');
}
//verify successful MFA before updating record
if (event.authentication?.methods.find(x => x.name == 'mfa')) {
//Update metadata if MFA is successful
if (!metadata.device_id) {
api.user.setAppMetadata("device_id", [vid]);
console.log('metadata updated')
} else if (!metadata.device_id.includes(vid)) {
let newArr = metadata.device_id;
newArr.unshift(vid)
api.user.setAppMetadata("device_id",newArr );
console.log('MFA triggered based on new device')
}
}
};
Unfortunately as you’ve noticed MFA does not complete until after Actions/Rules have executed - It’s outside the scope of an Action, but you could potentially look at ID token claims to see if MFA was performed, or add a claim to an access token to indicate that MFA was required for a given login and go about it that way. An ID token returned after a login requiring MFA will contain both the acr and amr claims:
( request.env["omniauth.auth"] will be available within your callback route)
As advertised in the previous comment, we can see acr / amr after an MFA authentification. There aren’t present after a standard auth via email/password