fix: WebAuthn config typo and improve error handling
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 1m41s

- Fix WEBAUTHN_ORIGIN -> WEBAUTHN_ORIGINS env var name
- Add null check for cancelled passkey creation
- Use finally block to ensure loading state is always reset
- Add console.error for better debugging
This commit is contained in:
Gan, Jimmy
2026-03-11 00:53:28 +08:00
parent 75cfafd388
commit 2f8a5d84dc
3 changed files with 43 additions and 11 deletions
+36 -9
View File
@@ -23,19 +23,46 @@ export function setRefreshToken() {}
let refreshPromise = null;
function getLegacyRefreshToken() {
return localStorage.getItem("refresh_token") || "";
}
function clearLegacyRefreshToken() {
localStorage.removeItem("refresh_token");
}
async function requestRefresh(body) {
const r = await fetch(BASE + "/auth/refresh", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "same-origin",
body: body ? JSON.stringify(body) : undefined,
});
if (!r.ok) return false;
const data = await r.json();
setToken(data.access_token || "");
return !!data.access_token;
}
export async function tryRefreshSession() {
if (refreshPromise) return refreshPromise;
refreshPromise = (async () => {
try {
const r = await fetch(BASE + "/auth/refresh", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "same-origin",
});
if (!r.ok) return false;
const data = await r.json();
setToken(data.access_token || "");
return !!data.access_token;
const cookieRefreshed = await requestRefresh();
if (cookieRefreshed) {
clearLegacyRefreshToken();
return true;
}
const legacyRefreshToken = getLegacyRefreshToken();
if (!legacyRefreshToken) return false;
const legacyRefreshed = await requestRefresh({ refresh_token: legacyRefreshToken });
if (legacyRefreshed) {
clearLegacyRefreshToken();
return true;
}
clearLegacyRefreshToken();
return false;
} catch {
return false;
} finally {
@@ -49,6 +49,9 @@
opts.excludeCredentials = opts.excludeCredentials.map(c => ({ ...c, id: base64urlToBuffer(c.id) }));
}
const cred = await navigator.credentials.create({ publicKey: opts });
if (!cred) {
throw new Error("Passkey creation was cancelled");
}
const name = prompt("Name this passkey (e.g. MacBook, iPhone):", "Passkey") || "Passkey";
const body = {
id: cred.id,
@@ -64,9 +67,11 @@
passkeyMsg = "Passkey registered successfully";
await loadPasskeys();
} catch (e) {
console.error("Passkey registration error:", e);
passkeyErr = e.body?.detail || e.message || "Failed to register passkey";
} finally {
passkeyLoading = false;
}
passkeyLoading = false;
}
async function clearPasskeys() {