diff options
Diffstat (limited to 'packages/server/src/helpers/decodeAuthenticatorExtensions.ts')
-rw-r--r-- | packages/server/src/helpers/decodeAuthenticatorExtensions.ts | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/packages/server/src/helpers/decodeAuthenticatorExtensions.ts b/packages/server/src/helpers/decodeAuthenticatorExtensions.ts index a889879..7bd583c 100644 --- a/packages/server/src/helpers/decodeAuthenticatorExtensions.ts +++ b/packages/server/src/helpers/decodeAuthenticatorExtensions.ts @@ -1,4 +1,4 @@ -import cbor from 'cbor'; +import { isoCBOR } from './iso'; /** * Convert authenticator extension data buffer to a proper object @@ -6,16 +6,17 @@ import cbor from 'cbor'; * @param extensionData Authenticator Extension Data buffer */ export function decodeAuthenticatorExtensions( - extensionData: Buffer, + extensionData: Uint8Array, ): AuthenticationExtensionsAuthenticatorOutputs | undefined { - let toCBOR: AuthenticationExtensionsAuthenticatorOutputs | undefined; + let toCBOR: Map<string, unknown>; try { - toCBOR = cbor.decodeAllSync(extensionData)[0]; + toCBOR = isoCBOR.decodeFirst(extensionData); } catch (err) { const _err = err as Error; throw new Error(`Error decoding authenticator extensions: ${_err.message}`); } - return toCBOR; + + return convertMapToObjectDeep(toCBOR); } export type AuthenticationExtensionsAuthenticatorOutputs = { @@ -24,14 +25,34 @@ export type AuthenticationExtensionsAuthenticatorOutputs = { }; export type DevicePublicKeyAuthenticatorOutput = { - dpk?: Buffer; - scp?: Buffer; + dpk?: Uint8Array; sig?: string; - aaguid?: Buffer; + nonce?: Uint8Array; + scope?: Uint8Array; + aaguid?: Uint8Array; }; // TODO: Need to verify this format // https://w3c.github.io/webauthn/#sctn-uvm-extension. export type UVMAuthenticatorOutput = { - uvm?: Buffer[]; + uvm?: Uint8Array[]; }; + +/** + * CBOR-encoded extensions can be deeply-nested Maps, which are too deep for a simple + * `Object.entries()`. This method will recursively make sure that all Maps are converted into + * basic objects. + */ +function convertMapToObjectDeep(input: Map<string, unknown>): { [key: string]: unknown } { + const mapped: { [key: string]: unknown } = {}; + + for (const [key, value] of input) { + if (value instanceof Map) { + mapped[key] = convertMapToObjectDeep(value); + } else { + mapped[key] = value; + } + } + + return mapped; +} |