Client for Auth0 MFA API operations

Manages multi-factor authentication including:

  • Listing enrolled authenticators
  • Enrolling new authenticators (OTP, SMS, Voice, Push, Email)
  • Initiating MFA challenges
  • Verifying MFA challenges

This is a wrapper around auth0-auth-js MfaClient that maintains backward compatibility with the existing spa-js API.

MFA context (scope, audience) is stored internally keyed by mfaToken, enabling concurrent MFA flows without state conflicts.

Example

try {
await auth0.getTokenSilently({ authorizationParams: { audience: 'https://api.example.com' } });
} catch (e) {
if (e instanceof MfaRequiredError) {
// SDK automatically stores context for this mfaToken
const authenticators = await auth0.mfa.getAuthenticators({ mfaToken: e.mfa_token });
// ... complete MFA flow
}
}

Methods

  • Initiates an MFA challenge

    Sends OTP via SMS, initiates push notification, or prepares for OTP entry

    Parameters

    Returns Promise<ChallengeResponse>

    Challenge response with oobCode if applicable

    Throws

    If challenge initiation fails

    Example: OTP challenge

    const challenge = await mfa.challenge({
    mfaToken: mfaTokenFromLogin,
    challengeType: 'otp',
    authenticatorId: 'otp|dev_xxx'
    });
    // User enters OTP from their authenticator app

    Example: SMS challenge

    const challenge = await mfa.challenge({
    mfaToken: mfaTokenFromLogin,
    challengeType: 'oob',
    authenticatorId: 'sms|dev_xxx'
    });
    console.log(challenge.oobCode); // Use for verification
  • Enrolls a new MFA authenticator

    Requires MFA access token with 'enroll' scope

    Parameters

    • params: EnrollParams

      Enrollment parameters including mfaToken and factorType

    Returns Promise<EnrollmentResponse>

    Enrollment response with authenticator details

    Throws

    If enrollment fails

    Example: OTP enrollment

    const enrollment = await mfa.enroll({
    mfaToken: mfaToken,
    factorType: 'otp'
    });
    console.log(enrollment.secret); // Base32 secret
    console.log(enrollment.barcodeUri); // QR code URI

    Example: SMS enrollment

    const enrollment = await mfa.enroll({
    mfaToken: mfaToken,
    factorType: 'sms',
    phoneNumber: '+12025551234'
    });
  • Gets enrolled MFA authenticators filtered by challenge types from context.

    Challenge types are automatically resolved from the stored MFA context (set when mfa_required error occurred).

    Parameters

    • mfaToken: string

      MFA token from mfa_required error

    Returns Promise<Authenticator[]>

    Array of enrolled authenticators matching the challenge types

    Throws

    If the request fails or context not found

    Example: Basic usage

    try {
    await auth0.getTokenSilently();
    } catch (e) {
    if (e instanceof MfaRequiredError) {
    // SDK automatically uses challenge types from error context
    const authenticators = await auth0.mfa.getAuthenticators(e.mfa_token);
    }
    }
  • Gets available MFA enrollment factors from the stored context.

    This method exposes the enrollment options from the mfa_required error's mfaRequirements.enroll array, eliminating the need for manual parsing.

    Parameters

    • mfaToken: string

      MFA token from mfa_required error

    Returns Promise<EnrollmentFactor[]>

    Array of enrollment factors available for the user (empty array if no enrollment required)

    Throws

    If MFA context not found

    Example: Basic usage

    try {
    await auth0.getTokenSilently();
    } catch (error) {
    if (error.error === 'mfa_required') {
    // Get enrollment options from SDK
    const enrollOptions = await auth0.mfa.getEnrollmentFactors(error.mfa_token);
    // [{ type: 'otp' }, { type: 'phone' }, { type: 'push-notification' }]

    showEnrollmentOptions(enrollOptions);
    }
    }

    Example: Check if enrollment is required

    try {
    const factors = await auth0.mfa.getEnrollmentFactors(mfaToken);
    if (factors.length > 0) {
    // User needs to enroll in MFA
    renderEnrollmentUI(factors);
    } else {
    // No enrollment required, proceed with challenge
    }
    } catch (error) {
    if (error instanceof MfaEnrollmentFactorsError) {
    console.error('Context not found:', error.error_description);
    }
    }
  • Verifies an MFA challenge and completes authentication

    The scope and audience are retrieved from the stored context (set when the mfa_required error occurred). The grant_type is automatically inferred from which verification field is provided (otp, oobCode, or recoveryCode).

    Parameters

    • params: VerifyParams

      Verification parameters with OTP, OOB code, or recovery code

    Returns Promise<TokenEndpointResponse>

    Token response with access_token, id_token, refresh_token

    Throws

    If verification fails (invalid code, expired, rate limited)

    Throws

    If MFA context not found

    Throws

    If grant_type cannot be inferred

    Rate limits:

    • 10 verification attempts allowed
    • Refreshes at 1 attempt per 6 minutes

    Example: OTP verification (grant_type inferred from otp field)

    const tokens = await mfa.verify({
    mfaToken: mfaTokenFromLogin,
    otp: '123456'
    });
    console.log(tokens.access_token);

    Example: OOB verification (grant_type inferred from oobCode field)

    const tokens = await mfa.verify({
    mfaToken: mfaTokenFromLogin,
    oobCode: challenge.oobCode,
    bindingCode: '123456' // Code user received via SMS
    });

    Example: Recovery code verification (grant_type inferred from recoveryCode field)

    const tokens = await mfa.verify({
    mfaToken: mfaTokenFromLogin,
    recoveryCode: 'XXXX-XXXX-XXXX'
    });