UNPKG

@userfront/core

Version:
134 lines (124 loc) 3.11 kB
import { post, put } from "./api.js"; import { store } from "./store.js"; import { throwFormattedError } from "./utils.js"; import { handleLoginResponse } from "./authentication.js"; import { getMfaHeaders, isFirstFactorTokenPresent } from "./mfa.js"; import { getPkceRequestQueryParams } from "./pkce.js"; /** * Verify that proper identifier is available for the channel * @property {String} channel "sms" or "email" * @property {String} phoneNumber * @property {String} email */ function enforceChannel({ channel, phoneNumber, email }) { // Enforce valid channels if (channel !== "sms" && channel !== "email") { throw new Error("Invalid channel"); } // Do not require phoneNumber or email when firstFactorToken is included if (isFirstFactorTokenPresent()) { return; } // Check that phoneNumber or email are present if needed if (channel === "sms" && !phoneNumber) { throw new Error(`SMS verification code requires "phoneNumber"`); } else if (channel === "email" && !email) { throw new Error(`Email verification code requires "email"`); } } /** * Send a verification code to the provided email address or phone number. * @property {String} channel "sms" (default) or "email" * @property {String} phoneNumber * @property {String} email * @property {String} name * @property {String} username * @property {Object} data */ export async function sendVerificationCode({ channel = "sms", phoneNumber, email, name, username, data, }) { try { enforceChannel({ channel, phoneNumber, email, }); const { tenantId } = store; const { data: res } = await post( `/tenants/${tenantId}/auth/code`, { channel, email, phoneNumber, name, username, data, }, { headers: getMfaHeaders(), } ); return res; } catch (error) { throwFormattedError(error); } } /** * Log a user in with a token/uuid combo passed into the function or * in the URL querystring. ?token=...&uuid=... * @param {String} token * @param {UUID} uuid * @param {String} redirect - do not redirect if false, or redirect to given path */ export async function loginWithVerificationCode({ channel, verificationCode, email, phoneNumber, redirect, handleUpstreamResponse, handleMfaRequired, handlePkceRequired, handleTokens, handleRedirect, } = {}) { try { enforceChannel({ channel, phoneNumber, email, }); const { tenantId } = store; const { data } = await put( `/tenants/${tenantId}/auth/code`, { channel, verificationCode, email, phoneNumber, }, { headers: getMfaHeaders(), params: getPkceRequestQueryParams(), } ); // Handle the API response to the login request return handleLoginResponse({ data, redirect, handleUpstreamResponse, handleMfaRequired, handlePkceRequired, handleTokens, handleRedirect, }); } catch (error) { throwFormattedError(error); } }