@adonis-agora/authkit-react
Version:
Frontend ergonomics over AuthKit for AdonisJS + Inertia + React apps: a typed useAuth() hook, role-gating hooks and gating components.
84 lines (83 loc) • 3.56 kB
JavaScript
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
if (typeof path === "string" && /^\.\.?\//.test(path)) {
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
});
}
return path;
};
import { submitClassicForm } from './classic_form.js';
async function importWebAuthnBrowser() {
return await import(__rewriteRelativeImportExtension('@simplewebauthn/browser'));
}
function missingPeerError(cause) {
return new Error('@adonis-agora/authkit-react: a passkey requer o pacote ' +
'`@simplewebauthn/browser`, que não foi encontrado. Instale-o no seu app ' +
'(`npm i @simplewebauthn/browser@^13`) — ele é uma peer dependency ' +
'opcional, e não uma dependência direta, porque quem faz o bundle do ' +
'frontend é o seu app: embutir uma segunda cópia da lib duplicaria o ' +
'código e brigaria com a versão que você já usa. Este pacote também não ' +
'cai num CDN público: isso colocaria um terceiro dentro do caminho de ' +
'autenticação, em silêncio.', { cause });
}
export async function loadStartAuthentication(importModule = importWebAuthnBrowser) {
try {
const mod = await importModule();
return mod.startAuthentication;
}
catch (cause) {
throw missingPeerError(cause);
}
}
export async function loadStartRegistration(importModule = importWebAuthnBrowser) {
try {
const mod = await importModule();
return mod.startRegistration;
}
catch (cause) {
throw missingPeerError(cause);
}
}
async function fetchCeremonyOptions(optionsUrl, csrfToken, doFetch, signal) {
const headers = {
'content-type': 'application/json',
};
if (csrfToken)
headers['x-csrf-token'] = csrfToken;
const res = await doFetch(optionsUrl, {
method: 'POST',
headers,
body: JSON.stringify({}),
signal,
});
if (!res.ok) {
throw new Error(`passkey options request failed: ${res.status}`);
}
return res.json();
}
export async function authenticatePasskey(options, deps = {}) {
const { optionsUrl, csrfToken, signal } = options;
const doFetch = deps.fetch ?? globalThis.fetch;
const loadFn = deps.loadStartAuthentication ?? loadStartAuthentication;
const optionsJSON = await fetchCeremonyOptions(optionsUrl, csrfToken, doFetch, signal);
const startAuthentication = await loadFn();
const assertion = await startAuthentication({ optionsJSON }, signal);
return JSON.stringify(assertion);
}
export async function registerPasskey(options, deps = {}) {
const { optionsUrl, csrfToken, signal } = options;
const doFetch = deps.fetch ?? globalThis.fetch;
const loadFn = deps.loadStartRegistration ?? loadStartRegistration;
const optionsJSON = await fetchCeremonyOptions(optionsUrl, csrfToken, doFetch, signal);
const startRegistration = await loadFn();
const attestation = await startRegistration({ optionsJSON });
return JSON.stringify(attestation);
}
export function submitPasskeyVerification(options) {
const { verifyUrl, assertion, csrfToken } = options;
const fields = {};
if (csrfToken)
fields._csrf = csrfToken;
fields.response = assertion;
submitClassicForm({ action: verifyUrl, fields });
}