Hi guys. I’m trying to enforce MFA for users that have enabled the feature in my app. To do this, I’m storing an array in the user metadata with the authentication factors the user has enabled in the app, for example ['sms', 'email', 'otp']
.
I’ve checked all the documentation I’ve been able to find related to MFA, and this article in particular.
According to that article, there are two methods available in the Action Post-Login flow that could help me accomplish what I’m trying to do:
-
api.authentication.challengeWithAny
-
api.authentication.challengeWith
I’ve tried both methods several times, but they don’t seem to work. When the user logs in, the MFA flow is never triggered, and goes directly to the app.
The only method that triggers the MFA flow so far is api.multifactor.enable('any')
, however this method triggers the MFA with the factors available at tenant level (with SMS as the main factor), which doesn’t work for what I’m trying to accomplish.
I also saw some discrepancy in the documentation because on the article I mentioned, the first example is this:
api.authentication.challengeWithAny([{ type: 'sms'}, { type: 'push-notification' }]);
And then, later on it uses ‘phone’ instead of ‘sms’:
api.authentication.challengeWithAny([{type: 'otp'}, {type: 'phone'}]);
However, at the top of the articles, before the examples, it clearly shows the name for each factor, which coincides with the documentation for the post-login api object.
I’ve tried all I could think of but didn’t have any luck. Am I missing something?
This is my action’s code:
exports.onExecutePostLogin = async (event, api) => {
if (event.transaction?.protocol === "oauth2-refresh-token") {
return;
}
const enabledFactors = event.user.user_metadata.mfa_enabled_factors;
// Check if the user has opted-in for MFA
if (event.user.user_metadata && enabledFactors && enabledFactors.length > 0) {
try {
const factors = enabledFactors.map((factor) => {
if (factor === 'sms') {
return {
type: 'phone',
options: {
preferredMethod: 'sms'
}
}
}
return {
type: factor
}
})
api.authentication.challengeWithAny(factors)
}
catch (error) {
console.log(error)
}
}
}
Additionally, I’m not sure if it’s relevant, but I’m using passwordless authentication as the primary method for signin in.
Thanks in advance.