Skip to content

Commit 6763f16

Browse files
committed
use test-passkey for passkey tests
1 parent 2cdf595 commit 6763f16

File tree

5 files changed

+36
-51
lines changed

5 files changed

+36
-51
lines changed

exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/authentication.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ export async function action({ request }: Route.ActionArgs) {
6464
},
6565
})
6666

67-
console.log(333)
68-
6967
if (!verification.verified) {
7068
throw new Error('Authentication verification failed')
7169
}

exercises/02.authentication/03.solution.passkeys/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@
138138
"@types/source-map-support": "^0.5.10",
139139
"@vitejs/plugin-react": "^4.4.1",
140140
"@vitest/coverage-v8": "^3.1.3",
141-
"cbor": "^10.0.11",
142141
"enforce-unique": "^1.3.0",
143142
"esbuild": "^0.25.3",
144143
"eslint": "^9.26.0",
@@ -152,6 +151,7 @@
152151
"prettier-plugin-tailwindcss": "^0.6.11",
153152
"react-router-devtools": "^5.0.5",
154153
"remix-flat-routes": "^0.8.5",
154+
"test-passkey": "^1.0.1",
155155
"tsx": "^4.19.4",
156156
"tw-animate-css": "^1.2.9",
157157
"typescript": "^5.8.3",

exercises/02.authentication/03.solution.passkeys/tests/db-utils.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { faker } from '@faker-js/faker'
22
import bcrypt from 'bcryptjs'
33
import { UniqueEnforcer } from 'enforce-unique'
4-
import { prisma } from '#app/utils/db.server.ts'
54
import { getPasswordHash } from '#app/utils/auth.server.ts'
5+
import { prisma } from '#app/utils/db.server.ts'
66

77
const uniqueUsernameEnforcer = new UniqueEnforcer()
88

@@ -51,21 +51,23 @@ export async function createUser() {
5151
}
5252
}
5353

54-
export async function createPasskey(input: { userId: string; publicKey: any }) {
54+
export async function createPasskey(input: {
55+
id: string
56+
userId: string
57+
aaguid: string
58+
publicKey: Uint8Array
59+
counter?: number
60+
}) {
5561
const passkey = await prisma.passkey.create({
5662
data: {
57-
/**
58-
* @note This has to be base64-encoded because WebAuthn expects that encoding.
59-
* Store the same encoded value in the database so the keypass could be looked up by ID.
60-
*/
61-
id: Buffer.from(crypto.randomUUID()).toString('base64'),
62-
aaguid: Buffer.from(new Uint8Array(16)).toString('base64'),
63+
id: input.id,
64+
aaguid: input.aaguid,
6365
userId: input.userId,
6466
publicKey: input.publicKey,
6567
backedUp: false,
6668
webauthnUserId: input.userId,
6769
deviceType: 'singleDevice',
68-
counter: 0,
70+
counter: input.counter || 0,
6971
},
7072
})
7173

exercises/02.authentication/03.solution.passkeys/tests/e2e/auth-passkeys.test.ts

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { generateKeyPairSync } from 'node:crypto'
21
import { type Page } from '@playwright/test'
3-
import cbor from 'cbor'
2+
import { createTestPasskey } from 'test-passkey'
43
import { createPasskey, createUser } from '#tests/db-utils.ts'
54
import { test, expect } from '#tests/test-extend.ts'
65

@@ -25,57 +24,33 @@ async function createWebAuthnClient(page: Page) {
2524
}
2625
}
2726

28-
function generateKeys() {
29-
const { privateKey, publicKey } = generateKeyPairSync('ec', {
30-
namedCurve: 'P-256',
31-
})
32-
33-
const spkiPublicKey = publicKey.export({ type: 'spki', format: 'der' })
34-
const publicKeyBytes = spkiPublicKey.subarray(-65)
35-
const x = publicKeyBytes.subarray(1, 33)
36-
const y = publicKeyBytes.subarray(33, 65)
37-
38-
const cosePublickey = cbor.encode(
39-
new Map<number, number | Buffer>([
40-
[1, 2],
41-
[3, -7],
42-
[-1, 1],
43-
[-2, x],
44-
[-3, y],
45-
]),
46-
)
47-
48-
return {
49-
privateKey: privateKey
50-
.export({ type: 'pkcs8', format: 'der' })
51-
.toString('base64'),
52-
publicKey: cosePublickey,
53-
}
54-
}
55-
5627
test('authenticates using a passkey', async ({ navigate, page }) => {
5728
await navigate('/login')
5829

59-
const { client, authenticatorId } = await createWebAuthnClient(page)
30+
const passkey = createTestPasskey({
31+
rpId: new URL(page.url()).hostname,
32+
})
6033

61-
const keys = generateKeys()
34+
// Add the passkey to the server.
6235
await using user = await createUser()
63-
await using passkey = await createPasskey({
36+
await using _ = await createPasskey({
37+
id: passkey.credential.credentialId,
38+
aaguid: passkey.credential.aaguid || '',
39+
publicKey: passkey.publicKey,
6440
userId: user.id,
65-
publicKey: keys.publicKey,
41+
counter: passkey.credential.signCount,
6642
})
6743

44+
// Add the passkey to the browser.
45+
const { client, authenticatorId } = await createWebAuthnClient(page)
6846
await client.send('WebAuthn.addCredential', {
6947
authenticatorId,
7048
credential: {
71-
rpId: new URL(page.url()).hostname,
72-
credentialId: passkey.id,
73-
signCount: 0,
49+
...passkey.credential,
7450
isResidentCredential: true,
7551
userName: user.username,
7652
userHandle: btoa(user.id),
7753
userDisplayName: user.name ?? user.email,
78-
privateKey: keys.privateKey,
7954
},
8055
})
8156

package-lock.json

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)