35 lines
1.2 KiB
JavaScript
35 lines
1.2 KiB
JavaScript
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.trim();
|
|
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 account.");
|
|
return;
|
|
}
|
|
const data = await start.json();
|
|
const pk = data.publicKey;
|
|
pk.challenge = b64ToBytes(pk.challenge);
|
|
if (pk.allowCredentials) {
|
|
pk.allowCredentials.forEach((c) => (c.id = b64ToBytes(c.id)));
|
|
}
|
|
const credential = await navigator.credentials.get({ publicKey: pk });
|
|
const finish = await fetch("/auth/passkey/login/finish", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ token: data.token, response: credential }),
|
|
});
|
|
if (finish.ok) {
|
|
window.location.href = "/lists";
|
|
}
|
|
});
|