UNPKG

@adonis-agora/authkit-react

Version:

Frontend ergonomics over AuthKit for AdonisJS + Inertia + React apps: a typed useAuth() hook, role-gating hooks and gating components.

69 lines (68 loc) 2.51 kB
import { useEffect, useRef } from 'react'; import { loadStartAuthentication } from '../passkey/authenticate.js'; export function usePasskeyAutofill(options) { const { optionsUrl, verifyUrl, onSuccess, csrfToken, enabled = true } = options; const abortRef = useRef(null); useEffect(() => { if (!enabled) return; if (typeof window === 'undefined' || typeof navigator === 'undefined') return; if (!window.PublicKeyCredential) return; let cancelled = false; const ac = new AbortController(); abortRef.current = ac; const run = async () => { try { const supported = typeof PublicKeyCredential.isConditionalMediationAvailable === 'function' ? await PublicKeyCredential.isConditionalMediationAvailable() : false; if (!supported || cancelled) return; let startAuthentication; try { startAuthentication = await loadStartAuthentication(); } catch { return; } if (cancelled) return; const headers = { 'content-type': 'application/json', }; if (csrfToken) headers['x-csrf-token'] = csrfToken; const optRes = await fetch(optionsUrl, { method: 'POST', headers, body: JSON.stringify({}), signal: ac.signal, }); if (!optRes.ok || cancelled) return; const optionsJSON = await optRes.json(); optionsJSON._discoverable = undefined; if (cancelled) return; const assertion = await startAuthentication({ optionsJSON, useBrowserAutofill: true, verifyBrowserAutofillInput: true, }, ac.signal); if (cancelled) return; onSuccess(JSON.stringify(assertion)); } catch { } }; void run(); return () => { cancelled = true; ac.abort(); abortRef.current = null; }; }, [enabled, optionsUrl, verifyUrl, onSuccess, csrfToken]); }