diff options
-rw-r--r-- | example/index.ts | 21 | ||||
-rw-r--r-- | packages/server/src/attestation/generateAttestationOptions.ts | 12 | ||||
-rw-r--r-- | packages/typescript-types/src/index.ts | 2 |
3 files changed, 23 insertions, 12 deletions
diff --git a/example/index.ts b/example/index.ts index b3ecd4d..1492395 100644 --- a/example/index.ts +++ b/example/index.ts @@ -21,6 +21,10 @@ import { generateAssertionOptions, verifyAssertionResponse, } from '@simplewebauthn/server'; +import type { + AttestationCredentialJSON, + AuthenticatorDevice, +} from '@simplewebauthn/typescript-types'; import { LoggedInUser } from './example-server'; @@ -65,15 +69,7 @@ const inMemoryUserDeviceDB: { [loggedInUserId: string]: LoggedInUser } = { [loggedInUserId]: { id: loggedInUserId, username: `user@${rpID}`, - devices: [ - /** - * { - * credentialID: string, - * publicKey: string, - * counter: number, - * } - */ - ], + devices: [], /** * A simple way of storing a user's current challenge being signed by attestation or assertion. * It should be expired after `timeout` milliseconds (optional argument for `generate` methods, @@ -135,7 +131,7 @@ app.get('/generate-attestation-options', (req, res) => { }); app.post('/verify-attestation', async (req, res) => { - const { body } = req; + const body: AttestationCredentialJSON = req.body; const user = inMemoryUserDeviceDB[loggedInUserId]; @@ -165,11 +161,12 @@ app.post('/verify-attestation', async (req, res) => { /** * Add the returned device to the user's list of devices */ - user.devices.push({ + const newDevice: AuthenticatorDevice = { publicKey: base64PublicKey, credentialID: base64CredentialID, counter, - }); + }; + user.devices.push(newDevice); } } diff --git a/packages/server/src/attestation/generateAttestationOptions.ts b/packages/server/src/attestation/generateAttestationOptions.ts index e1fc70e..2c0f85b 100644 --- a/packages/server/src/attestation/generateAttestationOptions.ts +++ b/packages/server/src/attestation/generateAttestationOptions.ts @@ -119,6 +119,18 @@ export default function generateAttestationOptions( type: 'public-key', })); + /** + * "Relying Parties SHOULD set [requireResidentKey] to true if, and only if, residentKey is set + * to "required"" + * + * See https://www.w3.org/TR/webauthn-2/#dom-authenticatorselectioncriteria-requireresidentkey + */ + if (authenticatorSelection.residentKey === 'required') { + authenticatorSelection.requireResidentKey = true; + } else { + authenticatorSelection.requireResidentKey = false; + } + return { challenge: base64url.encode(challenge), rp: { diff --git a/packages/typescript-types/src/index.ts b/packages/typescript-types/src/index.ts index 436f7ff..c950398 100644 --- a/packages/typescript-types/src/index.ts +++ b/packages/typescript-types/src/index.ts @@ -116,6 +116,8 @@ export type AuthenticatorDevice = { credentialID: Base64URLString; // Number of times this device is expected to have been used counter: number; + // From browser's `startAttestation()` -> AttestationCredentialJSON.transports (API L2 and up) + transports?: AuthenticatorTransport[]; }; /** |