Documentation navigation
← Back to Jupiter Auth

Multi-factor Authentication

Enroll, challenge, verify, list, and remove TOTP, phone, and WebAuthn factors.

Enroll a TOTP factor

Enrollment returns an unverified factor plus its secret, URI, and QR code. Complete a challenge before treating it as active.

const { data: factor, error } =  await client.auth.mfa.enroll({    factorType: 'totp',    friendlyName: 'Authenticator app',    issuer: 'Jupiter'  }) if (error || !factor) throw error console.log(factor.totp.qr_code)

Challenge and verify TOTP

challengeAndVerify creates the factor challenge and verifies the TOTP code in one request flow. Successful verification returns the higher-assurance session and emits MFA_CHALLENGE_VERIFIED.

const { data: factor, error: enrollError } =  await client.auth.mfa.enroll({    factorType: 'totp',    friendlyName: 'Authenticator app'  }) if (enrollError || !factor) throw enrollError const { data, error } =  await client.auth.mfa.challengeAndVerify({    factorId: factor.id,    code: verificationCode  })

Phone factors

Enroll the phone factor, request an SMS challenge, then verify the received code with the factor and challenge identifiers.

const { data: factor, error } =  await client.auth.mfa.enroll({    factorType: 'phone',    friendlyName: 'Primary phone',    phone: '+15551234567'  }) if (error || !factor) throw error const { data: challenge } = await client.auth.mfa.challenge({  factorId: factor.id,  channel: 'sms'}) if (!challenge) throw new Error('MFA challenge failed') const result = await client.auth.mfa.verify({  factorId: factor.id,  challengeId: challenge.id,  code: verificationCode})

List factors and assurance level

listFactors groups enrolled factors into all, totp, phone, and webauthn collections. getAuthenticatorAssuranceLevel returns the current level, the next available level, and the authentication methods used by the current session.

const factorResult = await client.auth.mfa.listFactors()const assuranceResult =  await client.auth.mfa.getAuthenticatorAssuranceLevel() if (factorResult.error) {  throw factorResult.error} if (assuranceResult.error) {  throw assuranceResult.error} console.log(factorResult.data.all)console.log(assuranceResult.data.currentLevel)console.log(assuranceResult.data.nextLevel)

Remove a factor

unenroll removes the factor identified by factorId from the current user.

const { data, error } = await client.auth.mfa.unenroll({  factorId})