import { BrowserPasskeyAuth } from "jazz-tools/browser"; import { useAuthSecretStorage, useIsAuthenticated, useJazzContextValue, } from "jazz-tools/react-core"; import { useMemo, useState } from "react"; /** * `usePasskeyAuth` hook provides a `JazzAuth` object for passkey authentication. * * @example * ```ts * const auth = usePasskeyAuth({ appName, appHostname }); * ``` * * @category Auth Providers */ export function usePasskeyAuth({ appName, appHostname, }: { appName: string; appHostname?: string; }) { const context = useJazzContextValue(); const authSecretStorage = useAuthSecretStorage(); if ("guest" in context) { throw new Error("Passkey auth is not supported in guest mode"); } const authMethod = useMemo(() => { return new BrowserPasskeyAuth( context.node.crypto, context.authenticate, authSecretStorage, appName, appHostname, ); }, [appName, appHostname, authSecretStorage]); const isAuthenticated = useIsAuthenticated(); return { state: isAuthenticated ? "signedIn" : "anonymous", logIn: authMethod.logIn, signUp: authMethod.signUp, } as const; } export const PasskeyAuthBasicUI = (props: { appName: string; appHostname?: string; children?: React.ReactNode; }) => { const [username, setUsername] = useState(""); const [error, setError] = useState(null); const auth = usePasskeyAuth({ appName: props.appName, appHostname: props.appHostname, }); if (auth.state === "signedIn") { return props.children ?? null; } const { logIn, signUp } = auth; function handleError(error: Error) { if (error.cause instanceof Error) { setError(error.cause.message); } else { setError(error.message); } } return (
{error && (
{error}
)}
{ e.preventDefault(); setError(null); signUp(username).catch(handleError); }} > setUsername(e.target.value)} autoComplete="webauthn" style={{ border: "2px solid #000", padding: "11px 8px", borderRadius: "6px", }} />
); };