function b64ToBytes(b64) { const bin = atob(b64.replace(/-/g, "+").replace(/_/g, "/")); const bytes = new Uint8Array(bin.length); for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i); return bytes; } document.getElementById("passkey-login").addEventListener("click", async () => { const email = document.getElementById("email").value; if (!email) { alert("Enter your email first."); return; } const start = await fetch("/auth/passkey/login/start", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email }), }); if (!start.ok) { alert("No passkey found for that email."); return; } const options = await start.json(); const pk = options.publicKey; pk.challenge = b64ToBytes(pk.challenge); if (pk.allowCredentials) { pk.allowCredentials.forEach((c) => (c.id = b64ToBytes(c.id))); } const credential = await navigator.credentials.get(options); const finish = await fetch("/auth/passkey/login/finish", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ response: credential }), }); if (finish.ok) { window.location.href = "/lists"; } });