Skip to content

Commit ac763a8

Browse files
committed
feat(web-demo): add login flow and rework PasskeyDemo UI
Replace access-token-based initialization with a proper login flow using WebCryptoHmacStrategy + IndexedDbTokenStore for browser-compatible HMAC auth. Rework the UI to map 1:1 to passkey-crypto SDK functions with explicit inputs, split passkey selection buttons, colored activity log, and wallet keychain fetching for webauthnDevices display. TICKET: WCN-188
1 parent 70da36d commit ac763a8

3 files changed

Lines changed: 703 additions & 298 deletions

File tree

modules/passkey-crypto/src/derivePasskeyPrfKey.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { buildEvalByCredential, matchDeviceByCredentialId } from './prfHelpers';
33
import { derivePassword } from './derivePassword';
44
import type { WebAuthnProvider } from './webAuthnTypes';
55

6-
interface AssertionChallengeResponse {
6+
interface AuthChallengeResponse {
77
challenge: string;
8+
allowCredentials?: Array<{ id: string; type: string; transports?: string[] }>;
9+
origin?: string;
810
}
911

1012
/**
@@ -36,16 +38,15 @@ export async function derivePasskeyPrfKey(params: {
3638
throw new Error('No passkey devices available with a valid PRF salt');
3739
}
3840

39-
// Fetch a server-issued assertion challenge
40-
const { challenge } = (await bitgo
41-
.get(bitgo.url('/user/otp/webauthn/assertion', 2))
42-
.result()) as AssertionChallengeResponse;
41+
// Fetch a server-issued assertion challenge via the auth endpoint
42+
const { challenge } = (await bitgo.get(bitgo.url('/user/otp/webauthn/auth', 2)).result()) as AuthChallengeResponse;
4343

44-
// Build allowCredentials from the evalByCredential map so the browser
45-
// knows which credentials are valid for the PRF extension.
44+
// Build allowCredentials so the browser knows which credentials to use.
45+
// Pass the Buffer (Uint8Array) directly — not .buffer — so the provider
46+
// layer can correctly slice it via ArrayBuffer.isView.
4647
const allowCredentials = Object.keys(evalByCredential).map((credId) => ({
4748
type: 'public-key' as const,
48-
id: Buffer.from(credId.replace(/-/g, '+').replace(/_/g, '/'), 'base64').buffer,
49+
id: Buffer.from(credId.replace(/-/g, '+').replace(/_/g, '/'), 'base64') as unknown as ArrayBuffer,
4950
}));
5051

5152
// Trigger WebAuthn assertion with PRF evaluation via the provider (navigator layer)

modules/passkey-crypto/test/unit/derivePasskeyPrfKey.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe('derivePasskeyPrfKey', function () {
7373
assert.strictEqual(getCallArgs.evalByCredential['cred-bbb'], 'salt-bbb');
7474
// Verify bitgo was used to fetch the assertion challenge
7575
assert.ok(mockBitGo.get.calledOnce);
76-
assert.ok(mockBitGo.url.calledWith('/user/otp/webauthn/assertion', 2));
76+
assert.ok(mockBitGo.url.calledWith('/user/otp/webauthn/auth', 2));
7777
});
7878

7979
it("should throw 'No passkey devices available' when no devices", async function () {

0 commit comments

Comments
 (0)