Skip to content
This repository was archived by the owner on Jul 28, 2026. It is now read-only.

Commit 496e0c3

Browse files
committed
fix: convert base64url options to ArrayBuffer before passing to navigator.credentials
1 parent e7bd0dd commit 496e0c3

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

public/js/app.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,34 @@ function base64UrlFromBuffer(buf) {
152152
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
153153
}
154154

155+
function bufferFromBase64Url(str) {
156+
str = str.replace(/-/g, '+').replace(/_/g, '/');
157+
while (str.length % 4) str += '=';
158+
const binary = atob(str);
159+
const bytes = new Uint8Array(binary.length);
160+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
161+
return bytes.buffer;
162+
}
163+
164+
function prepareWebAuthnOptions(opts) {
165+
const o = JSON.parse(JSON.stringify(opts));
166+
if (o.challenge) o.challenge = bufferFromBase64Url(o.challenge);
167+
if (o.user?.id) o.user.id = bufferFromBase64Url(o.user.id);
168+
if (o.excludeCredentials) {
169+
o.excludeCredentials = o.excludeCredentials.map(c => ({
170+
...c,
171+
id: typeof c.id === 'string' ? bufferFromBase64Url(c.id) : c.id,
172+
}));
173+
}
174+
if (o.allowCredentials) {
175+
o.allowCredentials = o.allowCredentials.map(c => ({
176+
...c,
177+
id: typeof c.id === 'string' ? bufferFromBase64Url(c.id) : c.id,
178+
}));
179+
}
180+
return o;
181+
}
182+
155183
function serializeCredential(cred) {
156184
const res = {};
157185
for (const key of Object.keys(cred)) {
@@ -630,7 +658,7 @@ async function handlePasskeyLogin() {
630658
});
631659

632660
const credential = await navigator.credentials.get({
633-
publicKey: beginData.options,
661+
publicKey: prepareWebAuthnOptions(beginData.options),
634662
});
635663

636664
const completeData = await api('/auth/passkeys/login/complete', {
@@ -2372,7 +2400,7 @@ async function handleRegisterPasskey() {
23722400
});
23732401

23742402
const credential = await navigator.credentials.create({
2375-
publicKey: beginData.options,
2403+
publicKey: prepareWebAuthnOptions(beginData.options),
23762404
});
23772405

23782406
await api('/auth/passkeys/register/complete', {

0 commit comments

Comments
 (0)