diff options
Diffstat (limited to 'packages/browser/src/helpers')
17 files changed, 96 insertions, 97 deletions
diff --git a/packages/browser/src/helpers/__jest__/generateCustomError.ts b/packages/browser/src/helpers/__jest__/generateCustomError.ts index 3c0a817..25609fa 100644 --- a/packages/browser/src/helpers/__jest__/generateCustomError.ts +++ b/packages/browser/src/helpers/__jest__/generateCustomError.ts @@ -2,17 +2,17 @@ * Create "custom errors" to help emulate WebAuthn API errors */ type WebAuthnErrorName = - | "AbortError" - | "ConstraintError" - | "InvalidStateError" - | "NotAllowedError" - | "NotSupportedError" - | "SecurityError" - | "UnknownError"; + | 'AbortError' + | 'ConstraintError' + | 'InvalidStateError' + | 'NotAllowedError' + | 'NotSupportedError' + | 'SecurityError' + | 'UnknownError'; export function generateCustomError( name: WebAuthnErrorName, - message = "", + message = '', ): Error { const customError = new Error(); customError.name = name; diff --git a/packages/browser/src/helpers/base64URLStringToBuffer.ts b/packages/browser/src/helpers/base64URLStringToBuffer.ts index db78b35..f30b3d5 100644 --- a/packages/browser/src/helpers/base64URLStringToBuffer.ts +++ b/packages/browser/src/helpers/base64URLStringToBuffer.ts @@ -7,7 +7,7 @@ */ export function base64URLStringToBuffer(base64URLString: string): ArrayBuffer { // Convert from Base64URL to Base64 - const base64 = base64URLString.replace(/-/g, "+").replace(/_/g, "/"); + const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/'); /** * Pad with '=' until it's a multiple of four * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding @@ -16,7 +16,7 @@ export function base64URLStringToBuffer(base64URLString: string): ArrayBuffer { * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding */ const padLength = (4 - (base64.length % 4)) % 4; - const padded = base64.padEnd(base64.length + padLength, "="); + const padded = base64.padEnd(base64.length + padLength, '='); // Convert to a binary string const binary = atob(padded); diff --git a/packages/browser/src/helpers/browserSupportsWebAuthn.test.ts b/packages/browser/src/helpers/browserSupportsWebAuthn.test.ts index 639bd2f..dcd5c7c 100644 --- a/packages/browser/src/helpers/browserSupportsWebAuthn.test.ts +++ b/packages/browser/src/helpers/browserSupportsWebAuthn.test.ts @@ -1,26 +1,26 @@ -import { browserSupportsWebAuthn } from "./browserSupportsWebAuthn"; +import { browserSupportsWebAuthn } from './browserSupportsWebAuthn'; beforeEach(() => { // @ts-ignore 2741 window.PublicKeyCredential = jest.fn().mockReturnValue(() => {}); }); -test("should return true when browser supports WebAuthn", () => { +test('should return true when browser supports WebAuthn', () => { expect(browserSupportsWebAuthn()).toBe(true); }); -test("should return false when browser does not support WebAuthn", () => { +test('should return false when browser does not support WebAuthn', () => { // This looks weird but it appeases the linter so it's _fiiiine_ delete (window as { PublicKeyCredential: unknown }).PublicKeyCredential; expect(browserSupportsWebAuthn()).toBe(false); }); -test("should return false when window is undefined", () => { +test('should return false when window is undefined', () => { // Make window undefined as it is in node environments. - const windowSpy = jest.spyOn<typeof globalThis, "window">( + const windowSpy = jest.spyOn<typeof globalThis, 'window'>( global, - "window", - "get", + 'window', + 'get', ); // @ts-ignore: Intentionally making window unavailable windowSpy.mockImplementation(() => undefined); diff --git a/packages/browser/src/helpers/browserSupportsWebAuthn.ts b/packages/browser/src/helpers/browserSupportsWebAuthn.ts index 02b3c43..706862d 100644 --- a/packages/browser/src/helpers/browserSupportsWebAuthn.ts +++ b/packages/browser/src/helpers/browserSupportsWebAuthn.ts @@ -4,6 +4,6 @@ export function browserSupportsWebAuthn(): boolean { return ( window?.PublicKeyCredential !== undefined && - typeof window.PublicKeyCredential === "function" + typeof window.PublicKeyCredential === 'function' ); } diff --git a/packages/browser/src/helpers/browserSupportsWebAuthnAutofill.ts b/packages/browser/src/helpers/browserSupportsWebAuthnAutofill.ts index 621ab9a..cfdfb52 100644 --- a/packages/browser/src/helpers/browserSupportsWebAuthnAutofill.ts +++ b/packages/browser/src/helpers/browserSupportsWebAuthnAutofill.ts @@ -1,4 +1,4 @@ -import { PublicKeyCredentialFuture } from "@simplewebauthn/typescript-types"; +import { PublicKeyCredentialFuture } from '@simplewebauthn/typescript-types'; /** * Determine if the browser supports conditional UI, so that WebAuthn credentials can diff --git a/packages/browser/src/helpers/bufferToBase64URLString.ts b/packages/browser/src/helpers/bufferToBase64URLString.ts index 0bd29b5..6a40cbb 100644 --- a/packages/browser/src/helpers/bufferToBase64URLString.ts +++ b/packages/browser/src/helpers/bufferToBase64URLString.ts @@ -6,7 +6,7 @@ */ export function bufferToBase64URLString(buffer: ArrayBuffer): string { const bytes = new Uint8Array(buffer); - let str = ""; + let str = ''; for (const charCode of bytes) { str += String.fromCharCode(charCode); @@ -14,5 +14,5 @@ export function bufferToBase64URLString(buffer: ArrayBuffer): string { const base64String = btoa(str); - return base64String.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); + return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); } diff --git a/packages/browser/src/helpers/bufferToUTF8String.ts b/packages/browser/src/helpers/bufferToUTF8String.ts index 8a6c3b9..0da3246 100644 --- a/packages/browser/src/helpers/bufferToUTF8String.ts +++ b/packages/browser/src/helpers/bufferToUTF8String.ts @@ -3,5 +3,5 @@ * string. */ export function bufferToUTF8String(value: ArrayBuffer): string { - return new TextDecoder("utf-8").decode(value); + return new TextDecoder('utf-8').decode(value); } diff --git a/packages/browser/src/helpers/identifyAuthenticationError.ts b/packages/browser/src/helpers/identifyAuthenticationError.ts index 3d84ce2..78732b2 100644 --- a/packages/browser/src/helpers/identifyAuthenticationError.ts +++ b/packages/browser/src/helpers/identifyAuthenticationError.ts @@ -1,5 +1,5 @@ -import { isValidDomain } from "./isValidDomain"; -import { WebAuthnError } from "./webAuthnError"; +import { isValidDomain } from './isValidDomain'; +import { WebAuthnError } from './webAuthnError'; /** * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.get()` @@ -14,52 +14,52 @@ export function identifyAuthenticationError({ const { publicKey } = options; if (!publicKey) { - throw Error("options was missing required publicKey property"); + throw Error('options was missing required publicKey property'); } - if (error.name === "AbortError") { + if (error.name === 'AbortError') { if (options.signal instanceof AbortSignal) { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16) return new WebAuthnError({ - message: "Authentication ceremony was sent an abort signal", - code: "ERROR_CEREMONY_ABORTED", + message: 'Authentication ceremony was sent an abort signal', + code: 'ERROR_CEREMONY_ABORTED', cause: error, }); } - } else if (error.name === "NotAllowedError") { + } else if (error.name === 'NotAllowedError') { /** * Pass the error directly through. Platforms are overloading this error beyond what the spec * defines and we don't want to overwrite potentially useful error messages. */ return new WebAuthnError({ message: error.message, - code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY", + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', cause: error, }); - } else if (error.name === "SecurityError") { + } else if (error.name === 'SecurityError') { const effectiveDomain = window.location.hostname; if (!isValidDomain(effectiveDomain)) { // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 5) return new WebAuthnError({ message: `${window.location.hostname} is an invalid domain`, - code: "ERROR_INVALID_DOMAIN", + code: 'ERROR_INVALID_DOMAIN', cause: error, }); } else if (publicKey.rpId !== effectiveDomain) { // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 6) return new WebAuthnError({ message: `The RP ID "${publicKey.rpId}" is invalid for this domain`, - code: "ERROR_INVALID_RP_ID", + code: 'ERROR_INVALID_RP_ID', cause: error, }); } - } else if (error.name === "UnknownError") { + } else if (error.name === 'UnknownError') { // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 1) // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 12) return new WebAuthnError({ message: - "The authenticator was unable to process the specified options, or could not create a new assertion signature", - code: "ERROR_AUTHENTICATOR_GENERAL_ERROR", + 'The authenticator was unable to process the specified options, or could not create a new assertion signature', + code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR', cause: error, }); } diff --git a/packages/browser/src/helpers/identifyRegistrationError.ts b/packages/browser/src/helpers/identifyRegistrationError.ts index d0def65..59533da 100644 --- a/packages/browser/src/helpers/identifyRegistrationError.ts +++ b/packages/browser/src/helpers/identifyRegistrationError.ts @@ -1,5 +1,5 @@ -import { isValidDomain } from "./isValidDomain"; -import { WebAuthnError } from "./webAuthnError"; +import { isValidDomain } from './isValidDomain'; +import { WebAuthnError } from './webAuthnError'; /** * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.create()` @@ -14,66 +14,65 @@ export function identifyRegistrationError({ const { publicKey } = options; if (!publicKey) { - throw Error("options was missing required publicKey property"); + throw Error('options was missing required publicKey property'); } - if (error.name === "AbortError") { + if (error.name === 'AbortError') { if (options.signal instanceof AbortSignal) { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16) return new WebAuthnError({ - message: "Registration ceremony was sent an abort signal", - code: "ERROR_CEREMONY_ABORTED", + message: 'Registration ceremony was sent an abort signal', + code: 'ERROR_CEREMONY_ABORTED', cause: error, }); } - } else if (error.name === "ConstraintError") { + } else if (error.name === 'ConstraintError') { if (publicKey.authenticatorSelection?.requireResidentKey === true) { // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 4) return new WebAuthnError({ message: - "Discoverable credentials were required but no available authenticator supported it", - code: "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT", + 'Discoverable credentials were required but no available authenticator supported it', + code: 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT', cause: error, }); } else if ( - publicKey.authenticatorSelection?.userVerification === "required" + publicKey.authenticatorSelection?.userVerification === 'required' ) { // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 5) return new WebAuthnError({ - message: - "User verification was required but no available authenticator supported it", - code: "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT", + message: 'User verification was required but no available authenticator supported it', + code: 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT', cause: error, }); } - } else if (error.name === "InvalidStateError") { + } else if (error.name === 'InvalidStateError') { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 20) // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 3) return new WebAuthnError({ - message: "The authenticator was previously registered", - code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED", + message: 'The authenticator was previously registered', + code: 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED', cause: error, }); - } else if (error.name === "NotAllowedError") { + } else if (error.name === 'NotAllowedError') { /** * Pass the error directly through. Platforms are overloading this error beyond what the spec * defines and we don't want to overwrite potentially useful error messages. */ return new WebAuthnError({ message: error.message, - code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY", + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', cause: error, }); - } else if (error.name === "NotSupportedError") { + } else if (error.name === 'NotSupportedError') { const validPubKeyCredParams = publicKey.pubKeyCredParams.filter( - (param) => param.type === "public-key", + (param) => param.type === 'public-key', ); if (validPubKeyCredParams.length === 0) { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 10) return new WebAuthnError({ message: 'No entry in pubKeyCredParams was of type "public-key"', - code: "ERROR_MALFORMED_PUBKEYCREDPARAMS", + code: 'ERROR_MALFORMED_PUBKEYCREDPARAMS', cause: error, }); } @@ -81,43 +80,43 @@ export function identifyRegistrationError({ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 2) return new WebAuthnError({ message: - "No available authenticator supported any of the specified pubKeyCredParams algorithms", - code: "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG", + 'No available authenticator supported any of the specified pubKeyCredParams algorithms', + code: 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG', cause: error, }); - } else if (error.name === "SecurityError") { + } else if (error.name === 'SecurityError') { const effectiveDomain = window.location.hostname; if (!isValidDomain(effectiveDomain)) { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 7) return new WebAuthnError({ message: `${window.location.hostname} is an invalid domain`, - code: "ERROR_INVALID_DOMAIN", + code: 'ERROR_INVALID_DOMAIN', cause: error, }); } else if (publicKey.rp.id !== effectiveDomain) { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 8) return new WebAuthnError({ message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`, - code: "ERROR_INVALID_RP_ID", + code: 'ERROR_INVALID_RP_ID', cause: error, }); } - } else if (error.name === "TypeError") { + } else if (error.name === 'TypeError') { if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) { // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 5) return new WebAuthnError({ - message: "User ID was not between 1 and 64 characters", - code: "ERROR_INVALID_USER_ID_LENGTH", + message: 'User ID was not between 1 and 64 characters', + code: 'ERROR_INVALID_USER_ID_LENGTH', cause: error, }); } - } else if (error.name === "UnknownError") { + } else if (error.name === 'UnknownError') { // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 1) // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 8) return new WebAuthnError({ message: - "The authenticator was unable to process the specified options, or could not create a new credential", - code: "ERROR_AUTHENTICATOR_GENERAL_ERROR", + 'The authenticator was unable to process the specified options, or could not create a new credential', + code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR', cause: error, }); } diff --git a/packages/browser/src/helpers/isValidDomain.ts b/packages/browser/src/helpers/isValidDomain.ts index 3e1ad10..22f045f 100644 --- a/packages/browser/src/helpers/isValidDomain.ts +++ b/packages/browser/src/helpers/isValidDomain.ts @@ -9,7 +9,7 @@ export function isValidDomain(hostname: string): boolean { return ( // Consider localhost valid as well since it's okay wrt Secure Contexts - hostname === "localhost" || + hostname === 'localhost' || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname) ); } diff --git a/packages/browser/src/helpers/platformAuthenticatorIsAvailable.test.ts b/packages/browser/src/helpers/platformAuthenticatorIsAvailable.test.ts index 6b3e90c..6f2b91d 100644 --- a/packages/browser/src/helpers/platformAuthenticatorIsAvailable.test.ts +++ b/packages/browser/src/helpers/platformAuthenticatorIsAvailable.test.ts @@ -1,4 +1,4 @@ -import { platformAuthenticatorIsAvailable } from "./platformAuthenticatorIsAvailable"; +import { platformAuthenticatorIsAvailable } from './platformAuthenticatorIsAvailable'; const mockIsUVPAA = jest.fn(); @@ -7,17 +7,17 @@ beforeEach(() => { // @ts-ignore 2741 window.PublicKeyCredential = jest.fn().mockReturnValue(() => {}); - window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable = - mockIsUVPAA.mockResolvedValue(true); + window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable = mockIsUVPAA + .mockResolvedValue(true); }); -test("should return true when platform authenticator is available", async () => { +test('should return true when platform authenticator is available', async () => { const isAvailable = await platformAuthenticatorIsAvailable(); expect(isAvailable).toEqual(true); }); -test("should return false when platform authenticator is unavailable", async () => { +test('should return false when platform authenticator is unavailable', async () => { mockIsUVPAA.mockResolvedValue(false); const isAvailable = await platformAuthenticatorIsAvailable(); @@ -25,7 +25,7 @@ test("should return false when platform authenticator is unavailable", async () expect(isAvailable).toEqual(false); }); -test("should return false when browser does not support WebAuthn", async () => { +test('should return false when browser does not support WebAuthn', async () => { // This looks weird but it appeases the linter so it's _fiiiine_ delete (window as { PublicKeyCredential: unknown }).PublicKeyCredential; const isAvailable = await platformAuthenticatorIsAvailable(); diff --git a/packages/browser/src/helpers/platformAuthenticatorIsAvailable.ts b/packages/browser/src/helpers/platformAuthenticatorIsAvailable.ts index d188669..269789c 100644 --- a/packages/browser/src/helpers/platformAuthenticatorIsAvailable.ts +++ b/packages/browser/src/helpers/platformAuthenticatorIsAvailable.ts @@ -1,4 +1,4 @@ -import { browserSupportsWebAuthn } from "./browserSupportsWebAuthn"; +import { browserSupportsWebAuthn } from './browserSupportsWebAuthn'; /** * Determine whether the browser can communicate with a built-in authenticator, like diff --git a/packages/browser/src/helpers/toAuthenticatorAttachment.ts b/packages/browser/src/helpers/toAuthenticatorAttachment.ts index 99319fb..366cf8f 100644 --- a/packages/browser/src/helpers/toAuthenticatorAttachment.ts +++ b/packages/browser/src/helpers/toAuthenticatorAttachment.ts @@ -1,6 +1,6 @@ -import { AuthenticatorAttachment } from "@simplewebauthn/typescript-types"; +import { AuthenticatorAttachment } from '@simplewebauthn/typescript-types'; -const attachments: AuthenticatorAttachment[] = ["cross-platform", "platform"]; +const attachments: AuthenticatorAttachment[] = ['cross-platform', 'platform']; /** * If possible coerce a `string` value into a known `AuthenticatorAttachment` diff --git a/packages/browser/src/helpers/toPublicKeyCredentialDescriptor.ts b/packages/browser/src/helpers/toPublicKeyCredentialDescriptor.ts index 258efe2..e4c34a2 100644 --- a/packages/browser/src/helpers/toPublicKeyCredentialDescriptor.ts +++ b/packages/browser/src/helpers/toPublicKeyCredentialDescriptor.ts @@ -1,6 +1,6 @@ -import type { PublicKeyCredentialDescriptorJSON } from "@simplewebauthn/typescript-types"; +import type { PublicKeyCredentialDescriptorJSON } from '@simplewebauthn/typescript-types'; -import { base64URLStringToBuffer } from "./base64URLStringToBuffer"; +import { base64URLStringToBuffer } from './base64URLStringToBuffer'; export function toPublicKeyCredentialDescriptor( descriptor: PublicKeyCredentialDescriptorJSON, diff --git a/packages/browser/src/helpers/webAuthnAbortService.test.ts b/packages/browser/src/helpers/webAuthnAbortService.test.ts index e8d358e..506bb2a 100644 --- a/packages/browser/src/helpers/webAuthnAbortService.test.ts +++ b/packages/browser/src/helpers/webAuthnAbortService.test.ts @@ -1,13 +1,13 @@ -import { webauthnAbortService } from "./webAuthnAbortService"; +import { webauthnAbortService } from './webAuthnAbortService'; -test("should create a new abort signal every time", () => { +test('should create a new abort signal every time', () => { const signal1 = webauthnAbortService.createNewAbortSignal(); const signal2 = webauthnAbortService.createNewAbortSignal(); expect(signal2).not.toBe(signal1); }); -test("should call abort() with AbortError on existing controller when creating a new signal", () => { +test('should call abort() with AbortError on existing controller when creating a new signal', () => { // Populate `.controller` webauthnAbortService.createNewAbortSignal(); @@ -23,5 +23,5 @@ test("should call abort() with AbortError on existing controller when creating a // Make sure we raise an AbortError so it can be detected correctly const abortReason = abortSpy.mock.calls[0][0]; expect(abortReason).toBeInstanceOf(Error); - expect(abortReason.name).toEqual("AbortError"); + expect(abortReason.name).toEqual('AbortError'); }); diff --git a/packages/browser/src/helpers/webAuthnAbortService.ts b/packages/browser/src/helpers/webAuthnAbortService.ts index eb0e9be..50e00ba 100644 --- a/packages/browser/src/helpers/webAuthnAbortService.ts +++ b/packages/browser/src/helpers/webAuthnAbortService.ts @@ -13,9 +13,9 @@ class WebAuthnAbortService { // Abort any existing calls to navigator.credentials.create() or navigator.credentials.get() if (this.controller) { const abortError = new Error( - "Cancelling existing WebAuthn API call for new one", + 'Cancelling existing WebAuthn API call for new one', ); - abortError.name = "AbortError"; + abortError.name = 'AbortError'; this.controller.abort(abortError); } diff --git a/packages/browser/src/helpers/webAuthnError.ts b/packages/browser/src/helpers/webAuthnError.ts index bf60341..fb1def5 100644 --- a/packages/browser/src/helpers/webAuthnError.ts +++ b/packages/browser/src/helpers/webAuthnError.ts @@ -37,14 +37,14 @@ export class WebAuthnError extends Error { } export type WebAuthnErrorCode = - | "ERROR_CEREMONY_ABORTED" - | "ERROR_INVALID_DOMAIN" - | "ERROR_INVALID_RP_ID" - | "ERROR_INVALID_USER_ID_LENGTH" - | "ERROR_MALFORMED_PUBKEYCREDPARAMS" - | "ERROR_AUTHENTICATOR_GENERAL_ERROR" - | "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT" - | "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT" - | "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED" - | "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG" - | "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY"; + | 'ERROR_CEREMONY_ABORTED' + | 'ERROR_INVALID_DOMAIN' + | 'ERROR_INVALID_RP_ID' + | 'ERROR_INVALID_USER_ID_LENGTH' + | 'ERROR_MALFORMED_PUBKEYCREDPARAMS' + | 'ERROR_AUTHENTICATOR_GENERAL_ERROR' + | 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT' + | 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT' + | 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED' + | 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG' + | 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY'; |