import { startAuthentication, startRegistration, } from "@simplewebauthn/browser"; export const AUTH_HOST = "/api/auth"; export async function initLogin( autofill: boolean, signal?: AbortSignal, ): Promise<{ verified: boolean; credentialID?: string }> { return fetch(`${AUTH_HOST}/webauthn/login`, { signal, credentials: "include", }) .then(checkResponse) .then((opts) => { return startAuthentication({ optionsJSON: opts, useBrowserAutofill: autofill, }); }) .then((assets) => fetch(`${AUTH_HOST}/webauthn/verify`, { credentials: "include", method: "POST", body: JSON.stringify(assets), headers: { "Content-Type": "application/json", }, }), ) .then(checkResponse); } export async function initRegistration( signal?: AbortSignal, useAutoRegister = false, ): Promise<{ verified: boolean; credentialID?: string }> { return fetch(`${AUTH_HOST}/webauthn/register`, { credentials: "include", signal, }) .then(checkResponse) .then((opts) => { return startRegistration({ optionsJSON: opts, useAutoRegister, }); }) .then((assets) => fetch(`${AUTH_HOST}/webauthn/register`, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(assets), }), ) .then((resp) => resp.json()); } export async function checkResponse(resp: Response) { if (!resp.ok) { const message = resp.headers.get("content-type")?.includes("json") ? await resp.json() : await resp.text(); throw new Error(message?.error || message || resp.statusText); } return resp.json(); } export { browserSupportsWebAuthn, browserSupportsWebAuthnAutofill, } from "@simplewebauthn/browser";