Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
AuthenticatorTransport,
PublicKeyCredentialDescriptor,
PublicKeyCredentialDescriptorJSON,
PublicKeyCredentialType,
} from '../types/index.ts';
import { base64URLStringToBuffer } from './base64URLStringToBuffer.ts';

Expand All @@ -13,11 +14,7 @@ export function toPublicKeyCredentialDescriptor(
return {
...descriptor,
id: base64URLStringToBuffer(id),
/**
* `descriptor.transports` is an array of our `AuthenticatorTransportFuture` that includes newer
* transports that TypeScript's DOM lib is ignorant of. Convince TS that our list of transports
* are fine to pass to WebAuthn since browsers will recognize the new value.
*/
transports: descriptor.transports as AuthenticatorTransport[],
type: descriptor.type as PublicKeyCredentialType,
};
}
5 changes: 4 additions & 1 deletion packages/browser/src/methods/startAuthentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ export async function startAuthentication(
// Wait for the user to complete assertion
let credential;
try {
credential = (await navigator.credentials.get(getOptions as globalThis.CredentialRequestOptions)) as AuthenticationCredential;
credential = (await navigator.credentials.get(
// TODO: Newer versions of Deno require this casting, revisit once we're using Deno 2.6+
getOptions as globalThis.CredentialRequestOptions,
)) as AuthenticationCredential;
} catch (err) {
throw identifyAuthenticationError({ error: err as Error, options: getOptions });
}
Expand Down
8 changes: 5 additions & 3 deletions packages/browser/src/methods/startRegistration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type {
AuthenticatorTransportFuture,
CredentialCreationOptions,
PublicKeyCredentialCreationOptions,
PublicKeyCredentialCreationOptionsJSON,
Expand Down Expand Up @@ -78,7 +77,10 @@ export async function startRegistration(
// Wait for the user to complete attestation
let credential;
try {
credential = (await navigator.credentials.create(createOptions as globalThis.CredentialCreationOptions)) as RegistrationCredential;
credential = (await navigator.credentials.create(
// TODO: Newer versions of Deno require this casting, revisit once we're using Deno 2.6+
createOptions as globalThis.CredentialCreationOptions,
)) as RegistrationCredential;
} catch (err) {
throw identifyRegistrationError({ error: err as Error, options: createOptions });
}
Expand All @@ -90,7 +92,7 @@ export async function startRegistration(
const { id, rawId, response, type } = credential;

// Continue to play it safe with `getTransports()` for now, even when L3 types say it's required
let transports: AuthenticatorTransportFuture[] | undefined = undefined;
let transports: string[] | undefined = undefined;
if (typeof response.getTransports === 'function') {
transports = response.getTransports();
}
Expand Down
7 changes: 7 additions & 0 deletions packages/browser/src/types/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ export interface PublicKeyCredentialDescriptor {
type: PublicKeyCredentialType;
}

export interface PublicKeyCredentialDescriptorJSON {
id: Base64URLString;
transports?: string[];
type: string;
}

export interface PublicKeyCredentialParameters {
alg: COSEAlgorithmIdentifier;
type: PublicKeyCredentialType;
Expand Down Expand Up @@ -592,6 +598,7 @@ export interface RsaKeyGenParams extends Algorithm {

export type AttestationConveyancePreference = "direct" | "enterprise" | "indirect" | "none";
export type AuthenticatorTransport = "ble" | "hybrid" | "internal" | "nfc" | "usb";
export type Base64URLString = string;
export type COSEAlgorithmIdentifier = number;
export type ResidentKeyRequirement = "discouraged" | "preferred" | "required";
export type UserVerificationRequirement = "discouraged" | "preferred" | "required";
Expand Down
64 changes: 8 additions & 56 deletions packages/browser/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import type {
AuthenticatorAttachment,
AuthenticatorAttestationResponse,
AuthenticatorSelectionCriteria,
Base64URLString,
COSEAlgorithmIdentifier,
PublicKeyCredential,
PublicKeyCredentialCreationOptions,
PublicKeyCredentialDescriptor,
PublicKeyCredentialDescriptorJSON,
PublicKeyCredentialParameters,
PublicKeyCredentialRequestOptions,
PublicKeyCredentialRpEntity,
Expand All @@ -36,13 +37,15 @@ export type {
AuthenticatorAttestationResponse,
AuthenticatorSelectionCriteria,
AuthenticatorTransport,
Base64URLString,
COSEAlgorithmIdentifier,
CredentialCreationOptions,
CredentialRequestOptions,
Crypto,
PublicKeyCredential,
PublicKeyCredentialCreationOptions,
PublicKeyCredentialDescriptor,
PublicKeyCredentialDescriptorJSON,
PublicKeyCredentialParameters,
PublicKeyCredentialRequestOptions,
PublicKeyCredentialRpEntity,
Expand Down Expand Up @@ -89,15 +92,6 @@ export interface PublicKeyCredentialRequestOptionsJSON {
extensions?: AuthenticationExtensionsClientInputs;
}

/**
* https://w3c.github.io/webauthn/#dictdef-publickeycredentialdescriptorjson
*/
export interface PublicKeyCredentialDescriptorJSON {
id: Base64URLString;
type: PublicKeyCredentialType;
transports?: AuthenticatorTransportFuture[];
}

/**
* https://w3c.github.io/webauthn/#dictdef-publickeycredentialuserentityjson
*/
Expand All @@ -111,7 +105,7 @@ export interface PublicKeyCredentialUserEntityJSON {
* The value returned from navigator.credentials.create()
*/
export interface RegistrationCredential extends PublicKeyCredentialFuture {
response: AuthenticatorAttestationResponseFuture;
response: AuthenticatorAttestationResponse;
}

/**
Expand Down Expand Up @@ -163,7 +157,7 @@ export interface AuthenticatorAttestationResponseJSON {
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
authenticatorData?: Base64URLString;
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
transports?: AuthenticatorTransportFuture[];
transports?: string[];
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
publicKeyAlgorithm?: COSEAlgorithmIdentifier;
publicKey?: Base64URLString;
Expand All @@ -190,52 +184,10 @@ export type WebAuthnCredential = {
publicKey: Uint8Array_;
// Number of times this authenticator is expected to have been used
counter: number;
// From browser's `startRegistration()` -> RegistrationCredentialJSON.transports (API L2 and up)
transports?: AuthenticatorTransportFuture[];
// From browser's `startRegistration()` -> RegistrationCredential.response.transports (API L2 and up)
transports?: string[];
};

/**
* An attempt to communicate that this isn't just any string, but a Base64URL-encoded string
*/
export type Base64URLString = string;

/**
* AuthenticatorAttestationResponse in TypeScript's DOM lib is outdated (up through v3.9.7).
* Maintain an augmented version here so we can implement additional properties as the WebAuthn
* spec evolves.
*
* See https://www.w3.org/TR/webauthn-2/#iface-authenticatorattestationresponse
*
* Properties marked optional are not supported in all browsers.
*/
export interface AuthenticatorAttestationResponseFuture extends AuthenticatorAttestationResponse {
getTransports(): AuthenticatorTransportFuture[];
}

/**
* A super class of TypeScript's `AuthenticatorTransport` that includes support for the latest
* transports. Should eventually be replaced by TypeScript's when TypeScript gets updated to
* know about it (sometime after 4.6.3)
*/
export type AuthenticatorTransportFuture =
| 'ble'
| 'cable'
| 'hybrid'
| 'internal'
| 'nfc'
| 'smart-card'
| 'usb';

/**
* A super class of TypeScript's `PublicKeyCredentialDescriptor` that knows about the latest
* transports. Should eventually be replaced by TypeScript's when TypeScript gets updated to
* know about it (sometime after 4.6.3)
*/
export interface PublicKeyCredentialDescriptorFuture
extends Omit<PublicKeyCredentialDescriptor, 'transports'> {
transports?: AuthenticatorTransportFuture[];
}

/** */
export type PublicKeyCredentialJSON =
| RegistrationResponseJSON
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type {
AuthenticationExtensionsClientInputs,
AuthenticatorTransportFuture,
Base64URLString,
PublicKeyCredentialRequestOptionsJSON,
Uint8Array_,
Expand All @@ -27,7 +26,7 @@ export async function generateAuthenticationOptions(
rpID: string;
allowCredentials?: {
id: Base64URLString;
transports?: AuthenticatorTransportFuture[];
transports?: string[];
}[];
challenge?: string | Uint8Array_;
timeout?: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
AuthenticationExtensionsClientInputs,
AuthenticatorSelectionCriteria,
AuthenticatorTransportFuture,
Base64URLString,
COSEAlgorithmIdentifier,
PublicKeyCredentialCreationOptionsJSON,
Expand Down Expand Up @@ -94,7 +93,7 @@ export async function generateRegistrationOptions(
attestationType?: 'direct' | 'enterprise' | 'none';
excludeCredentials?: {
id: Base64URLString;
transports?: AuthenticatorTransportFuture[];
transports?: string[];
}[];
authenticatorSelection?: AuthenticatorSelectionCriteria;
extensions?: AuthenticationExtensionsClientInputs;
Expand Down
7 changes: 7 additions & 0 deletions packages/server/src/types/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ export interface PublicKeyCredentialDescriptor {
type: PublicKeyCredentialType;
}

export interface PublicKeyCredentialDescriptorJSON {
id: Base64URLString;
transports?: string[];
type: string;
}

export interface PublicKeyCredentialParameters {
alg: COSEAlgorithmIdentifier;
type: PublicKeyCredentialType;
Expand Down Expand Up @@ -592,6 +598,7 @@ export interface RsaKeyGenParams extends Algorithm {

export type AttestationConveyancePreference = "direct" | "enterprise" | "indirect" | "none";
export type AuthenticatorTransport = "ble" | "hybrid" | "internal" | "nfc" | "usb";
export type Base64URLString = string;
export type COSEAlgorithmIdentifier = number;
export type ResidentKeyRequirement = "discouraged" | "preferred" | "required";
export type UserVerificationRequirement = "discouraged" | "preferred" | "required";
Expand Down
64 changes: 8 additions & 56 deletions packages/server/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import type {
AuthenticatorAttachment,
AuthenticatorAttestationResponse,
AuthenticatorSelectionCriteria,
Base64URLString,
COSEAlgorithmIdentifier,
PublicKeyCredential,
PublicKeyCredentialCreationOptions,
PublicKeyCredentialDescriptor,
PublicKeyCredentialDescriptorJSON,
PublicKeyCredentialParameters,
PublicKeyCredentialRequestOptions,
PublicKeyCredentialRpEntity,
Expand All @@ -36,13 +37,15 @@ export type {
AuthenticatorAttestationResponse,
AuthenticatorSelectionCriteria,
AuthenticatorTransport,
Base64URLString,
COSEAlgorithmIdentifier,
CredentialCreationOptions,
CredentialRequestOptions,
Crypto,
PublicKeyCredential,
PublicKeyCredentialCreationOptions,
PublicKeyCredentialDescriptor,
PublicKeyCredentialDescriptorJSON,
PublicKeyCredentialParameters,
PublicKeyCredentialRequestOptions,
PublicKeyCredentialRpEntity,
Expand Down Expand Up @@ -89,15 +92,6 @@ export interface PublicKeyCredentialRequestOptionsJSON {
extensions?: AuthenticationExtensionsClientInputs;
}

/**
* https://w3c.github.io/webauthn/#dictdef-publickeycredentialdescriptorjson
*/
export interface PublicKeyCredentialDescriptorJSON {
id: Base64URLString;
type: PublicKeyCredentialType;
transports?: AuthenticatorTransportFuture[];
}

/**
* https://w3c.github.io/webauthn/#dictdef-publickeycredentialuserentityjson
*/
Expand All @@ -111,7 +105,7 @@ export interface PublicKeyCredentialUserEntityJSON {
* The value returned from navigator.credentials.create()
*/
export interface RegistrationCredential extends PublicKeyCredentialFuture {
response: AuthenticatorAttestationResponseFuture;
response: AuthenticatorAttestationResponse;
}

/**
Expand Down Expand Up @@ -163,7 +157,7 @@ export interface AuthenticatorAttestationResponseJSON {
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
authenticatorData?: Base64URLString;
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
transports?: AuthenticatorTransportFuture[];
transports?: string[];
// Optional in L2, but becomes required in L3. Play it safe until L3 becomes Recommendation
publicKeyAlgorithm?: COSEAlgorithmIdentifier;
publicKey?: Base64URLString;
Expand All @@ -190,52 +184,10 @@ export type WebAuthnCredential = {
publicKey: Uint8Array_;
// Number of times this authenticator is expected to have been used
counter: number;
// From browser's `startRegistration()` -> RegistrationCredentialJSON.transports (API L2 and up)
transports?: AuthenticatorTransportFuture[];
// From browser's `startRegistration()` -> RegistrationCredential.response.transports (API L2 and up)
transports?: string[];
};

/**
* An attempt to communicate that this isn't just any string, but a Base64URL-encoded string
*/
export type Base64URLString = string;

/**
* AuthenticatorAttestationResponse in TypeScript's DOM lib is outdated (up through v3.9.7).
* Maintain an augmented version here so we can implement additional properties as the WebAuthn
* spec evolves.
*
* See https://www.w3.org/TR/webauthn-2/#iface-authenticatorattestationresponse
*
* Properties marked optional are not supported in all browsers.
*/
export interface AuthenticatorAttestationResponseFuture extends AuthenticatorAttestationResponse {
getTransports(): AuthenticatorTransportFuture[];
}

/**
* A super class of TypeScript's `AuthenticatorTransport` that includes support for the latest
* transports. Should eventually be replaced by TypeScript's when TypeScript gets updated to
* know about it (sometime after 4.6.3)
*/
export type AuthenticatorTransportFuture =
| 'ble'
| 'cable'
| 'hybrid'
| 'internal'
| 'nfc'
| 'smart-card'
| 'usb';

/**
* A super class of TypeScript's `PublicKeyCredentialDescriptor` that knows about the latest
* transports. Should eventually be replaced by TypeScript's when TypeScript gets updated to
* know about it (sometime after 4.6.3)
*/
export interface PublicKeyCredentialDescriptorFuture
extends Omit<PublicKeyCredentialDescriptor, 'transports'> {
transports?: AuthenticatorTransportFuture[];
}

/** */
export type PublicKeyCredentialJSON =
| RegistrationResponseJSON
Expand Down
2 changes: 2 additions & 0 deletions packages/types/extract-dom-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ const types = [
'AuthenticationExtensionsClientInputs',
'AuthenticationExtensionsClientOutputs',
'AuthenticatorSelectionCriteria',
'Base64URLString',
'COSEAlgorithmIdentifier',
'CredentialCreationOptions',
'CredentialRequestOptions',
'Crypto',
'PublicKeyCredential',
'PublicKeyCredentialCreationOptions',
'PublicKeyCredentialDescriptor',
'PublicKeyCredentialDescriptorJSON',
'PublicKeyCredentialParameters',
'PublicKeyCredentialRequestOptions',
'PublicKeyCredentialUserEntity',
Expand Down
Loading