diff options
Diffstat (limited to 'packages/browser/src/helpers')
17 files changed, 115 insertions, 102 deletions
diff --git a/packages/browser/src/helpers/__jest__/generateCustomError.ts b/packages/browser/src/helpers/__jest__/generateCustomError.ts index 55f6acf..3c0a817 100644 --- a/packages/browser/src/helpers/__jest__/generateCustomError.ts +++ b/packages/browser/src/helpers/__jest__/generateCustomError.ts @@ -2,15 +2,18 @@ * 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 = ''): Error { +export function generateCustomError( + name: WebAuthnErrorName, + message = "", +): Error { const customError = new Error(); customError.name = name; customError.message = message; diff --git a/packages/browser/src/helpers/base64URLStringToBuffer.ts b/packages/browser/src/helpers/base64URLStringToBuffer.ts index f30b3d5..db78b35 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 20d96c2..195f089 100644 --- a/packages/browser/src/helpers/browserSupportsWebAuthn.test.ts +++ b/packages/browser/src/helpers/browserSupportsWebAuthn.test.ts @@ -1,22 +1,22 @@ -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", () => { delete (window as any).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<any, 'window'>(global, 'window', 'get'); + const windowSpy = jest.spyOn<any, "window">(global, "window", "get"); windowSpy.mockImplementation(() => undefined); expect(window).toBe(undefined); diff --git a/packages/browser/src/helpers/browserSupportsWebAuthn.ts b/packages/browser/src/helpers/browserSupportsWebAuthn.ts index 79fe673..02b3c43 100644 --- a/packages/browser/src/helpers/browserSupportsWebAuthn.ts +++ b/packages/browser/src/helpers/browserSupportsWebAuthn.ts @@ -3,6 +3,7 @@ */ export function browserSupportsWebAuthn(): boolean { return ( - window?.PublicKeyCredential !== undefined && typeof window.PublicKeyCredential === 'function' + window?.PublicKeyCredential !== undefined && + typeof window.PublicKeyCredential === "function" ); } diff --git a/packages/browser/src/helpers/browserSupportsWebAuthnAutofill.ts b/packages/browser/src/helpers/browserSupportsWebAuthnAutofill.ts index afc1176..b3b1e86 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 @@ -11,8 +11,8 @@ export async function browserSupportsWebAuthnAutofill(): Promise<boolean> { * want. I think I'm fine with this for now since it's _supposed_ to be temporary, until TS types * have a chance to catch up. */ - const globalPublicKeyCredential = - window.PublicKeyCredential as unknown as PublicKeyCredentialFuture; + const globalPublicKeyCredential = window + .PublicKeyCredential as unknown as PublicKeyCredentialFuture; return ( globalPublicKeyCredential.isConditionalMediationAvailable !== undefined && diff --git a/packages/browser/src/helpers/bufferToBase64URLString.ts b/packages/browser/src/helpers/bufferToBase64URLString.ts index 6a40cbb..0bd29b5 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 0da3246..8a6c3b9 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 d8d6960..3d84ce2 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,51 +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', + message: + "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 02c9dac..d0def65 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,104 +14,110 @@ 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', + message: + "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') { + } else if ( + 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', - cause: error + 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, }); } // 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', + message: + "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', - cause: error + 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', + message: + "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 4d2eedd..3e1ad10 100644 --- a/packages/browser/src/helpers/isValidDomain.ts +++ b/packages/browser/src/helpers/isValidDomain.ts @@ -9,6 +9,7 @@ export function isValidDomain(hostname: string): boolean { return ( // Consider localhost valid as well since it's okay wrt Secure Contexts - hostname === 'localhost' || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname) + 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 3e0b65b..3024420 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(); @@ -11,13 +11,13 @@ beforeEach(() => { 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 () => { delete (window as any).PublicKeyCredential; const isAvailable = await platformAuthenticatorIsAvailable(); diff --git a/packages/browser/src/helpers/platformAuthenticatorIsAvailable.ts b/packages/browser/src/helpers/platformAuthenticatorIsAvailable.ts index 7dc1505..319825b 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 366cf8f..99319fb 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 e4c34a2..258efe2 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 98c1ccd..c1607e6 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 f90b263..eb0e9be 100644 --- a/packages/browser/src/helpers/webAuthnAbortService.ts +++ b/packages/browser/src/helpers/webAuthnAbortService.ts @@ -12,8 +12,10 @@ class WebAuthnAbortService { createNewAbortSignal() { // 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'); - abortError.name = 'AbortError'; + const abortError = new Error( + "Cancelling existing WebAuthn API call for new one", + ); + abortError.name = "AbortError"; this.controller.abort(abortError); } diff --git a/packages/browser/src/helpers/webAuthnError.ts b/packages/browser/src/helpers/webAuthnError.ts index 1debec0..968c05b 100644 --- a/packages/browser/src/helpers/webAuthnError.ts +++ b/packages/browser/src/helpers/webAuthnError.ts @@ -25,32 +25,31 @@ export class WebAuthnError extends Error { cause, name, }: { - message: string, - code: WebAuthnErrorCode, - cause: Error, - name?: string, + message: string; + code: WebAuthnErrorCode; + cause: Error; + name?: string; }) { /** * `cause` is supported in evergreen browsers, but not IE10, so this ts-ignore is to * help Rollup complete the ES5 build. */ // @ts-ignore - super(message, { cause }) + super(message, { cause }); this.name = name ?? cause.name; this.code = code; } } 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"; |