@loginid/websdk3 3.2.2 → 3.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../../core/src/utils/browser/index.ts","../../core/src/errors/abort.ts","../../core/src/errors/loginid.ts","../../core/src/errors/passkey.ts","../../core/src/errors/storage.ts","../../core/src/utils/crypto/index.ts","../../core/src/webauthn/abort-controller.ts","../../core/src/webauthn/errors.ts","../../core/src/webauthn/webauthn.ts","../../core/src/webauthn/webauthn-helper.ts","../../core/src/api/services/PasskeysService.ts","../../core/src/api/core/BaseHttpRequest.ts","../../core/src/api/core/CancelablePromise.ts","../../core/src/api/core/ApiError.ts","../../core/src/api/core/request.ts","../../core/src/api/core/FetchHttpRequest.ts","../../core/src/api/services/AuthService.ts","../../core/src/api/services/MfaService.ts","../../core/src/api/services/RegService.ts","../../core/src/api/services/TxService.ts","../../core/src/api/LoginIDService.ts","../../core/src/api/core/OpenAPI.ts","../../core/src/defaults/index.ts","../../core/src/validators/base.ts","../../core/src/validators/mfa.ts","../../core/src/session/index.ts","../../core/src/helpers/index.ts","../../core/src/store/local-storage.ts","../../core/src/store/local-storage-flagger.ts","../../core/src/store/local-checkout-id.ts","../../core/src/store/device-store.ts","../../core/src/store/indexdb.ts","../../core/src/store/checkout-id.ts","../../core/src/store/trust-store.ts","../../core/src/store/mfa-store.ts","../../core/src/controllers/base.ts","../../core/src/controllers/utils.ts","../../core/src/controllers/mfa.ts","../../core/src/mfa/mfa.ts","../src/loginid/controllers/passkey-manager.ts","../src/loginid/lib/defaults.ts","../src/loginid/lib/utils.ts","../src/loginid/controllers/otp.ts","../src/loginid/controllers/passkeys.ts","../src/loginid/index.ts"],"sourcesContent":["// Copyright (C) LoginID\n\nimport {\n isConditionalUIAvailable,\n isPlatformAuthenticatorAvailable,\n} from \"@loginid/core/utils/browser\";\nimport {\n WebAuthnHelper,\n createPasskeyCredential,\n getPasskeyCredential,\n} from \"@loginid/core/webauthn\";\nimport { AbortError, PasskeyError } from \"@loginid/core/errors\";\nimport { LoginIDMfa } from \"@loginid/core/mfa\";\nimport LoginIDWebSDK from \"./loginid\";\n\nexport {\n createPasskeyCredential,\n getPasskeyCredential,\n isConditionalUIAvailable,\n isPlatformAuthenticatorAvailable,\n AbortError,\n LoginIDMfa,\n LoginIDWebSDK,\n PasskeyError,\n WebAuthnHelper,\n};\nexport type { Passkey, PasskeyCollection } from \"@loginid/core/api\";\n\nexport * from \"./loginid/types\";\n\nexport default LoginIDWebSDK;\n","// Copyright (C) LoginID\n\nimport { DeviceInfo } from \"../../api\";\n\n/**\n * Retrieves default device information based on the user agent for LoginID service (gen3).\n * This function parses the user agent string to extract information about the client,\n * such as browser name, version, operating system, and architecture.\n * It constructs a deviceInfoRequestBody object containing this information and returns it.\n */\nexport const defaultDeviceInfo = (deviceId?: string): DeviceInfo => {\n const device: DeviceInfo = {\n clientType: \"browser\",\n screenWidth: window.screen.width,\n screenHeight: window.screen.height,\n // Service will try and fill in the missing fields\n clientName: \"\",\n clientVersion: \"\",\n osName: \"\",\n osVersion: \"\",\n osArch: \"\",\n };\n\n if (deviceId) {\n device.deviceId = deviceId;\n }\n\n return device;\n};\n\n/**\n * Checks if platform authenticator available\n * */\nexport const isPlatformAuthenticatorAvailable = async (): Promise<boolean> => {\n try {\n if (\n !window.PublicKeyCredential ||\n !window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable\n ) {\n return false;\n }\n return await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();\n } catch {\n return false;\n }\n};\n\n/**\n * Checks if conditional UI is available\n * */\nexport const isConditionalUIAvailable = async (): Promise<boolean> => {\n try {\n if (\n !window.PublicKeyCredential ||\n !window.PublicKeyCredential.isConditionalMediationAvailable\n ) {\n return false;\n }\n return await window.PublicKeyCredential.isConditionalMediationAvailable();\n } catch {\n return false;\n }\n};\n\n/**\n * Used to access a specific cookie\n *\n * @param {string} name The name of the targetted cookie\n * @returns\n */\nexport const getCookie = (name: string): string | undefined => {\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${name}=`);\n if (parts && parts.length === 2) {\n return parts.pop()!.split(\";\").shift();\n }\n};\n\n/**\n * Used to set a cookie on the browser\n *\n * @param {string} cookie The full cookie string\n */\nexport const setCookie = (cookie: string) => {\n document.cookie = cookie;\n};\n\n/**\n * Used to delete a cookie on the browser\n *\n * @param {string} name The name of the targetted cookie\n */\nexport const deleteCookie = (name: string) => {\n document.cookie = `${name}=; expires=${new Date()}`;\n};\n","// Copyright (C) LoginID\n\n/**\n * Error class for abort-related errors.\n */\nexport class AbortError extends Error {\n /**\n * Initializes a new instance of AbortError with the provided message.\n *\n * @type {Error}\n * @memberof AbortError\n */\n constructor(message: string) {\n super(message);\n this.name = \"AbortError\";\n }\n}\n","// Copyright (C) LoginID\n\n/**\n * Error class for LoginID SDK related errors.\n */\nexport class LoginIDError extends Error {\n /**\n * Initializes a new instance of LoginIDError with the provided message.\n *\n * @type {Error}\n * @memberof AbortError\n */\n constructor(message: string) {\n super(message);\n this.name = \"LoginIDError\";\n }\n}\n","// Copyright (C) LoginID\n\nimport { PasskeyErrorCode } from \"./types\";\n\n/**\n * Error class for passkey-related errors.\n */\nexport class PasskeyError extends Error {\n public readonly code: PasskeyErrorCode;\n\n /**\n * Initializes a new instance of PasskeyError with the provided message, code, and original error.\n *\n * @type {Error}\n * @memberof PasskeyError\n */\n constructor(message: string, code: PasskeyErrorCode, originalError: Error) {\n super(message);\n this.code = code;\n this.cause = originalError;\n }\n}\n","// Copyright (C) LoginID\n\nimport { StorageErrorCode } from \"./types\";\n\n/**\n * Error class for storage related errors.\n */\nexport class StorageError extends Error {\n /**\n * The error code.\n *\n * @type {string}\n * @memberof StorageError\n */\n public code?: StorageErrorCode;\n\n /**\n * Initializes a new instance of StorageError with the provided message.\n *\n * @type {Error}\n * @memberof StorageError\n */\n constructor(message: string, code?: StorageErrorCode) {\n super(message);\n this.name = \"StorageError\";\n this.code = code;\n }\n}\n","// Copyright (C) LoginID\n\nexport const base64EncodeUrl = (str: string) => {\n return str.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n};\n\n/**\n * The `btoa` method encodes a string in base-64.\n * This method uses the \"A-Z\", \"a-z\", \"0-9\", \"+\", \"/\" and \"=\" characters to encode the string.\n * */\nexport const b2a = (input: string): string => {\n // If input is empty or undefined, return it as is.\n if (!input) return input;\n\n const base64Chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n const encodedArray = []; // Array to store encoded characters.\n let inputIndex = 0; // Index for tracking the current position in the input string.\n\n // Process input string in chunks of 3 characters.\n while (inputIndex < input.length) {\n const char1 = input.charCodeAt(inputIndex++);\n const char2 = input.charCodeAt(inputIndex++);\n const char3 = input.charCodeAt(inputIndex++);\n\n // Combine three characters into a single 24-bit value.\n const combined = (char1 << 16) | (char2 << 8) | char3;\n\n // Extract individual 6-bit values and map to base64 characters.\n encodedArray.push(\n base64Chars[(combined >> 18) & 63] +\n base64Chars[(combined >> 12) & 63] +\n base64Chars[(combined >> 6) & 63] +\n base64Chars[combined & 63],\n );\n }\n\n // Join the array of encoded characters into a single string.\n const result = encodedArray.join(\"\");\n\n // Calculate padding based on the input length.\n const padding = input.length % 3;\n\n // Add appropriate padding characters (if needed) to meet base64 requirements.\n return padding\n ? result.slice(0, padding - 3) + \"===\".slice(padding || 3)\n : result;\n};\n\n/**\n * The `atob` method decodes a base-64 encoded string.\n * This method decodes a string of data which has been encoded by the `btoa` method.\n * */\nexport const a2b = (input: string): string => {\n // Define the base64 character set and create a lookup table.\n const base64Chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\n const charToValueMap: { [char: string]: number } = {};\n const fromCharCode = String.fromCharCode;\n\n // Create a lookup table that maps base64 characters to their numeric values.\n for (let i = 0; i < 64; i++) {\n charToValueMap[base64Chars.charAt(i)] = i;\n }\n\n let accumulator = 0; // Accumulator for storing bits.\n let accumulatorBits = 0; // Number of bits in the accumulator.\n let decodedString = \"\"; // The resulting decoded string.\n\n // Iterate through each character in the input base64 string.\n for (const char of input) {\n const charValue = charToValueMap[char];\n\n // Check if the character is a valid base64 character.\n if (charValue !== undefined) {\n accumulator = (accumulator << 6) + charValue; // Add the value to the accumulator.\n accumulatorBits += 6; // Increase the bit count.\n\n // When there are 8 or more bits in the accumulator, convert to a character.\n while (accumulatorBits >= 8) {\n // Extract the lowest 8 bits from the accumulator, convert to a character, and append to the result.\n decodedString += fromCharCode(\n (accumulator >> (accumulatorBits -= 8)) & 255,\n );\n }\n }\n }\n\n // Return the decoded string.\n return decodedString;\n};\n\n/**\n * Convert `string` into `base64` checking if the `btoa` method\n * is available for HTML+JS implementation compatibility.\n * */\nexport const bufferToBase64Url = (data: ArrayBuffer) => {\n let binary = \"\";\n const bytes = new Uint8Array(data);\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n\n const base64 = b2a(binary);\n return base64EncodeUrl(base64);\n};\n\n/**\n * Convert `base64` into `Uint8Array`\n * */\nexport const base64UrlToBuffer = (data: string): ArrayBuffer => {\n data = data.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const binary = a2b(data);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return bytes.buffer;\n};\n\n/**\n * Parse JWT to decode and access its variables\n *\n * @param {string} token The jwt token that will be parsed\n * @returns\n */\nexport const parseJwt = (token: string) => {\n try {\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const jsonPayload = decodeURIComponent(\n window\n .atob(base64)\n .split(\"\")\n .map((c) => {\n return \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join(\"\"),\n );\n\n return JSON.parse(jsonPayload);\n } catch (e) {\n console.error(e);\n }\n};\n\n/**\n * Generates a random string of the specified length containing only\n * uppercase letters (A-Z) and numbers (0-9).\n *\n * @param length - The length of the generated string. Defaults to 25.\n * @returns A randomly generated string of uppercase letters and numbers.\n */\nexport const generateRandomId = (length: number = 25) => {\n const characters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * characters.length));\n }\n return result;\n};\n\n/**\n * Returns a new non-exportable key pair for signing and verifying using ES256 (ECDSA P-256).\n * @returns {Promise<CryptoKeyPair>}\n */\nexport const generateES256KeyPair = async (): Promise<CryptoKeyPair> => {\n return await window.crypto.subtle.generateKey(\n {\n name: \"ECDSA\",\n namedCurve: \"P-256\",\n },\n false,\n [\"sign\"],\n );\n};\n\n/**\n * Exports a public key from a CryptoKeyPair in JWK (JSON Web Key) format.\n * @param {CryptoKeyPair} keyPair - The cryptographic key pair.\n * @returns {Promise<JsonWebKey>} The exported public key in JWK format.\n */\nexport const exportPublicKeyJwk = async (\n keyPair: CryptoKeyPair,\n): Promise<JsonWebKey> => {\n return await window.crypto.subtle.exportKey(\"jwk\", keyPair.publicKey);\n};\n\n/**\n * Signs a given data string using an ES256 private key.\n * @param {CryptoKey} privateKey - The private key used for signing.\n * @param {string} data - The data to be signed.\n * @returns {Promise<string>} The base64url-encoded signature.\n */\nexport const signWithES256PrivateKey = async (\n privateKey: CryptoKey,\n data: string,\n): Promise<string> => {\n const encoder = new TextEncoder();\n const tokenData = encoder.encode(data);\n\n const buffer = await window.crypto.subtle.sign(\n {\n name: \"ECDSA\",\n hash: { name: \"SHA-256\" },\n },\n privateKey,\n tokenData,\n );\n\n return bufferToBase64Url(buffer);\n};\n\n/**\n * Generates a random string of a specified length.\n *\n * @param {number} [length=12] - The length of the random string to generate.\n * @returns {string} A random string of the specified length.\n */\nexport const generateRandomString = (length: number = 12): string => {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(36))\n .join(\"\")\n .slice(0, length);\n};\n\n/**\n * Generates a random UUID.\n * If the environment does not support `crypto.randomUUID`, it falls back to generating a random string.\n *\n * @returns {string} A random UUID or a random string if `crypto.randomUUID` is not supported.\n */\nexport const randomUUID = (): string => {\n if (!window.crypto?.randomUUID) {\n return generateRandomString(24);\n }\n return window.crypto.randomUUID();\n};\n","// Copyright (C) LoginID\n\nimport { AbortError } from \"../errors/abort\";\n\nexport class AbortControllerManager {\n /**\n * AbortController to manage the lifecycle of asynchronous WebAuthn requests,\n * allowing them to be cancelled when another request needs to be made.\n */\n public static abortController: AbortController = new AbortController();\n\n /**\n * Cancels the current WebAuthn request by aborting the active AbortController\n * and throwing an AbortError with a custom message.\n */\n public static abortWebAuthnRequest = () => {\n const error = new AbortError(\"Cancelling current WebAuthn request\");\n AbortControllerManager.abortController.abort(error);\n };\n\n /**\n * Refreshes an existing WebAuthn AbortController by aborting the current request and initiating a new controller.\n * This function is useful for handling scenarios where a WebAuthn request needs to be programmatically cancelled\n * to handle new user interactions.\n */\n public static renewWebAuthnAbortController = () => {\n AbortControllerManager.abortWebAuthnRequest();\n const controller = new AbortController();\n AbortControllerManager.abortController = controller;\n };\n\n /**\n * Assigns a new AbortController to manage WebAuthn requests after aborting the\n * current one. This is useful when a specific AbortController needs to be used\n * or swapped in response to external triggers or interactions.\n *\n * @param controller - The new AbortController instance to be used.\n */\n public static assignWebAuthnAbortController = (\n controller: AbortController,\n ) => {\n AbortControllerManager.abortWebAuthnRequest();\n AbortControllerManager.abortController = controller;\n };\n}\n","// Copyright (C) LoginID\n\nimport { LoginIDError, PasskeyError } from \"../errors\";\n\n/**\n * Identifies the error that occurred during passkey creation.\n *\n * @param {Error} error The error that occurred during passkey creation.\n * @param {CredentialCreationOptions} options The options used to create the passkey.\n * @returns {PasskeyError | Error} The identified error.\n */\nexport const identifyCreateError = (\n error: Error,\n options: CredentialCreationOptions,\n): PasskeyError | Error => {\n const name = error.name;\n const { publicKey } = options;\n\n if (name === \"ConstraintError\") {\n if (publicKey?.authenticatorSelection?.requireResidentKey === true) {\n return new PasskeyError(\n \"Your device does not support discoverable credentials\",\n \"ERROR_DISCOVERABLE_CREDENTIALS_UNSUPPORTED\",\n error,\n );\n }\n\n if (publicKey?.authenticatorSelection?.userVerification === \"required\") {\n return new PasskeyError(\n \"Your device does not support user verification\",\n \"ERROR_USER_VERIFICATION_UNSUPPORTED\",\n error,\n );\n }\n }\n\n // This is the most import error to catch. It means that a passkey already exists\n // within the authenticator for this current user.\n if (name === \"InvalidStateError\") {\n return new PasskeyError(\n \"A passkey already exists on your device\",\n \"ERROR_PASSKEY_EXISTS\",\n error,\n );\n }\n\n // Platforms overload this error and it's not always clear what the actual error is.\n // Best to generalize it.\n if (name === \"NotAllowedError\") {\n return new PasskeyError(\n \"Passkey creation has failed\",\n \"ERROR_GENERAL_ERROR_SEE_CAUSE_FIELD\",\n error,\n );\n }\n\n if (name === \"NotSupportedError\") {\n return new PasskeyError(\n \"Your device does not support the algorithms required for passkey creation\",\n \"ERROR_ALGORITHMS_UNSUPPORTED\",\n error,\n );\n }\n\n if (name === \"SecurityError\") {\n const rpId = publicKey?.rp?.id;\n if (rpId !== window.location.hostname) {\n return new PasskeyError(\n `The domain of the relying party (${rpId}) is invalid for this domain`,\n \"ERROR_DOMAIN_MISMATCH\",\n error,\n );\n }\n }\n\n if (name === \"UnknownError\") {\n return new PasskeyError(\n \"Your device could not process the requested options or could not create a new passkey\",\n \"ERROR_AUTHENTICATOR_UNKNOWN_ERROR\",\n error,\n );\n }\n\n return error;\n};\n\n/**\n * Identifies the error that occurred during passkey authentication.\n *\n * @param {Error} error The error that occurred during passkey authentication.\n * @param {CredentialRequestOptions} options The options used to authenticate with the passkey.\n * @returns {PasskeyError | Error} The identified error.\n */\nexport const identifyGetError = (\n error: Error,\n options: CredentialRequestOptions,\n): PasskeyError | Error => {\n const name = error.name;\n const { publicKey } = options;\n\n if (name === \"AbortError\") {\n if (options.signal instanceof AbortSignal) {\n return new PasskeyError(\n \"Passkey authentication has been aborted\",\n \"ERROR_PASSKEY_ABORTED\",\n error,\n );\n }\n }\n\n // Platforms overload this error and it's not always clear what the actual error is.\n // Best to generalize it.\n if (name === \"NotAllowedError\") {\n return new PasskeyError(\n \"Passkey authentication has failed\",\n \"ERROR_GENERAL_ERROR_SEE_CAUSE_FIELD\",\n error,\n );\n }\n\n if (name === \"SecurityError\") {\n const rpId = publicKey?.rpId;\n if (rpId !== window.location.hostname) {\n return new PasskeyError(\n `The domain of the relying party (${rpId}) is invalid for this domain`,\n \"ERROR_DOMAIN_MISMATCH\",\n error,\n );\n }\n }\n\n if (name === \"UnknownError\") {\n return new PasskeyError(\n \"Your device could not process the requested options or could not authenticate with a passkey\",\n \"ERROR_AUTHENTICATOR_UNKNOWN_ERROR\",\n error,\n );\n }\n\n return error;\n};\n\nexport const USER_NO_OP_ERROR = new LoginIDError(\n \"User needs to be logged in to perform this operation.\",\n);\nexport const NO_LOGIN_OPTIONS_ERROR = new LoginIDError(\n \"No login options available.\",\n);\n","// Copyright (C) LoginID\n\nimport type {\n PublicKeyCredentialCreationOptions,\n PublicKeyCredentialRequestOptions,\n} from \"../api\";\nimport { identifyCreateError, identifyGetError } from \"./errors\";\nimport { GetPasskeyCredentialOptions } from \"../types\";\nimport { base64UrlToBuffer } from \"../utils/crypto\";\n\n/**\n * Asynchronously creates a passkey credential using the provided registration response.\n *\n * @param {IRegisterPasskeyInitResponse} init - The registration initiation response.\n * @returns {Promise<PublicKeyCredential>} A promise that resolves to the passkey credential.\n * @throws {LoginIdError} If any errors occur during credential creation or if the credential type is invalid.\n */\nconst createPasskeyCredential = async (\n init: PublicKeyCredentialCreationOptions,\n): Promise<PublicKeyCredential> => {\n let excludeCredentials: any[] | undefined = undefined;\n\n // Check if excludeCredentials is defined in the registration initiation response.\n if (init.excludeCredentials !== undefined) {\n // Initialize an empty array to store the transformed credentials.\n excludeCredentials = [];\n\n // Iterate through the provided credentials and transform them.\n for (const cred of init.excludeCredentials) {\n // Create a new credential descriptor with transformed values.\n const transformedCred = {\n id: base64UrlToBuffer(cred.id), // Convert the credential ID from base64 URL to a buffer.\n transports: cred.transports, // Transport hints for the credential.\n type: cred.type, // Type of the credential (e.g., \"public-key\").\n };\n\n // Add the transformed credential descriptor to the excludeCredentials array.\n excludeCredentials.push(transformedCred);\n }\n }\n\n // Make TypeScript happy\n const pubKeyCredParams =\n init.pubKeyCredParams as PublicKeyCredentialParameters[];\n\n // Define options for creating the passkey credential.\n // TODO: Add hints\n const options: CredentialCreationOptions = {\n publicKey: {\n attestation: init.attestation,\n authenticatorSelection: { ...init.authenticatorSelection },\n challenge: base64UrlToBuffer(init.challenge),\n excludeCredentials: excludeCredentials,\n extensions: init.extensions,\n pubKeyCredParams: pubKeyCredParams,\n rp: init.rp,\n timeout: init.timeout,\n user: {\n ...init.user,\n id: base64UrlToBuffer(init.user.id),\n },\n },\n };\n\n try {\n // Create the passkey credential using the Web Authentication API.\n const credential = await navigator.credentials.create(options);\n\n // Check if the credential creation was successful.\n if (credential === null) {\n throw new Error(\"Failed to create the passkey credential.\");\n }\n\n // Return the created passkey credential.\n return <PublicKeyCredential>credential;\n } catch (e) {\n // Identify error if possible to provide a more friendly error message.\n if (e instanceof Error) {\n throw identifyCreateError(e, options);\n }\n\n // Re-throw the object if it is not an instance of Error.\n throw e;\n }\n};\n\n/**\n * Asynchronously retrieves a passkey credential for authentication using the provided request options.\n *\n * @param {publicKeyCredentialRequestOptionsResponseBody} init - The authentication initiation response.\n * @param {AuthenticateWithPasskeysOptions} options - Additional options for the authentication request.\n * @returns {Promise<PublicKeyCredential>} A promise that resolves to the passkey credential.\n */\nconst getPasskeyCredential = async (\n init: PublicKeyCredentialRequestOptions,\n options: GetPasskeyCredentialOptions = {},\n): Promise<PublicKeyCredential> => {\n let allowCredentials: any[] | undefined = undefined;\n\n // Check if allowCredentials is defined in the registration initiation response.\n if (init.allowCredentials !== undefined) {\n // Initialize an empty array to store the transformed credentials.\n allowCredentials = [];\n\n // Iterate through the provided credentials and transform them.\n for (const cred of init.allowCredentials) {\n // Create a new credential descriptor with transformed values.\n const transformedCred = {\n id: base64UrlToBuffer(cred.id), // Convert the credential ID from base64 URL to a buffer.\n transports: cred.transports, // Transport hints for the credential.\n type: cred.type, // Type of the credential (e.g., \"public-key\").\n };\n\n // Add the transformed credential descriptor to the allowCredentials array.\n allowCredentials.push(transformedCred);\n }\n }\n\n // Define options for creating the passkey credential.\n // TODO: Add hints\n const credOptions: CredentialRequestOptions = {\n ...(options.autoFill && { mediation: \"conditional\" }),\n ...(options.abortController && { signal: options.abortController.signal }),\n publicKey: {\n allowCredentials: allowCredentials,\n challenge: base64UrlToBuffer(init.challenge),\n extensions: init.extensions,\n rpId: init.rpId,\n timeout: init.timeout,\n userVerification: init.userVerification,\n },\n };\n\n try {\n // Create the passkey credential using the Web Authentication API.\n const credential = await navigator.credentials.get(credOptions);\n\n // Check if the credential creation was successful.\n if (credential === null) {\n throw new Error(\"Failed to create the passkey credential.\");\n }\n\n // Return the created passkey credential.\n return <PublicKeyCredential>credential;\n } catch (e) {\n // Identify error if possible to provide a more friendly error message.\n if (e instanceof Error) {\n throw identifyGetError(e, credOptions);\n }\n\n // Re-throw the object if it is not an instance of Error.\n throw e;\n }\n};\n\n// Export the function for external use.\nexport { createPasskeyCredential, getPasskeyCredential };\n","// Copyright (C) LoginID\n\nimport {\n AuthCompleteRequestBody,\n AuthInit,\n RegCompleteRequestBody,\n RegInit,\n} from \"../api\";\nimport { createPasskeyCredential, getPasskeyCredential } from \"./webauthn\";\nimport { GetNavigatorCredentialOptions, Transports } from \"../types\";\nimport { AbortControllerManager } from \"./abort-controller\";\nimport { bufferToBase64Url } from \"../utils/crypto\";\n\nexport class WebAuthnHelper {\n /**\n * A helper function that attempts public-key credential authentication using WebAuthn API. It is designed to be used with LoginID's\n * passkey authentication flow. The function takes an authentication initialization response and returns an authentication completion request body.\n */\n static async getNavigatorCredential(\n authInitResponseBody: AuthInit,\n options: GetNavigatorCredentialOptions = {},\n ) {\n const { assertionOptions, session } = authInitResponseBody;\n\n if (!options.abortController) {\n AbortControllerManager.renewWebAuthnAbortController();\n options.abortController = AbortControllerManager.abortController;\n } else {\n AbortControllerManager.assignWebAuthnAbortController(\n options.abortController,\n );\n }\n\n const credential = await getPasskeyCredential(assertionOptions, options);\n const response = credential.response as AuthenticatorAssertionResponse;\n\n const authCompleteRequestBody: AuthCompleteRequestBody = {\n assertionResult: {\n authenticatorData: bufferToBase64Url(response.authenticatorData),\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n credentialId: credential.id,\n signature: bufferToBase64Url(response.signature),\n ...(response.userHandle && {\n userHandle: bufferToBase64Url(response.userHandle),\n }),\n },\n session: session,\n };\n\n return authCompleteRequestBody;\n }\n\n /**\n * A helper function that creates a public-key credential using WebAuthn API.\n * It processes the response body from registration initialization and returns\n * a registration completion request body.\n */\n static async createNavigatorCredential(regInitResponseBody: RegInit) {\n const { registrationRequestOptions, session } = regInitResponseBody;\n\n AbortControllerManager.renewWebAuthnAbortController();\n\n const credential = await createPasskeyCredential(\n registrationRequestOptions,\n );\n const response = credential.response as AuthenticatorAttestationResponse;\n\n const publicKey = response.getPublicKey && response.getPublicKey();\n const publicKeyAlg =\n response.getPublicKeyAlgorithm && response.getPublicKeyAlgorithm();\n const authenticatorData =\n response.getAuthenticatorData && response.getAuthenticatorData();\n const transports =\n response.getTransports && (response.getTransports() as Transports);\n\n const regCompleteRequestBody: RegCompleteRequestBody = {\n creationResult: {\n attestationObject: bufferToBase64Url(response.attestationObject),\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n credentialId: credential.id,\n ...(publicKey && { publicKey: bufferToBase64Url(publicKey) }),\n ...(publicKeyAlg && { publicKeyAlgorithm: publicKeyAlg }),\n ...(authenticatorData && {\n authenticatorData: bufferToBase64Url(authenticatorData),\n }),\n ...(transports && { transports: transports }),\n },\n session: session,\n };\n\n return regCompleteRequestBody;\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { PasskeyRenameRequestBody } from \"../models/PasskeyRenameRequestBody\";\nimport type { PasskeyCollection } from \"../models/PasskeyCollection\";\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\nimport type { Aaguid } from \"../models/Aaguid\";\nexport class PasskeysService {\n constructor(public readonly httpRequest: BaseHttpRequest) {}\n /**\n * List passkeys of the user\n * @returns PasskeyCollection OK response.\n * @throws ApiError\n */\n public passkeysPasskeysList({\n authorization,\n }: {\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<PasskeyCollection> {\n return this.httpRequest.request({\n method: \"GET\",\n url: \"/fido2/v2/passkeys\",\n headers: {\n Authorization: authorization,\n },\n errors: {\n 401: `unauthorized: Unauthorized response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Delete passkey\n * @returns void\n * @throws ApiError\n */\n public passkeysPasskeyDelete({\n id,\n authorization,\n }: {\n /**\n * Internal passkey identifier\n */\n id: string;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<void> {\n return this.httpRequest.request({\n method: \"DELETE\",\n url: \"/fido2/v2/passkeys/{id}\",\n path: {\n id: id,\n },\n headers: {\n Authorization: authorization,\n },\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Rename passkey\n * @returns void\n * @throws ApiError\n */\n public passkeysPasskeyRename({\n id,\n requestBody,\n authorization,\n }: {\n /**\n * Internal passkey identifier\n */\n id: string;\n requestBody: PasskeyRenameRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<void> {\n return this.httpRequest.request({\n method: \"PUT\",\n url: \"/fido2/v2/passkeys/{id}\",\n path: {\n id: id,\n },\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Get AAGUID Metadata\n * @returns Aaguid OK response.\n * @throws ApiError\n */\n public passkeysAaguidMetadata({\n aaguid,\n authorization,\n }: {\n /**\n * AAGUID identifier\n */\n aaguid: string;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<Aaguid> {\n return this.httpRequest.request({\n method: \"GET\",\n url: \"/fido2/v2/passkeys/aaguid/{aaguid}\",\n path: {\n aaguid: aaguid,\n },\n headers: {\n Authorization: authorization,\n },\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport type { CancelablePromise } from \"./CancelablePromise\";\nimport type { OpenAPIConfig } from \"./OpenAPI\";\n\nexport abstract class BaseHttpRequest {\n constructor(public readonly config: OpenAPIConfig) {}\n\n public abstract request<T>(options: ApiRequestOptions): CancelablePromise<T>;\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nexport class CancelError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CancelError\";\n }\n\n public get isCancelled(): boolean {\n return true;\n }\n}\n\nexport interface OnCancel {\n readonly isResolved: boolean;\n readonly isRejected: boolean;\n readonly isCancelled: boolean;\n\n (cancelHandler: () => void): void;\n}\n\nexport class CancelablePromise<T> implements Promise<T> {\n #isResolved: boolean;\n #isRejected: boolean;\n #isCancelled: boolean;\n readonly #cancelHandlers: (() => void)[];\n readonly #promise: Promise<T>;\n #resolve?: (value: T | PromiseLike<T>) => void;\n #reject?: (reason?: any) => void;\n\n constructor(\n executor: (\n resolve: (value: T | PromiseLike<T>) => void,\n reject: (reason?: any) => void,\n onCancel: OnCancel,\n ) => void,\n ) {\n this.#isResolved = false;\n this.#isRejected = false;\n this.#isCancelled = false;\n this.#cancelHandlers = [];\n this.#promise = new Promise<T>((resolve, reject) => {\n this.#resolve = resolve;\n this.#reject = reject;\n\n const onResolve = (value: T | PromiseLike<T>): void => {\n if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n return;\n }\n this.#isResolved = true;\n if (this.#resolve) this.#resolve(value);\n };\n\n const onReject = (reason?: any): void => {\n if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n return;\n }\n this.#isRejected = true;\n if (this.#reject) this.#reject(reason);\n };\n\n const onCancel = (cancelHandler: () => void): void => {\n if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n return;\n }\n this.#cancelHandlers.push(cancelHandler);\n };\n\n Object.defineProperty(onCancel, \"isResolved\", {\n get: (): boolean => this.#isResolved,\n });\n\n Object.defineProperty(onCancel, \"isRejected\", {\n get: (): boolean => this.#isRejected,\n });\n\n Object.defineProperty(onCancel, \"isCancelled\", {\n get: (): boolean => this.#isCancelled,\n });\n\n return executor(onResolve, onReject, onCancel as OnCancel);\n });\n }\n\n get [Symbol.toStringTag]() {\n return \"Cancellable Promise\";\n }\n\n public then<TResult1 = T, TResult2 = never>(\n onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.#promise.then(onFulfilled, onRejected);\n }\n\n public catch<TResult = never>(\n onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n ): Promise<T | TResult> {\n return this.#promise.catch(onRejected);\n }\n\n public finally(onFinally?: (() => void) | null): Promise<T> {\n return this.#promise.finally(onFinally);\n }\n\n public cancel(): void {\n if (this.#isResolved || this.#isRejected || this.#isCancelled) {\n return;\n }\n this.#isCancelled = true;\n if (this.#cancelHandlers.length) {\n try {\n for (const cancelHandler of this.#cancelHandlers) {\n cancelHandler();\n }\n } catch (error) {\n console.warn(\"Cancellation threw an error\", error);\n return;\n }\n }\n this.#cancelHandlers.length = 0;\n if (this.#reject) this.#reject(new CancelError(\"Request aborted\"));\n }\n\n public get isCancelled(): boolean {\n return this.#isCancelled;\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport type { ApiResult } from \"./ApiResult\";\n\nexport class ApiError extends Error {\n public readonly url: string;\n public readonly status: number;\n public readonly statusText: string;\n public readonly body: any;\n public readonly request: ApiRequestOptions;\n\n constructor(\n request: ApiRequestOptions,\n response: ApiResult,\n message: string,\n ) {\n super(message);\n\n this.name = \"ApiError\";\n this.url = response.url;\n this.status = response.status;\n this.statusText = response.statusText;\n this.body = response.body;\n this.request = request;\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n/* eslint-disable */\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport { CancelablePromise } from \"./CancelablePromise\";\nimport type { OnCancel } from \"./CancelablePromise\";\nimport type { OpenAPIConfig } from \"./OpenAPI\";\nimport type { ApiResult } from \"./ApiResult\";\nimport { ApiError } from \"./ApiError\";\n\nexport const isDefined = <T>(\n value: T | null | undefined,\n): value is Exclude<T, null | undefined> => {\n return value !== undefined && value !== null;\n};\n\nexport const isString = (value: any): value is string => {\n return typeof value === \"string\";\n};\n\nexport const isStringWithValue = (value: any): value is string => {\n return isString(value) && value !== \"\";\n};\n\nexport const isBlob = (value: any): value is Blob => {\n return (\n typeof value === \"object\" &&\n typeof value.type === \"string\" &&\n typeof value.stream === \"function\" &&\n typeof value.arrayBuffer === \"function\" &&\n typeof value.constructor === \"function\" &&\n typeof value.constructor.name === \"string\" &&\n /^(Blob|File)$/.test(value.constructor.name) &&\n /^(Blob|File)$/.test(value[Symbol.toStringTag])\n );\n};\n\nexport const isFormData = (value: any): value is FormData => {\n return value instanceof FormData;\n};\n\nexport const base64 = (str: string): string => {\n try {\n return btoa(str);\n } catch (err) {\n // @ts-ignore\n return Buffer.from(str).toString(\"base64\");\n }\n};\n\nexport const getQueryString = (params: Record<string, any>): string => {\n const qs: string[] = [];\n\n const append = (key: string, value: any) => {\n qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n };\n\n const process = (key: string, value: any) => {\n if (isDefined(value)) {\n if (Array.isArray(value)) {\n value.forEach((v) => {\n process(key, v);\n });\n } else if (typeof value === \"object\") {\n Object.entries(value).forEach(([k, v]) => {\n process(`${key}[${k}]`, v);\n });\n } else {\n append(key, value);\n }\n }\n };\n\n Object.entries(params).forEach(([key, value]) => {\n process(key, value);\n });\n\n if (qs.length > 0) {\n return `?${qs.join(\"&\")}`;\n }\n\n return \"\";\n};\n\nconst getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {\n const encoder = config.ENCODE_PATH || encodeURI;\n\n const path = options.url\n .replace(\"{api-version}\", config.VERSION)\n .replace(/{(.*?)}/g, (substring: string, group: string) => {\n if (options.path?.hasOwnProperty(group)) {\n return encoder(String(options.path[group]));\n }\n return substring;\n });\n\n const url = `${config.BASE}${path}`;\n if (options.query) {\n return `${url}${getQueryString(options.query)}`;\n }\n return url;\n};\n\nexport const getFormData = (\n options: ApiRequestOptions,\n): FormData | undefined => {\n if (options.formData) {\n const formData = new FormData();\n\n const process = (key: string, value: any) => {\n if (isString(value) || isBlob(value)) {\n formData.append(key, value);\n } else {\n formData.append(key, JSON.stringify(value));\n }\n };\n\n Object.entries(options.formData)\n .filter(([_, value]) => isDefined(value))\n .forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((v) => process(key, v));\n } else {\n process(key, value);\n }\n });\n\n return formData;\n }\n return undefined;\n};\n\ntype Resolver<T> = (options: ApiRequestOptions) => Promise<T>;\n\nexport const resolve = async <T>(\n options: ApiRequestOptions,\n resolver?: T | Resolver<T>,\n): Promise<T | undefined> => {\n if (typeof resolver === \"function\") {\n return (resolver as Resolver<T>)(options);\n }\n return resolver;\n};\n\nexport const getHeaders = async (\n config: OpenAPIConfig,\n options: ApiRequestOptions,\n): Promise<Headers> => {\n const [token, username, password, additionalHeaders] = await Promise.all([\n resolve(options, config.TOKEN),\n resolve(options, config.USERNAME),\n resolve(options, config.PASSWORD),\n resolve(options, config.HEADERS),\n ]);\n\n const headers = Object.entries({\n Accept: \"application/json\",\n ...additionalHeaders,\n ...options.headers,\n })\n .filter(([_, value]) => isDefined(value))\n .reduce(\n (headers, [key, value]) => ({\n ...headers,\n [key]: String(value),\n }),\n {} as Record<string, string>,\n );\n\n if (isStringWithValue(token)) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n if (isStringWithValue(username) && isStringWithValue(password)) {\n const credentials = base64(`${username}:${password}`);\n headers[\"Authorization\"] = `Basic ${credentials}`;\n }\n\n if (options.body) {\n if (options.mediaType) {\n headers[\"Content-Type\"] = options.mediaType;\n } else if (isBlob(options.body)) {\n headers[\"Content-Type\"] = options.body.type || \"application/octet-stream\";\n } else if (isString(options.body)) {\n headers[\"Content-Type\"] = \"text/plain\";\n } else if (!isFormData(options.body)) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n }\n\n return new Headers(headers);\n};\n\nexport const getRequestBody = (options: ApiRequestOptions): any => {\n if (options.body !== undefined) {\n if (options.mediaType?.includes(\"/json\")) {\n return JSON.stringify(options.body);\n } else if (\n isString(options.body) ||\n isBlob(options.body) ||\n isFormData(options.body)\n ) {\n return options.body;\n } else {\n return JSON.stringify(options.body);\n }\n }\n return undefined;\n};\n\nexport const sendRequest = async (\n config: OpenAPIConfig,\n options: ApiRequestOptions,\n url: string,\n body: any,\n formData: FormData | undefined,\n headers: Headers,\n onCancel: OnCancel,\n): Promise<Response> => {\n const controller = new AbortController();\n\n const request: RequestInit = {\n headers,\n body: body ?? formData,\n method: options.method,\n signal: controller.signal,\n };\n\n if (config.WITH_CREDENTIALS) {\n request.credentials = config.CREDENTIALS;\n }\n\n onCancel(() => controller.abort());\n\n return await fetch(url, request);\n};\n\nexport const getResponseHeader = (\n response: Response,\n responseHeader?: string,\n): string | undefined => {\n if (responseHeader) {\n const content = response.headers.get(responseHeader);\n if (isString(content)) {\n return content;\n }\n }\n return undefined;\n};\n\nexport const getResponseBody = async (response: Response): Promise<any> => {\n if (response.status !== 204) {\n try {\n const contentType = response.headers.get(\"Content-Type\");\n if (contentType) {\n const jsonTypes = [\"application/json\", \"application/problem+json\"];\n const isJSON = jsonTypes.some((type) =>\n contentType.toLowerCase().startsWith(type),\n );\n if (isJSON) {\n return await response.json();\n } else {\n return await response.text();\n }\n }\n } catch (error) {\n console.error(error);\n }\n }\n return undefined;\n};\n\nexport const catchErrorCodes = (\n options: ApiRequestOptions,\n result: ApiResult,\n): void => {\n const errors: Record<number, string> = {\n 400: \"Bad Request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not Found\",\n 500: \"Internal Server Error\",\n 502: \"Bad Gateway\",\n 503: \"Service Unavailable\",\n ...options.errors,\n };\n\n const error = errors[result.status];\n if (error) {\n throw new ApiError(options, result, error);\n }\n\n if (!result.ok) {\n const errorStatus = result.status ?? \"unknown\";\n const errorStatusText = result.statusText ?? \"unknown\";\n const errorBody = (() => {\n try {\n return JSON.stringify(result.body, null, 2);\n } catch (e) {\n return undefined;\n }\n })();\n\n throw new ApiError(\n options,\n result,\n `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`,\n );\n }\n};\n\n/**\n * Request method\n * @param config The OpenAPI configuration object\n * @param options The request options from the service\n * @returns CancelablePromise<T>\n * @throws ApiError\n */\nexport const request = <T>(\n config: OpenAPIConfig,\n options: ApiRequestOptions,\n): CancelablePromise<T> => {\n return new CancelablePromise(async (resolve, reject, onCancel) => {\n try {\n const url = getUrl(config, options);\n const formData = getFormData(options);\n const body = getRequestBody(options);\n const headers = await getHeaders(config, options);\n\n if (!onCancel.isCancelled) {\n const response = await sendRequest(\n config,\n options,\n url,\n body,\n formData,\n headers,\n onCancel,\n );\n const responseBody = await getResponseBody(response);\n const responseHeader = getResponseHeader(\n response,\n options.responseHeader,\n );\n\n const result: ApiResult = {\n url,\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n body: responseHeader ?? responseBody,\n };\n\n catchErrorCodes(options, result);\n\n resolve(result.body);\n }\n } catch (error) {\n reject(error);\n }\n });\n};\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\nimport type { CancelablePromise } from \"./CancelablePromise\";\nimport { BaseHttpRequest } from \"./BaseHttpRequest\";\nimport { request as __request } from \"./request\";\nimport type { OpenAPIConfig } from \"./OpenAPI\";\n\nexport class FetchHttpRequest extends BaseHttpRequest {\n constructor(config: OpenAPIConfig) {\n super(config);\n }\n\n /**\n * Request method\n * @param options The request options from the service\n * @returns CancelablePromise<T>\n * @throws ApiError\n */\n public override request<T>(options: ApiRequestOptions): CancelablePromise<T> {\n return __request(this.config, options);\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { AuthCodeRequestSMSRequestBody } from \"../models/AuthCodeRequestSMSRequestBody\";\nimport type { AuthCodeVerifyRequestBody } from \"../models/AuthCodeVerifyRequestBody\";\nimport type { AuthCompleteRequestBody } from \"../models/AuthCompleteRequestBody\";\nimport type { AuthInitRequestBody } from \"../models/AuthInitRequestBody\";\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\nimport type { AuthCode } from \"../models/AuthCode\";\nimport type { AuthInit } from \"../models/AuthInit\";\nimport type { JWT } from \"../models/JWT\";\nexport class AuthService {\n constructor(public readonly httpRequest: BaseHttpRequest) {}\n /**\n * Complete WebAuthn authentication\n * @returns JWT OK response.\n * @throws ApiError\n */\n public authAuthComplete({\n requestBody,\n }: {\n requestBody: AuthCompleteRequestBody;\n }): CancelablePromise<JWT> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/auth/complete\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 404: `forbidden: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Start WebAuthn authentication flow\n * @returns AuthInit OK response.\n * @throws ApiError\n */\n public authAuthInit({\n requestBody,\n userAgent,\n }: {\n requestBody: AuthInitRequestBody;\n /**\n * Raw user-agent header as set by a browser\n */\n userAgent?: string;\n }): CancelablePromise<AuthInit> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/auth/init\",\n headers: {\n \"User-Agent\": userAgent,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Request OTP code by an authenticated user\n * An authenticated user can request an authentication code directly using this\n * method. The code can be used for authentication from another device.\n * @returns AuthCode OK response.\n * @throws ApiError\n */\n public authAuthCodeRequest({\n authorization,\n }: {\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<AuthCode> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/auth/otp\",\n headers: {\n Authorization: authorization,\n },\n errors: {\n 401: `unauthorized: Unauthorized response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Request OTP code to be sent via email.\n * Send authentication code to the provided email. The SMS will only be sent\n * if the email address is known to the application, however, this method will\n * return success regardless.\n * @returns void\n * @throws ApiError\n */\n public authAuthCodeRequestEmail({\n requestBody,\n }: {\n requestBody: AuthCodeRequestSMSRequestBody;\n }): CancelablePromise<void> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/auth/otp/email\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Request OTP code to be sent via SMS.\n * Send authentication code to the provided phone number. The SMS will only be\n * sent if the phone is registered with the application, however, it will return\n * success regardless.\n * @returns void\n * @throws ApiError\n */\n public authAuthCodeRequestSms({\n requestBody,\n }: {\n requestBody: AuthCodeRequestSMSRequestBody;\n }): CancelablePromise<void> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/auth/otp/sms\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Verify authentication code and return JWT access token with appropriate scopes\n * @returns JWT OK response.\n * @throws ApiError\n */\n public authAuthCodeVerify({\n requestBody,\n }: {\n requestBody: AuthCodeVerifyRequestBody;\n }): CancelablePromise<JWT> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/auth/otp/verify\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { MfaThirdPartyAuthVerifyRequestBody } from \"../models/MfaThirdPartyAuthVerifyRequestBody\";\nimport type { MfaOtpRequestResponseBody } from \"../models/MfaOtpRequestResponseBody\";\nimport type { MfaPasskeyAuthRequestBody } from \"../models/MfaPasskeyAuthRequestBody\";\nimport type { MfaOtpRequestRequestBody } from \"../models/MfaOtpRequestRequestBody\";\nimport type { MfaPasskeyRegRequestBody } from \"../models/MfaPasskeyRegRequestBody\";\nimport type { MfaOtpVerifyRequestBody } from \"../models/MfaOtpVerifyRequestBody\";\nimport type { MfaBeginRequestBody } from \"../models/MfaBeginRequestBody\";\nimport type { MfaErrorRequestBody } from \"../models/MfaErrorRequestBody\";\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\nimport type { MfaNext } from \"../models/MfaNext\";\nimport type { Mfa } from \"../models/Mfa\";\nexport class MfaService {\n constructor(public readonly httpRequest: BaseHttpRequest) {}\n /**\n * Begin and appropriate flow for the provided username.\n * Perform pre-authentication.\n * @returns MfaNext OK response.\n * @throws ApiError\n */\n public mfaMfaBegin({\n requestBody,\n userAgent,\n }: {\n requestBody: MfaBeginRequestBody;\n /**\n * Raw user-agent header as set by a browser\n */\n userAgent?: string;\n }): CancelablePromise<MfaNext> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/begin\",\n headers: {\n \"User-Agent\": userAgent,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 403: `forbidden: Forbidden response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Verify auth token created by a third party via management API.\n * Report a client error. It does not change state of the flow.\n * @returns void\n * @throws ApiError\n */\n public mfaMfaError({\n requestBody,\n authorization,\n }: {\n requestBody: MfaErrorRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<void> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/error\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Request OTP authentication using one of the available methods.\n * Request OTP.\n * @returns MfaOtpRequestResponseBody OK response.\n * @throws ApiError\n */\n public mfaMfaOtpRequest({\n requestBody,\n authorization,\n }: {\n requestBody: MfaOtpRequestRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<MfaOtpRequestResponseBody> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/otp/request\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Confirm OTP received in a previous step.\n * Verify OTP received by one of the methods.\n * @returns Mfa OK response.\n * @throws ApiError\n */\n public mfaMfaOtpVerify({\n requestBody,\n authorization,\n }: {\n requestBody: MfaOtpVerifyRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<Mfa> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/otp/verify\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `additional_auth_required: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Authenticate using passkey.\n * Authenticate with a passkeys.\n * @returns Mfa OK response.\n * @throws ApiError\n */\n public mfaMfaPasskeyAuth({\n requestBody,\n authorization,\n }: {\n requestBody: MfaPasskeyAuthRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<Mfa> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/passkey/auth\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `additional_auth_required: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Register a new passkey.\n * Register a new passkey.\n * @returns Mfa OK response.\n * @throws ApiError\n */\n public mfaMfaPasskeyReg({\n requestBody,\n authorization,\n }: {\n requestBody: MfaPasskeyRegRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<Mfa> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/passkey/reg\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Transaction confirmation using passkey.\n * Confirm a transaction with a passkey.\n * @returns Mfa OK response.\n * @throws ApiError\n */\n public mfaMfaPasskeyTx({\n requestBody,\n authorization,\n }: {\n requestBody: MfaPasskeyAuthRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<Mfa> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/passkey/tx\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Verify auth token created by a third party via management API.\n * Verify authentication token received from a third party.\n * @returns Mfa OK response.\n * @throws ApiError\n */\n public mfaMfaThirdPartyAuthVerify({\n requestBody,\n authorization,\n }: {\n requestBody: MfaThirdPartyAuthVerifyRequestBody;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<Mfa> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/mfa/third-party/verify\",\n headers: {\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `additional_auth_required: Unauthorized response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { RegCompleteRequestBody } from \"../models/RegCompleteRequestBody\";\nimport type { RegInitRequestBody } from \"../models/RegInitRequestBody\";\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\nimport type { RegInit } from \"../models/RegInit\";\nimport type { JWT } from \"../models/JWT\";\nexport class RegService {\n constructor(public readonly httpRequest: BaseHttpRequest) {}\n /**\n * Complete WebAuthn registration flow\n * @returns JWT OK response.\n * @throws ApiError\n */\n public regRegComplete({\n requestBody,\n }: {\n requestBody: RegCompleteRequestBody;\n }): CancelablePromise<JWT> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/reg/complete\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 403: `forbidden: Forbidden response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Start WebAuthn registration flow\n * @returns RegInit OK response.\n * @throws ApiError\n */\n public regRegInit({\n requestBody,\n userAgent,\n authorization,\n }: {\n requestBody: RegInitRequestBody;\n /**\n * Raw user-agent header as set by a browser\n */\n userAgent?: string;\n /**\n * JWT Authorization header\n */\n authorization?: string;\n }): CancelablePromise<RegInit> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/reg/init\",\n headers: {\n \"User-Agent\": userAgent,\n Authorization: authorization,\n },\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 401: `unauthorized: Unauthorized response.`,\n 403: `forbidden: Forbidden response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { TxCompleteRequestBody } from \"../models/TxCompleteRequestBody\";\nimport type { TxInitRequestBody } from \"../models/TxInitRequestBody\";\nimport type { CancelablePromise } from \"../core/CancelablePromise\";\nimport type { BaseHttpRequest } from \"../core/BaseHttpRequest\";\nimport type { TxComplete } from \"../models/TxComplete\";\nimport type { TxInit } from \"../models/TxInit\";\nexport class TxService {\n constructor(public readonly httpRequest: BaseHttpRequest) {}\n /**\n * Complete transaction confirmation\n * @returns TxComplete OK response.\n * @throws ApiError\n */\n public txTxComplete({\n requestBody,\n }: {\n requestBody: TxCompleteRequestBody;\n }): CancelablePromise<TxComplete> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/tx/complete\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 403: `forbidden: Forbidden response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n /**\n * Start transaction confirmation flow\n * @returns TxInit OK response.\n * @throws ApiError\n */\n public txTxInit({\n requestBody,\n }: {\n requestBody: TxInitRequestBody;\n }): CancelablePromise<TxInit> {\n return this.httpRequest.request({\n method: \"POST\",\n url: \"/fido2/v2/tx/init\",\n body: requestBody,\n mediaType: \"application/json\",\n errors: {\n 400: `bad_request: Bad Request response.`,\n 404: `not_found: Not Found response.`,\n 500: `internal_error: Internal Server Error response.`,\n },\n });\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { BaseHttpRequest } from \"./core/BaseHttpRequest\";\nimport { PasskeysService } from \"./services/PasskeysService\";\nimport { FetchHttpRequest } from \"./core/FetchHttpRequest\";\nimport { AuthService } from \"./services/AuthService\";\nimport type { OpenAPIConfig } from \"./core/OpenAPI\";\nimport { MfaService } from \"./services/MfaService\";\nimport { RegService } from \"./services/RegService\";\nimport { TxService } from \"./services/TxService\";\ntype HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;\nexport class LoginIDService {\n public readonly auth: AuthService;\n public readonly mfa: MfaService;\n public readonly passkeys: PasskeysService;\n public readonly reg: RegService;\n public readonly tx: TxService;\n public readonly request: BaseHttpRequest;\n constructor(\n config?: Partial<OpenAPIConfig>,\n HttpRequest: HttpRequestConstructor = FetchHttpRequest,\n ) {\n this.request = new HttpRequest({\n BASE: config?.BASE ?? \"https://api.loginid.io/fido2/v2\",\n VERSION: config?.VERSION ?? \"2.0\",\n WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,\n CREDENTIALS: config?.CREDENTIALS ?? \"include\",\n TOKEN: config?.TOKEN,\n USERNAME: config?.USERNAME,\n PASSWORD: config?.PASSWORD,\n HEADERS: config?.HEADERS,\n ENCODE_PATH: config?.ENCODE_PATH,\n });\n this.auth = new AuthService(this.request);\n this.mfa = new MfaService(this.request);\n this.passkeys = new PasskeysService(this.request);\n this.reg = new RegService(this.request);\n this.tx = new TxService(this.request);\n }\n}\n","// Copyright (C) LoginID\n\n/* istanbul ignore file */\n/* tslint:disable */\n\nimport type { ApiRequestOptions } from \"./ApiRequestOptions\";\n\ntype Resolver<T> = (options: ApiRequestOptions) => Promise<T>;\ntype Headers = Record<string, string>;\n\nexport type OpenAPIConfig = {\n BASE: string;\n VERSION: string;\n WITH_CREDENTIALS: boolean;\n CREDENTIALS: \"include\" | \"omit\" | \"same-origin\";\n TOKEN?: string | Resolver<string> | undefined;\n USERNAME?: string | Resolver<string> | undefined;\n PASSWORD?: string | Resolver<string> | undefined;\n HEADERS?: Headers | Resolver<Headers> | undefined;\n ENCODE_PATH?: ((path: string) => string) | undefined;\n};\n\nexport const OpenAPI: OpenAPIConfig = {\n BASE: \"https://api.loginid.io/fido2/v2\",\n VERSION: \"2.0\",\n WITH_CREDENTIALS: false,\n CREDENTIALS: \"include\",\n TOKEN: undefined,\n USERNAME: undefined,\n PASSWORD: undefined,\n HEADERS: undefined,\n ENCODE_PATH: undefined,\n};\n","// Copyright (C) LoginID\n\nimport {\n MfaBeginOptions,\n MfaFactorName,\n MfaInfo,\n MfaSessionResult,\n RemainingFactor,\n RequireProps,\n} from \"../controllers/types\";\nimport { LoginIDTokenSet } from \"../types\";\nimport { MfaNext } from \"../api\";\n\n/**\n * Merges provided options with default values for passkey options.\n *\n * @param {string} username Username for which the passkey options are being created.\n * @param {MfaBeginOptions} options Options to merge with default values.\n * @returns {MfaBeginOptions} The complete set of passkey options with defaults applied.\n */\nexport const mfaOptions = (\n username: string,\n options: MfaBeginOptions,\n): RequireProps<MfaBeginOptions, \"usernameType\" | \"displayName\"> => {\n return {\n ...options,\n usernameType: options.usernameType || \"other\",\n displayName: options.displayName || username,\n };\n};\n\n/**\n * Converts an `MfaNext` result into an `MfaInfo` object.\n *\n * @param {MfaNext} mfaNextResult - The result from an MFA authentication step.\n * @param {string} [username] - The username associated with the MFA session (optional).\n * @returns {MfaInfo} - The structured MFA information.\n */\nexport const toMfaInfo = (\n mfaNextResult: MfaNext,\n username?: string,\n): MfaInfo => {\n return {\n username: username,\n flow: mfaNextResult.flow,\n session: mfaNextResult.session,\n next: mfaNextResult.next,\n };\n};\n\n/**\n * Converts MFA information and token set into an `MfaSessionResult` object.\n *\n * @param {MfaInfo | null} [info] - The MFA session information, if available.\n * @param {LoginIDTokenSet} [tokenSet] - The token set containing authentication tokens.\n * @returns {MfaSessionResult} - The structured MFA session result.\n */\nexport const toMfaSessionDetails = (\n info?: MfaInfo | null,\n tokenSet?: LoginIDTokenSet,\n): MfaSessionResult => {\n const remainingFactors: RemainingFactor[] =\n info?.next?.map((factor) => {\n const { name, label, desc } = factor.action;\n const result: RemainingFactor = {\n type: name,\n label,\n ...(desc && { description: desc }),\n };\n\n if (factor.options) {\n const options = factor.options\n .filter(\n (option) =>\n (name === \"otp:sms\" || name === \"otp:email\") && option.label,\n )\n .map((option) => option.label!)\n .filter(Boolean);\n\n if (options.length) {\n result.options = options;\n }\n\n if (\n name === \"passkey:reg\" ||\n name === \"passkey:auth\" ||\n name === \"passkey:tx\"\n ) {\n const passkeyOption = factor.options.find((option) => option.value);\n if (passkeyOption) result.value = passkeyOption.value;\n }\n }\n\n return result;\n }) || [];\n\n const factorPriority: MfaFactorName[] = [\n \"passkey:auth\",\n \"passkey:tx\",\n \"otp:sms\",\n \"otp:email\",\n \"external\",\n \"passkey:reg\",\n ];\n\n const nextAction = factorPriority.find((name) =>\n info?.next?.some((factor) => factor.action.name === name),\n );\n\n return {\n username: info?.username,\n ...(info?.username && { username: info.username }),\n flow: info?.flow,\n ...(info?.flow && { flow: info.flow }),\n remainingFactors: remainingFactors,\n ...(nextAction && { nextAction }),\n isComplete: !!tokenSet?.accessToken || !!tokenSet?.payloadSignature,\n ...(info?.session && { session: info.session }),\n ...(tokenSet?.idToken && { idToken: tokenSet?.idToken }),\n ...(tokenSet?.accessToken && { accessToken: tokenSet?.accessToken }),\n ...(tokenSet?.refreshToken && { refreshToken: tokenSet?.refreshToken }),\n ...(tokenSet?.payloadSignature && {\n payloadSignature: tokenSet?.payloadSignature,\n }),\n };\n};\n","// Copyright (C) LoginID\n\nimport { LoginIDConfig } from \"../controllers\";\n\nexport class LoginIDConfigValidator {\n /**\n * Holds the configuration settings for the LoginID integration, including API base URL and optional app ID.\n */\n private readonly config: LoginIDConfig;\n\n /**\n * Constructs a new instance of the LoginIDConfigValidator class, initializing with the provided configuration.\n * @param {LoginIDConfig} config Configuration object for LoginID API, including the base URL and optional app ID.\n */\n constructor(config: LoginIDConfig) {\n this.config = config;\n }\n\n /**\n * Retrieves the application ID from the configuration or extracts it from the base URL if not provided.\n * @returns {string} The application ID.\n * @throws {Error} If the app ID is not found in the configuration or the base URL, throws an error.\n */\n getAppId(): string {\n if (this.config.appId) {\n return this.config.appId;\n }\n\n // Regex to capture the subdomain part before the first period in the baseUrl\n const pattern = /https?:\\/\\/([^.]+)\\./;\n const match = this.config.baseUrl.match(pattern);\n if (match) {\n return match[1];\n } else {\n throw new Error(\"Invalid LoginID base URL. App ID not found.\");\n }\n }\n}\n","// Copyright (C) LoginID\n\nimport {\n PublicKeyCredentialCreationOptions,\n PublicKeyCredentialRequestOptions,\n} from \"../api\";\nimport {\n MfaFactor,\n MfaFactorName,\n MfaInfo,\n MfaPerformActionOptions,\n} from \"../controllers\";\nimport { parseJwt } from \"../utils/crypto\";\nimport { LoginIDError } from \"../errors\";\n\n/**\n * Utility class for validating parameters related to LoginID MFA operations.\n */\nexport class LoginIDParamValidator {\n /**\n * Validates and extracts necessary parameters for performing an MFA factor.\n *\n * @param {MfaFactorName} factorName - The name of the MFA factor being validated.\n * @param {MfaInfo | null} info - The current MFA session information.\n * @param {MfaPerformActionOptions} options - The provided options for performing the MFA factor.\n * @returns {Pick<Complete<MfaPerformActionOptions>, \"payload\" | \"session\">} - The validated session and payload.\n */\n public static mfaOptionValidator(\n factorName: MfaFactorName,\n info: MfaInfo | null,\n options: MfaPerformActionOptions,\n ): Pick<Required<MfaPerformActionOptions>, \"payload\" | \"session\"> {\n const { session = info?.session, payload = \"\" } = options;\n\n if (!session) {\n throw new LoginIDError(\"A session is required to perform MFA factor.\");\n }\n\n if (payload) {\n return { session, payload };\n }\n\n const canFindPayloadInInfo = new Set<MfaFactorName>([\n \"passkey:reg\",\n \"passkey:auth\",\n \"passkey:tx\",\n \"otp:email\",\n \"otp:sms\",\n ]);\n if (!info?.next || !canFindPayloadInInfo.has(factorName)) {\n throw new LoginIDError(\"Payload is required to perform MFA factor.\");\n }\n\n const factor = info.next.find((f) => f.action.name === factorName);\n if (!factor) {\n throw new LoginIDError(`No matching factor found for ${factorName}.`);\n }\n\n const getFactorPayload = (factor: MfaFactor, key?: string): string => {\n if (!factor.options?.length) {\n throw new LoginIDError(`Payload is required for ${factorName}.`);\n }\n\n const isPasskey = new Set<MfaFactorName>([\n \"passkey:reg\",\n \"passkey:auth\",\n \"passkey:tx\",\n ]);\n if (isPasskey.has(factorName)) {\n return factor.options[0].value;\n }\n\n let selectedOption: string | undefined;\n\n // If key is provided (e.g., \"email:primary\"), find the option with that key\n if (key) {\n selectedOption = factor.options.find(\n (option: any) => option.name === key,\n )?.label;\n } else {\n selectedOption = factor.options[0]?.label;\n }\n\n if (!selectedOption) {\n throw new LoginIDError(`Contact is not found for ${factorName}.`);\n }\n\n return selectedOption;\n };\n\n switch (factorName) {\n case \"passkey:reg\":\n case \"passkey:auth\":\n case \"passkey:tx\":\n return { session, payload: getFactorPayload(factor) };\n\n case \"otp:email\":\n return { session, payload: getFactorPayload(factor, \"email:primary\") };\n\n case \"otp:sms\":\n return { session, payload: getFactorPayload(factor) };\n }\n\n throw new LoginIDError(\"Payload is required to perform MFA factor.\");\n }\n\n /**\n * Validates and parses a passkey payload.\n *\n * @param {string} payload - The encoded passkey payload.\n * @returns {PublicKeyCredentialCreationOptions | PublicKeyCredentialRequestOptions} - The parsed passkey options.\n */\n public static validatePasskeyPayload(\n payload: string,\n ): PublicKeyCredentialCreationOptions | PublicKeyCredentialRequestOptions {\n if (!payload) {\n throw new LoginIDError(\"Payload is required for passkeys.\");\n }\n\n const options = parseJwt(\".\" + payload);\n if (!options) {\n throw new LoginIDError(\"Invalid payload for passkeys.\");\n }\n\n if (LoginIDParamValidator.isPublicKeyCredentialCreationOptions(options)) {\n return options;\n }\n\n if (LoginIDParamValidator.isPublicKeyCredentialRequestOptions(options)) {\n return options;\n }\n\n throw new LoginIDError(\"Invalid payload for passkey.\");\n }\n\n /**\n * Checks if the given object is a valid `PublicKeyCredentialCreationOptions`.\n *\n * @param {any} options - The object to check.\n * @returns {options is PublicKeyCredentialCreationOptions} - `true` if valid, otherwise `false`.\n */\n public static isPublicKeyCredentialCreationOptions(\n options: any,\n ): options is PublicKeyCredentialCreationOptions {\n return !!(\n options.rp?.id &&\n options.challenge &&\n options.pubKeyCredParams &&\n options.user?.id\n );\n }\n\n /**\n * Checks if the given object is a valid `PublicKeyCredentialRequestOptions`.\n *\n * @param {any} options - The object to check.\n * @returns {options is PublicKeyCredentialRequestOptions} - `true` if valid, otherwise `false`.\n */\n public static isPublicKeyCredentialRequestOptions(\n options: any,\n ): options is PublicKeyCredentialRequestOptions {\n return !!(\n options.rpId &&\n options.challenge &&\n options.allowCredentials &&\n options.userVerification\n );\n }\n}\n","// Copyright (C) LoginID\n\nimport { AuthzTokenOptions, LoginIDTokenSet, SessionInfo } from \"../types\";\nimport { deleteCookie, getCookie, setCookie } from \"../utils/browser\";\nimport { LoginIDConfigValidator } from \"../validators\";\nimport { LoginIDConfig } from \"../controllers\";\nimport { parseJwt } from \"../utils/crypto\";\nimport { Mfa } from \"../api\";\n\nexport class SessionManager {\n /**\n * Holds the configuration settings for the LoginID integration, including API base URL.\n */\n protected config: LoginIDConfigValidator;\n\n /**\n * Initializes a new instance of SessionManager with the provided configuration.\n *\n * @param {LoginIDConfig} config Configuration object for LoginID.\n */\n constructor(config: LoginIDConfig) {\n this.config = new LoginIDConfigValidator(config);\n }\n\n /**\n * Retrieves the authentication token from the provided options or from cookies if not available in options.\n *\n * @param {AuthzTokenOptions} options Options containing the token.\n * @returns {string} The authentication token.\n */\n public getToken(options: AuthzTokenOptions): string {\n if (options.authzToken) {\n return options.authzToken;\n } else {\n const token = this.getJwtCookie();\n if (token) {\n return token;\n } else {\n return \"\";\n }\n }\n }\n\n /**\n * Retrieves the currently authenticated user's session information.\n *\n * @returns {LoginIDUser | null} The currently authenticated user's information, including username and id.\n * It will return null if user is not authenticated\n */\n public getSessionInfo(): SessionInfo | null {\n if (!this.isLoggedIn()) {\n return null;\n }\n const data = parseJwt(\n this.getJwtCookie() || this.retrieveToken(\"accessToken\") || \"{}\",\n );\n const user: SessionInfo = {\n username: data.username,\n id: data.sub,\n };\n return user;\n }\n\n /**\n * Returns the dynamic Cookie name holding the authorization token for the given application.\n *\n * @returns {string} The name of the cookie\n */\n public getJwtCookieName(): string {\n return `LoginID_${this.config.getAppId()}_token`;\n }\n\n /**\n * Returns the dynamic Cookie name holding the identification token for the given user.\n *\n * @returns {string} The name of the cookie\n */\n public getIdTokenName(): string {\n return `LoginID_${this.config.getAppId()}_id_token`;\n }\n\n /**\n * Returns the dynamic Cookie name holding the access token for the given user.\n *\n * @returns {string} The name of the cookie\n */\n public getAccessTokenName(): string {\n return `LoginID_${this.config.getAppId()}_access_token`;\n }\n\n /**\n * Returns the dynamic Cookie name holding the refresh token for the given user.\n *\n * @returns {string} The name of the cookie\n */\n public getRefreshTokenName(): string {\n return `LoginID_${this.config.getAppId()}_refresh_token`;\n }\n\n /**\n * Returns the dynamic Cookie name holding the payload signature for the given user.\n *\n * @returns {string} The name of the cookie\n */\n public getPayloadSignatureName(): string {\n return `LoginID_${this.config.getAppId()}_payload_signature`;\n }\n\n /**\n * Set jwt token to local Cookie\n *\n * @param {string} jwt Configuration object for LoginID API, including the base URL.\n */\n public setJwtCookie(jwt: string) {\n const token = parseJwt(jwt);\n const expiry = new Date(token.exp * 1000).toUTCString();\n const cookie = `${this.getJwtCookieName()}=${jwt}; expires=${expiry}`;\n setCookie(cookie);\n }\n\n /**\n * Retrieves the JWT access token.\n *\n * @returns {string | undefined} The JWT access token.\n */\n public getJwtCookie(): string | undefined {\n return getCookie(this.getJwtCookieName());\n }\n\n /**\n * Checks if the user is logged in.\n *\n * @returns {boolean}\n */\n public isLoggedIn(): boolean {\n return !!this.getJwtCookie() || !!this.retrieveToken(\"accessToken\");\n }\n\n /**\n * Deletes the jwt cookie.\n */\n public logout() {\n deleteCookie(this.getJwtCookieName());\n deleteCookie(this.getIdTokenName());\n deleteCookie(this.getAccessTokenName());\n deleteCookie(this.getRefreshTokenName());\n deleteCookie(this.getPayloadSignatureName());\n }\n\n /**\n * Set the successful result token set to local Cookie.\n *\n * @param {Mfa} result Configuration object for LoginID API, including the base URL.\n */\n public setTokenSet(result: Mfa) {\n const { accessToken, idToken, payloadSignature, refreshToken } = result;\n\n const setTokenCookie = (name: string, token: string) => {\n if (!token) return;\n const tokenPayload = parseJwt(token);\n const expiry = tokenPayload?.exp\n ? new Date(tokenPayload.exp * 1000).toUTCString()\n : \"\";\n document.cookie = `${name}=${token}; Expires=${expiry};`;\n };\n\n setTokenCookie(this.getIdTokenName(), idToken);\n setTokenCookie(this.getAccessTokenName(), accessToken);\n setTokenCookie(this.getRefreshTokenName(), refreshToken);\n setTokenCookie(this.getPayloadSignatureName(), payloadSignature);\n }\n\n /**\n * Retrieves a specific token by type.\n *\n * @param {string} tokenType The type of token to retrieve ('idToken', 'accessToken', 'refreshToken', 'payloadSignature').\n * @returns {string | undefined} The token value, or null if not found.\n */\n public retrieveToken(\n tokenType: \"idToken\" | \"accessToken\" | \"refreshToken\" | \"payloadSignature\",\n ): string {\n const tokenNameMap = {\n idToken: this.getIdTokenName(),\n accessToken: this.getAccessTokenName(),\n refreshToken: this.getRefreshTokenName(),\n payloadSignature: this.getPayloadSignatureName(),\n };\n const tokenName = tokenNameMap[tokenType];\n // NOTE: Later check for undefined and attempt to use refresh token with service\n return getCookie(tokenName) || \"\";\n }\n\n /**\n * Retrieves the complete token set as a JavaScript object.\n *\n * @returns {LoginIDTokenSet} The token set object.\n */\n public getTokenSet(): LoginIDTokenSet {\n return {\n idToken: this.retrieveToken(\"idToken\"),\n accessToken: this.retrieveToken(\"accessToken\"),\n refreshToken: this.retrieveToken(\"refreshToken\"),\n payloadSignature: this.retrieveToken(\"payloadSignature\"),\n };\n }\n}\n","// Copyright (C) LoginID\n\nimport {\n b2a,\n base64EncodeUrl,\n generateRandomId,\n signWithES256PrivateKey,\n} from \"../utils/crypto\";\nimport { TrustIDClaims } from \"../types\";\n\n/**\n * Along with traditional OO hierarchies, another popular way of building up classes from\n * reusable components is to build them by combining simpler partial classes.\n * https://www.typescriptlang.org/docs/handbook/mixins.html\n * */\nexport const applyMixins = (derivedCtor: any, constructors: any[]) => {\n constructors.forEach((baseCtor) => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {\n Object.defineProperty(\n derivedCtor.prototype,\n name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||\n Object.create(null),\n );\n });\n });\n};\n\n/**\n * Creates a Trust ID payload with the given parameters.\n * @param {string} [id] - The ID for the trust ID.\n * @returns {TrustIDClaims} The Trust ID payload.\n */\nexport const toTrustIDPayload = (\n id?: string,\n): TrustIDClaims => {\n if (!id) {\n id = generateRandomId();\n }\n\n const payload: TrustIDClaims = {\n id: id,\n exp: Math.floor(Date.now() / 1000) + 60,\n };\n\n return payload;\n};\n\n/**\n * Signs a token payload using an ES256 private key.\n * @param {Record<string, any>} payload - The payload to sign.\n * @param {JsonWebKey} publicKeyJwk - The public key associated with the private key.\n * @param {CryptoKey} privateKey - The private key used for signing.\n * @returns {Promise<string>} The signed JWT.\n */\nexport const signJwtWithJwk = async (\n payload: Record<string, any>,\n publicKeyJwk: JsonWebKey,\n privateKey: CryptoKey,\n): Promise<string> => {\n const header = {\n alg: \"ES256\",\n jwk: publicKeyJwk,\n };\n\n const encodedHeader = base64EncodeUrl(b2a(JSON.stringify(header)));\n const encodedPayload = base64EncodeUrl(b2a(JSON.stringify(payload)));\n const unsignedToken = `${encodedHeader}.${encodedPayload}`;\n const signature = await signWithES256PrivateKey(privateKey, unsignedToken);\n\n return `${unsignedToken}.${signature}`;\n};\n","// Copyright (C) LoginID\n\nexport class LocalStorageWrapper {\n /**\n * Stores a value in localStorage under the specified key.\n *\n * @template T - The type of the value to be stored.\n * @param {string} key - The key under which the value will be stored.\n * @param {T} [value] - The value to store. If `undefined`, nothing is stored.\n */\n protected static setItem<T>(key: string, value?: T): void {\n if (value !== undefined) {\n const data = typeof value === \"string\" ? value : JSON.stringify(value);\n localStorage.setItem(key, data);\n }\n }\n\n /**\n * Retrieves a value from localStorage by key.\n *\n * @template T - The expected type of the stored value.\n * @param {string} key - The key of the value to retrieve.\n * @returns {T | null} - The parsed value if JSON, the raw string if not JSON, or `null` if not found.\n */\n protected static getItem<T>(key: string): T | null {\n const data = localStorage.getItem(key);\n if (!data) return null;\n\n try {\n return JSON.parse(data) as T;\n } catch {\n return data as T;\n }\n }\n}\n","// Copyright (C) LoginID\n\nimport { LocalStorageWrapper } from \"./local-storage\";\nimport { randomUUID } from \"../utils/crypto\";\n\n/**\n * A utility class that marks a given localStorage key as `true`.\n *\n * This is useful for simple feature flags, acknowledgements,\n * or tracking if a user has completed a specific action.\n *\n * Extends {@link LocalStorageWrapper} to reuse its localStorage handling logic.\n */\nexport class LocalStorageFlagger extends LocalStorageWrapper {\n /**\n * Sets a boolean `true` value in localStorage under the provided key.\n *\n * @param {string} key - The key to stamp.\n */\n public static stamp(key: string): void {\n this.setItem<boolean>(key, true);\n }\n\n /**\n * Sets a boolean `true` value in localStorage under the provided key.\n *\n * @param {string} key - The key to stamp.\n */\n public static stampWithRandomUUID(key: string): void {\n this.setItem<string>(key, randomUUID());\n }\n\n /**\n * Checks if a key has been stamped (i.e., set to `true`).\n *\n * @param {string} key - The key to check.\n * @returns {boolean} - `true` if the key exists and is `true`, otherwise `false`.\n */\n public static isStamped(key: string): boolean {\n return this.getItem(key)!;\n }\n}\n","// Copyright (C) LoginID\n\nimport { LocalStorageWrapper } from \"./local-storage\";\n\nconst checkoutIdStorageKey = \"LoginID_checkout-id\";\n\n/**\n * The CheckoutIdLocalStorage class provides static methods to persist and retrieve\n * a checkoud ID associated with a merchant.\n */\nexport class CheckoutIdLocalStorage extends LocalStorageWrapper {\n public static persistCheckoutId(checkoutId: string): void {\n this.setItem(checkoutIdStorageKey, checkoutId);\n }\n\n public static getCheckoutId(): string {\n return this.getItem(checkoutIdStorageKey) || \"\";\n }\n}\n","// Copyright (C) LoginID\n\nimport { LocalStorageWrapper } from \"./local-storage\";\n\nconst deviceStorageKey = (appId: string) => `LoginID_${appId}_device-id`;\n\n/**\n * The DeviceStore class provides static methods to persist and retrieve\n * a device ID associated with a LoginID application.\n */\nexport class DeviceStore extends LocalStorageWrapper {\n public static persistDeviceId(appId: string, deviceId?: string): void {\n this.setItem(deviceStorageKey(appId), deviceId);\n }\n\n public static getDeviceId(appId: string): string {\n return this.getItem(deviceStorageKey(appId)) || \"\";\n }\n}\n","// Copyright (C) LoginID\n\nimport { StorageError } from \"../errors\";\n\n/**\n * Wrapper for IndexedDB operations.\n */\nexport class IndexedDBWrapper {\n /**\n * @private @type {string} Name of the database\n */\n private dbName: string;\n\n /**\n * @private @type {number} Version of the database\n */\n private dbVersion: number;\n\n /**\n * @private @type {string} Key for the object store\n */\n private storeKey: string;\n\n /**\n * @private\n * @type {Array<{ name: string; keyPath: string; options?: IDBIndexParameters }>}\n * List of indexes for the object store\n */\n private indexes: {\n name: string;\n keyPath: string[];\n options?: IDBIndexParameters;\n }[];\n\n /**\n * Creates an instance of IndexedDBWrapper.\n * @param {string} dbName - The name of the database.\n * @param {number} dbVersion - The version of the database.\n * @param {string} storeKey - The key for the object store.\n * @param {Array<{ name: string; keyPath: Array<string>; options?: IDBIndexParameters }>} [indexes=[]] - The indexes for the object store.\n */\n constructor(\n dbName: string,\n dbVersion: number,\n storeKey: string,\n indexes: {\n name: string;\n keyPath: string[];\n options?: IDBIndexParameters;\n }[] = [],\n ) {\n this.dbName = dbName;\n this.dbVersion = dbVersion;\n this.storeKey = storeKey;\n this.indexes = indexes;\n }\n\n /**\n * Opens the IndexedDB database.\n * @private\n * @returns {IDBOpenDBRequest} The open request for the database.\n */\n private openDb(): IDBOpenDBRequest {\n const open = indexedDB.open(this.dbName, this.dbVersion);\n\n open.onupgradeneeded = () => {\n const db = open.result;\n if (!db.objectStoreNames.contains(this.storeKey)) {\n const store = db.createObjectStore(this.storeKey, { keyPath: \"id\" });\n this.indexes.forEach(({ name, keyPath, options }) =>\n store.createIndex(name, keyPath, options),\n );\n }\n };\n\n return open;\n }\n\n /**\n * Retrieves all records from the object store using an index.\n * @protected\n * @template T\n * @param {string} indexName - The name of the index.\n * @param {Array<string>} value - The value to search for in the index.\n * @returns {Promise<T[]>} A promise that resolves to an array of matching records.\n */\n protected async getAllByIndex<T>(\n indexName: string,\n value: string[],\n ): Promise<T[]> {\n return new Promise<T[]>((resolve, reject) => {\n const open = this.openDb();\n\n open.onsuccess = () => {\n const db = open.result;\n const tx = db.transaction(this.storeKey, \"readonly\");\n const store = tx.objectStore(this.storeKey);\n const index = store.index(indexName);\n\n const request = index.getAll(value);\n\n request.onsuccess = () => {\n resolve(request.result);\n };\n\n request.onerror = () =>\n reject(\n new StorageError(\n `Failed to fetch records from index ${indexName}.`,\n \"ERROR_STORAGE_FAILED\",\n ),\n );\n };\n\n open.onerror = () =>\n reject(\n new StorageError(\n \"Failed to open the database.\",\n \"ERROR_STORAGE_FAILED_TO_OPEN\",\n ),\n );\n });\n }\n\n /**\n * Retrieves a record from the object store using an index.\n * @protected\n * @template T\n * @param {string} indexName - The name of the index.\n * @param {Array<string>} value - The value to search for in the index.\n * @returns {Promise<T>} A promise that resolves to the retrieved record.\n */\n protected async getByIndex<T>(\n indexName: string,\n value: string[],\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const open = this.openDb();\n\n open.onsuccess = () => {\n const db = open.result;\n const tx = db.transaction(this.storeKey, \"readonly\");\n const store = tx.objectStore(this.storeKey);\n const index = store.index(indexName);\n\n const request = index.get(value);\n\n request.onsuccess = () => {\n const result = request.result;\n if (!result) {\n reject(\n new StorageError(\n `No record found for ${value} in index ${indexName}.`,\n \"ERROR_STORAGE_NOT_FOUND\",\n ),\n );\n } else {\n resolve(result);\n }\n };\n\n request.onerror = () =>\n reject(\n new StorageError(\n `Failed to fetch record from index ${indexName}.`,\n \"ERROR_STORAGE_FAILED\",\n ),\n );\n };\n\n open.onerror = () =>\n reject(\n new StorageError(\n \"Failed to open the database.\",\n \"ERROR_STORAGE_FAILED_TO_OPEN\",\n ),\n );\n });\n }\n\n /**\n * Retrieves the first record from the object store.\n * @protected\n * @template T\n * @returns {Promise<T>} A promise that resolves to the first record in the store.\n */\n protected async getFirstRecord<T>(): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const open = this.openDb();\n\n open.onsuccess = () => {\n const db = open.result;\n const tx = db.transaction(this.storeKey, \"readonly\");\n const store = tx.objectStore(this.storeKey);\n\n const request = store.openCursor();\n\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n resolve(cursor.value);\n } else {\n reject(\n new StorageError(\n \"No records found in the store.\",\n \"ERROR_STORAGE_NOT_FOUND\",\n ),\n );\n }\n };\n\n request.onerror = () =>\n reject(\n new StorageError(\n \"Failed to fetch first record.\",\n \"ERROR_STORAGE_FAILED\",\n ),\n );\n };\n\n open.onerror = () =>\n reject(\n new StorageError(\n \"Failed to open the database.\",\n \"ERROR_STORAGE_FAILED_TO_OPEN\",\n ),\n );\n });\n }\n\n /**\n * Inserts or updates a record in the object store.\n * @protected\n * @template T\n * @param {T} record - The record to be stored.\n * @returns {Promise<void>} A promise that resolves when the record is successfully stored.\n */\n protected async putRecord<T>(record: T): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const open = this.openDb();\n\n open.onsuccess = () => {\n const db = open.result;\n const tx = db.transaction(this.storeKey, \"readwrite\");\n const store = tx.objectStore(this.storeKey);\n\n const request = store.put(record);\n\n request.onsuccess = () => resolve();\n request.onerror = () =>\n reject(\n new StorageError(\"Failed to save record.\", \"ERROR_STORAGE_FAILED\"),\n );\n };\n\n open.onerror = () =>\n reject(\n new StorageError(\n \"Failed to open the database.\",\n \"ERROR_STORAGE_FAILED_TO_OPEN\",\n ),\n );\n });\n }\n\n /**\n * Deletes a record from the object store by ID.\n * @protected\n * @param {string} id - The ID of the record to delete.\n * @returns {Promise<void>} A promise that resolves when the record is deleted.\n */\n protected async deleteRecord(id: string): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const open = this.openDb();\n\n open.onsuccess = () => {\n const db = open.result;\n const tx = db.transaction(this.storeKey, \"readwrite\");\n const store = tx.objectStore(this.storeKey);\n\n const request = store.delete(id);\n\n request.onsuccess = () => resolve();\n request.onerror = () =>\n reject(\n new StorageError(\n \"Failed to delete record.\",\n \"ERROR_STORAGE_FAILED\",\n ),\n );\n };\n\n open.onerror = () =>\n reject(\n new StorageError(\n \"Failed to open the database.\",\n \"ERROR_STORAGE_FAILED_TO_OPEN\",\n ),\n );\n });\n }\n}\n","// Copyright (C) LoginID\n\nimport {\n exportPublicKeyJwk,\n generateES256KeyPair,\n randomUUID,\n} from \"../utils/crypto\";\nimport { IndexedDBWrapper } from \"./indexdb\";\nimport { signJwtWithJwk } from \"../helpers\";\nimport { CheckoutIDRecord } from \"../types\";\nimport { StorageError } from \"../errors\";\n\nconst dbVersion = 1;\nconst checkoutIdDbName = \"lid_c_cid\";\nconst checkoutIdStorageKey = \"lid-cid-k\";\nconst walletTrustIdDbName = \"lid_c_wtid\";\nconst walletTrustIdStorageKey = \"lid-wtid-k\";\n\n/**\n * BaseCheckoutStore provides a common implementation for managing checkout ID records\n * using IndexedDB. It handles generation, storage, retrieval, and signing of unique IDs.\n */\nexport class BaseCheckoutStore extends IndexedDBWrapper {\n /**\n * Constructs a new BaseCheckoutStore instance.\n *\n * @param {string} dbName - The name of the IndexedDB database.\n * @param {string} trustStorageKey - The key used for namespacing storage.\n */\n constructor(dbName: string, trustStorageKey: string) {\n super(dbName, dbVersion, trustStorageKey);\n }\n\n /**\n * Generates a new random checkout ID, signs it using a newly created key pair,\n * and stores the key pair in IndexedDB.\n *\n * @returns {Promise<string>} A signed checkout ID (JWS).\n */\n public async setCheckoutId(): Promise<string> {\n const keyPair = await generateES256KeyPair();\n const publicKey = await exportPublicKeyJwk(keyPair);\n const token = { id: randomUUID() };\n const checkoutId = await signJwtWithJwk(\n token,\n publicKey,\n keyPair.privateKey,\n );\n\n await this.putRecord({\n id: token.id,\n keyPair,\n });\n\n return checkoutId;\n }\n\n /**\n * Retrieves the first checkout ID from storage, if available, and returns a signed version of it.\n *\n * @returns {Promise<string | null>} The signed checkout ID or null if no ID is found.\n */\n public async getCheckoutId(): Promise<string | null> {\n try {\n const record = await this.getFirstRecord<CheckoutIDRecord>();\n const publicKey = await exportPublicKeyJwk(record.keyPair);\n const token = { id: record.id };\n const checkoutId = await signJwtWithJwk(\n token,\n publicKey,\n record.keyPair.privateKey,\n );\n return checkoutId;\n } catch (error) {\n if (\n error instanceof StorageError &&\n error.code === \"ERROR_STORAGE_NOT_FOUND\"\n ) {\n return null;\n }\n throw error;\n }\n }\n\n /**\n * Signs a new token using the stored key pair and checkout ID.\n *\n * @returns {Promise<string>} A signed token (JWS) representing the checkout ID.\n * @throws {StorageError} If no checkout ID is found in storage.\n */\n public async signWithCheckoutId(): Promise<string> {\n const record = await this.getFirstRecord<CheckoutIDRecord>();\n const publicKey = await exportPublicKeyJwk(record.keyPair);\n const token = { id: record.id };\n const trustId = await signJwtWithJwk(\n token,\n publicKey,\n record.keyPair.privateKey,\n );\n return trustId;\n }\n\n /**\n * Checks for the existence of a checkout ID and signs with it if available;\n * otherwise, generates a new one and returns the signed value.\n *\n * @returns {Promise<string>} The signed checkout ID (JWS).\n */\n public async setOrSignWithCheckoutId(): Promise<string> {\n try {\n return await this.signWithCheckoutId();\n } catch (error) {\n if (\n error instanceof StorageError &&\n error.code === \"ERROR_STORAGE_NOT_FOUND\"\n ) {\n return await this.setCheckoutId();\n }\n console.log(\"IndexDB error: \" + error);\n return \"\";\n }\n }\n}\n\n/**\n * CheckoutIdStore is a concrete implementation of BaseCheckoutStore\n * specifically for managing checkout ID records.\n */\nexport class CheckoutIdStore extends BaseCheckoutStore {\n /**\n * Constructs a new CheckoutIdStore instance using predefined DB and key values.\n */\n constructor() {\n super(checkoutIdDbName, checkoutIdStorageKey);\n }\n}\n\n/**\n * WalletTrustIdStore is a concrete implementation of BaseCheckoutStore\n * specifically for managing wallet trust ID records.\n */\nexport class WalletTrustIdStore extends BaseCheckoutStore {\n /**\n * Constructs a new WalletTrustIdStore instance using predefined DB and key values.\n */\n constructor() {\n super(walletTrustIdDbName, walletTrustIdStorageKey);\n }\n}\n","// Copyright (C) LoginID\n\nimport { exportPublicKeyJwk, generateES256KeyPair } from \"../utils/crypto\";\nimport { signJwtWithJwk, toTrustIDPayload } from \"../helpers\";\nimport { IndexedDBWrapper } from \"./indexdb\";\nimport { StorageError } from \"../errors\";\nimport { TrustIDRecord } from \"../types\";\n\nconst dbVersion = 1;\nconst appIdIndex = \"app_id_idx\";\nconst nameIndex = \"username_idx\";\nconst dbName = \"loginid-trust-store\";\nconst trustStorageKey = `LoginID_trust-id`;\nconst appIdUsernameCompositeIndex = \"app_id_username_idx\";\n\n/**\n * TrustStore extends IndexedDBWrapper to manage trust ID records.\n */\nexport class TrustStore extends IndexedDBWrapper {\n /** App ID associated with this store */\n private readonly appId: string;\n\n /**\n * Creates an instance of TrustStore.\n * @param {string} appId - The app ID.\n */\n constructor(appId: string) {\n super(dbName, dbVersion, trustStorageKey, [\n { name: nameIndex, keyPath: [\"username\"] },\n { name: appIdIndex, keyPath: [\"appId\"] },\n { name: appIdUsernameCompositeIndex, keyPath: [\"appId\", \"username\"] },\n ]);\n this.appId = appId;\n }\n\n /**\n * Generates a Trust ID for a user and stores it.\n * @param {string} username - The username associated with the trust ID.\n * @returns {Promise<string>} The signed trust ID.\n */\n public async setTrustId(username: string): Promise<string> {\n const keyPair = await generateES256KeyPair();\n const publicKey = await exportPublicKeyJwk(keyPair);\n const token = toTrustIDPayload(this.appId);\n const trustId = await signJwtWithJwk(token, publicKey, keyPair.privateKey);\n\n await this.putRecord({\n id: token.id,\n appId: this.appId,\n username,\n keyPair,\n });\n\n return trustId;\n }\n\n /**\n * Creates a JWS using the stored Trust ID.\n * @param {string} username - The username to retrieve the Trust ID for.\n * @returns {Promise<string>} The signed trust ID.\n */\n public async signWithTrustId(username: string): Promise<string> {\n const record = await this.getByIndex<TrustIDRecord>(\n appIdUsernameCompositeIndex,\n [this.appId, username],\n );\n const publicKey = await exportPublicKeyJwk(record.keyPair);\n const token = toTrustIDPayload(this.appId);\n const trustId = await signJwtWithJwk(\n token,\n publicKey,\n record.keyPair.privateKey,\n );\n return trustId;\n }\n\n /**\n * Checks if a Trust ID exists for the user. If it does, signs with it; otherwise, generates and stores a new Trust ID.\n * @param {string} username - The username associated with the trust ID.\n * @returns {Promise<string>} The signed trust ID.\n */\n public async setOrSignWithTrustId(username: string): Promise<string> {\n try {\n if (!username) {\n return \"\";\n }\n return await this.signWithTrustId(username);\n } catch (error) {\n if (\n error instanceof StorageError &&\n error.code === \"ERROR_STORAGE_NOT_FOUND\"\n ) {\n return await this.setTrustId(username);\n }\n console.log(\"IndexDB error: \" + error);\n return \"\";\n }\n }\n\n /**\n * Retrieves all Trust ID records associated with the given appId.\n * @returns {Promise<TrustIDRecord[]>} A promise that resolves to an array of trust IDs.\n */\n public async getAllTrustIds(): Promise<TrustIDRecord[]> {\n try {\n const records = await this.getAllByIndex<TrustIDRecord>(appIdIndex, [\n this.appId,\n ]);\n return records;\n } catch (error) {\n console.error(\"Error retrieving Trust IDs:\", error);\n return [];\n }\n }\n\n /**\n * Retrieves a Trust ID record by username.\n * @param {string} username - The username to search for.\n * @returns {Promise<TrustIDRecord | null>} A promise that resolves to the TrustIDRecord or null if not found.\n */\n public async findByUsername(username: string): Promise<TrustIDRecord | null> {\n try {\n return await this.getByIndex<TrustIDRecord>(appIdUsernameCompositeIndex, [\n this.appId,\n username,\n ]);\n } catch (error) {\n console.error(\"Error retrieving Trust ID Record:\", error);\n return null;\n }\n }\n\n /**\n * Deletes all Trust ID records except the one specified.\n * @param {string} username - The username whose Trust IDs should be deleted, except for the specified one.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\n public async deleteAllExcept(username: string): Promise<void> {\n try {\n const records = await this.getAllTrustIds();\n const deletePromises = records\n .filter((record) => record.username !== username)\n .map((record) => this.deleteRecord(record.id));\n\n await Promise.all(deletePromises);\n } catch (error) {\n console.error(\"Error deleting Trust IDs:\", error);\n }\n }\n}\n","// Copyright (C) LoginID\n\nimport { LocalStorageWrapper } from \"./local-storage\";\nimport { MfaInfo } from \"../controllers\";\n\nconst mfaStorageKey = (appId: string) => `LoginID_${appId}_mfa-session`;\n\n/**\n * A storage utility class for managing Multi-Factor Authentication (MFA) session data using localStorage.\n */\nexport class MfaStore extends LocalStorageWrapper {\n public static persistInfo(appId: string, info?: MfaInfo): void {\n this.setItem(mfaStorageKey(appId), info);\n }\n\n public static getInfo(appId: string): MfaInfo | null {\n return this.getItem(mfaStorageKey(appId));\n }\n\n public static updateSession(appId: string, session: string): void {\n let info = MfaStore.getInfo(appId);\n\n if (!info) {\n info = { session: session };\n } else {\n info.session = session;\n }\n\n MfaStore.persistInfo(appId, info);\n }\n}\n","// Copyright (C) LoginID\n\nimport { LoginIDConfigValidator } from \"../validators\";\nimport { SessionManager } from \"../session\";\nimport { LoginIDConfig } from \"./types\";\nimport { LoginIDService } from \"../api\";\n\n/**\n * Provides a base class for integrating with the LoginID API services.\n * This class initializes the common configuration and service needed for derived classes to interact with LoginID services.\n */\nexport class LoginIDBase {\n /**\n * Holds the configuration settings for the LoginID integration, including API base URL.\n */\n protected readonly config: LoginIDConfigValidator;\n\n /**\n * Instance of LoginIDService, providing access to the LoginID API methods.\n */\n protected readonly service: LoginIDService;\n\n /**\n * Instance of SessionManager, providing access to the session management methods.\n */\n public readonly session: SessionManager;\n\n /**\n * Constructs a new instance of the LoginIDBase class, initializing the service with the provided configuration.\n * @param {LoginIDConfig} config Configuration object for LoginID API, including the base URL.\n */\n constructor(config: LoginIDConfig) {\n this.config = new LoginIDConfigValidator(config);\n this.service = new LoginIDService({ BASE: config.baseUrl });\n this.session = new SessionManager(config);\n }\n}\n","// Copyright (C) LoginID\n\nimport { LoginIDConfig, VerifyConfigResult } from \"./types\";\nimport { ApiError, AuthInitRequestBody } from \"../api\";\nimport { defaultDeviceInfo } from \"../utils/browser\";\nimport { LoginIDBase } from \"./base\";\nimport { MfaStore } from \"../store\";\n\nexport class Utils extends LoginIDBase {\n /**\n * Initializes a new Utils instance with the provided configuration.\n *\n * @param {LoginIDConfig} config Configuration object for LoginID.\n */\n constructor(config: LoginIDConfig) {\n super(config);\n }\n\n /**\n * Validates the application's configuration settings and provides a suggested correction if any issues are detected.\n *\n * @returns {Promise<VerifyConfigResult>} The result of the verification process.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * const lid = new LoginIDWebSDK(config);\n *\n * async function checkConfig() {\n * const result = await lid.verifyConfigSettings();\n *\n * if (result.isValid) {\n * console.log('Configuration is valid');\n * } else {\n * console.error(`Error: ${result.message} (Code: ${result.code})`);\n * console.info(`Solution: ${result.solution}`);\n * }\n * }\n *\n * checkConfig();\n *\n * // Attach the click handler to a button\n * const checkConfigButton = document.getElementById(\"button\");\n * checkConfigButton.addEventListener(\"click\", checkConfig);\n * ```\n */\n public async verifyConfigSettings(): Promise<VerifyConfigResult> {\n const result: VerifyConfigResult = {\n isValid: true,\n };\n\n try {\n this.config.getAppId();\n } catch {\n result.isValid = false;\n result.solution = \"Please verify that your base URL is correct.\";\n result.code = \"invalid_app_id\";\n result.message = \"Invalid app ID\";\n return result;\n }\n\n try {\n const requestBody: AuthInitRequestBody = {\n app: {\n id: this.config.getAppId(),\n },\n deviceInfo: defaultDeviceInfo(),\n user: {\n username: \"\",\n usernameType: \"other\",\n },\n };\n\n await this.service.auth.authAuthInit({ requestBody });\n } catch (error) {\n result.isValid = false;\n result.solution =\n \"Verify that your application exists and the base URL is correct.\";\n result.code = \"unknown_error\";\n result.message = \"Unknown error.\";\n\n if (error instanceof ApiError) {\n result.code = error.body.msgCode || \"unknown_error\";\n result.message =\n error.body.msg || error.body.message || \"Unknown error.\";\n }\n\n return result;\n }\n\n return result;\n }\n\n /**\n * Check whether the user of the current browser session is authenticated and returns user info.\n * This info is retrieved locally and no requests to backend are made.\n *\n * @returns {SessionInfo | null} The currently authenticated user's information, including username and id.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n * const username = \"billy@loginid.io\";\n *\n * try {\n * // Retrieve session information\n * await lid.authenticateWithPasskey(username);\n * const sessionInfo = lid.getSessionInfo();\n * console.log(\"Session Information:\", sessionInfo);\n * } catch (error) {\n * console.error(\"Error retrieving session information:\", error);\n * }\n * ```\n */\n public getSessionInfo() {\n return this.session.getSessionInfo();\n }\n\n /**\n * Clears current user session. This method is executed locally and it just deletes authorization token from local Cookies.\n *\n * @returns {boolean}\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * try {\n * // Retrieve user information\n * await lid.authenticateWithPasskey(username);\n * lid.logout();\n * const info = lid.getSessionInfo();\n * // false\n * console.log(\"Is user signed in?\", info !== null);\n * } catch (error) {\n * console.error(\"Error:\", error);\n * }\n * ```\n */\n public logout() {\n const appId = this.config.getAppId();\n\n this.session.logout();\n\n MfaStore.persistInfo(appId, { next: [] });\n }\n}\n","// Copyright (C) LoginID\n\nimport {\n LoginIDMfaConfig,\n MfaBeginOptions,\n MfaFactorName,\n MfaPerformActionOptions,\n MfaSessionResult,\n} from \"./types\";\nimport {\n DeviceStore,\n MfaStore,\n TrustStore,\n WalletTrustIdStore,\n} from \"../store\";\nimport { mfaOptions, toMfaInfo, toMfaSessionDetails } from \"../defaults\";\nimport { ApiError, Mfa, MfaBeginRequestBody, MfaNext } from \"../api\";\nimport { LoginIDParamValidator } from \"../validators\";\nimport { defaultDeviceInfo } from \"../utils/browser\";\nimport { WebAuthnHelper } from \"../webauthn\";\nimport { LoginIDError } from \"../errors\";\nimport { LoginIDBase } from \"./base\";\n\nexport class MFA extends LoginIDBase {\n /**\n * Initializes a new MFA instance with the provided configuration.\n *\n * @param {LoginIDMfaConfig} config Configuration object for LoginID services.\n *\n */\n constructor(config: LoginIDMfaConfig) {\n super(config);\n }\n\n /**\n * Initiates the pre-authentication process for Multi-Factor Authentication (MFA).\n * This method begins an MFA session and stores session details in local storage.\n *\n * To proceed with the MFA flow, use the `performAction` method with the required\n * payload if necessary. To check the current MFA session status, use `getMfaSessionDetails`.\n *\n * @param {string} username - The username of the user initiating MFA.\n * @param {MfaBeginOptions} [options={}] - Optional parameters for initiating MFA.\n * @returns {Promise<MfaSessionResult>} - A promise resolving to the MFA session result.\n */\n async beginFlow(\n username: string,\n options: MfaBeginOptions = {},\n ): Promise<MfaSessionResult> {\n const appId = this.config.getAppId();\n const deviceId = DeviceStore.getDeviceId(appId);\n const deviceInfo = defaultDeviceInfo(deviceId);\n const opts = mfaOptions(username, options);\n\n let walletTrustId = \"\";\n if (options.txPayload) {\n const store = new WalletTrustIdStore();\n walletTrustId = await store.setOrSignWithCheckoutId();\n }\n\n let trustId = \"\";\n if (!options.checkoutId && !walletTrustId) {\n const store = new TrustStore(appId);\n trustId = await store.setOrSignWithTrustId(username);\n }\n\n const mfaBeginRequestBody: MfaBeginRequestBody = {\n deviceInfo: deviceInfo,\n user: {\n username: username,\n usernameType: opts.usernameType,\n displayName: opts.displayName,\n },\n trustItems: {\n ...(trustId && { auth: trustId }),\n ...(walletTrustId && { wallet: walletTrustId }),\n ...(options.checkoutId && { merchant: options.checkoutId }),\n },\n ...(options.txPayload && { payload: options.txPayload }),\n };\n\n const mfaNextResult = await this.service.mfa.mfaMfaBegin({\n requestBody: mfaBeginRequestBody,\n });\n\n const mfaInfo = toMfaInfo(mfaNextResult, username);\n\n MfaStore.persistInfo(appId, mfaInfo);\n\n this.session.logout();\n\n return toMfaSessionDetails(mfaInfo);\n }\n\n /**\n * Performs a Multi-Factor Authentication (MFA) action using the specified factor.\n *\n * This method supports various MFA factors, including passkeys, OTP (email/SMS), and external authentication.\n * It validates the provided options, processes the authentication step, and invokes the corresponding MFA API.\n * The MFA session deatils is updated upon a successful factor completion.\n *\n * - **OTP Request (email/SMS):** Initiates an OTP request by sending an OTP to the user's contact information. If `options.payload` contains a contact, it will be used; otherwise, the primary contact on record is used.\n * - **OTP Verify (email/SMS):** Verifies the OTP code provided in `options.payload` by validating it against the expected value.\n * - **External authentication:** Provide the authorization code in `options.payload`.\n * - **Passkeys:** Uses WebAuthn for authentication or registration.\n *\n * @param {MfaFactorName} factorName - The MFA factor being performed (e.g., `\"passkey\"`, `\"otp:email\"`, `\"otp:sms\"`, `\"external\"`).\n * @param {MfaPerformActionOptions} [options={}] - The options containing session and payload data for the MFA factor.\n * @returns {Promise<MfaSessionResult>} - A promise resolving to the updated MFA session result.\n */\n async performAction(\n factorName: MfaFactorName,\n options: MfaPerformActionOptions = {},\n ): Promise<MfaSessionResult> {\n const appId = this.config.getAppId();\n const info = MfaStore.getInfo(appId);\n const { payload, session } = LoginIDParamValidator.mfaOptionValidator(\n factorName,\n info,\n options,\n );\n\n switch (factorName) {\n case \"passkey:reg\":\n case \"passkey:auth\":\n case \"passkey:tx\": {\n const requestOptions =\n LoginIDParamValidator.validatePasskeyPayload(payload);\n\n if (\"rpId\" in requestOptions) {\n const authCompleteRequestBody =\n await WebAuthnHelper.getNavigatorCredential(\n {\n action: \"proceed\",\n assertionOptions: requestOptions,\n crossAuthMethods: [],\n fallbackMethods: [],\n session: session,\n },\n { ...(options.autoFill && { autoFill: options.autoFill }) },\n );\n\n if (factorName === \"passkey:tx\") {\n return await this.invokeMfaApi(appId, info?.username, async () => {\n return await this.service.mfa.mfaMfaPasskeyTx({\n authorization: session,\n requestBody: {\n assertionResult: authCompleteRequestBody.assertionResult,\n },\n });\n });\n }\n\n return await this.invokeMfaApi(appId, info?.username, async () => {\n return await this.service.mfa.mfaMfaPasskeyAuth({\n authorization: session,\n requestBody: {\n assertionResult: authCompleteRequestBody.assertionResult,\n },\n });\n });\n }\n\n if (\"rp\" in requestOptions) {\n const regCompleteRequestBody =\n await WebAuthnHelper.createNavigatorCredential({\n action: \"proceed\",\n registrationRequestOptions: requestOptions,\n session: session,\n });\n\n return await this.invokeMfaApi(appId, info?.username, async () => {\n return await this.service.mfa.mfaMfaPasskeyReg({\n authorization: session,\n requestBody: {\n creationResult: regCompleteRequestBody.creationResult,\n },\n });\n });\n }\n\n break;\n }\n\n case \"otp:email\":\n case \"otp:sms\": {\n const { session: newSession } = await this.service.mfa.mfaMfaOtpRequest(\n {\n authorization: session,\n requestBody: {\n method: factorName === \"otp:email\" ? \"email\" : \"sms\",\n option: payload,\n },\n },\n );\n\n MfaStore.updateSession(appId, newSession);\n\n return toMfaSessionDetails(MfaStore.getInfo(appId));\n }\n\n case \"otp:verify\": {\n return await this.invokeMfaApi(appId, info?.username, async () => {\n return await this.service.mfa.mfaMfaOtpVerify({\n authorization: session,\n requestBody: {\n otp: payload,\n },\n });\n });\n }\n\n case \"external\": {\n return await this.invokeMfaApi(appId, info?.username, async () => {\n return await this.service.mfa.mfaMfaThirdPartyAuthVerify({\n authorization: session,\n requestBody: {\n token: payload,\n },\n });\n });\n }\n }\n\n throw new LoginIDError(\n `MFA factor ${factorName} is not supported in the current MFA flow.`,\n );\n }\n\n /**\n * Retrieves the current Multi-Factor Authentication (MFA) session details.\n *\n * This method fetches the latest MFA session information from local storage and\n * includes any available authentication tokens. It provides the current status\n * of the MFA process, including remaining factors and completion state.\n *\n * @returns {MfaSessionResult} - The current MFA session details, including session status and tokens.\n */\n getMfaSessionDetails(): MfaSessionResult {\n const appId = this.config.getAppId();\n const info = MfaStore.getInfo(appId);\n const tokenSet = this.session.getTokenSet();\n return toMfaSessionDetails(info, tokenSet);\n }\n\n /**\n * Handles the execution of an MFA API request and updates the MFA session state.\n *\n * This internal method executes the provided MFA request function, updates local storage,\n * and sets authentication tokens. If the request results in an MFA challenge (401 error),\n * it processes the response and updates the session accordingly.\n *\n * @param {string} appId - The application ID associated with the MFA session.\n * @param {string} [username=\"\"] - The username, if available.\n * @param {() => Promise<Mfa>} fn - A function that performs the MFA API request.\n * @returns {Promise<MfaSessionResult>} - The updated MFA session result.\n */\n private async invokeMfaApi(\n appId: string,\n username: string = \"\",\n fn: () => Promise<Mfa>,\n ): Promise<MfaSessionResult> {\n try {\n const mfaSuccessResult = await fn();\n const mfaInfo = MfaStore.getInfo(appId);\n\n MfaStore.persistInfo(appId, {\n ...(username && { username }),\n flow: mfaInfo?.flow,\n next: [],\n });\n\n this.session.setTokenSet(mfaSuccessResult);\n DeviceStore.persistDeviceId(appId, mfaSuccessResult.deviceId);\n\n const newMfaInfo = MfaStore.getInfo(appId);\n\n return toMfaSessionDetails(newMfaInfo, mfaSuccessResult);\n } catch (error) {\n if (error instanceof ApiError) {\n if (error.status === 401 && error.body.session) {\n const mfaNextResult = error.body as MfaNext;\n const mfaInfo = toMfaInfo(mfaNextResult, username);\n\n MfaStore.persistInfo(appId, mfaInfo);\n\n return toMfaSessionDetails(mfaInfo);\n }\n }\n\n throw error;\n }\n }\n}\n","// Copyright (C) LoginID\n\nimport { LoginIDBase, MFA, Utils } from \"../controllers\";\nimport type { LoginIDConfig } from \"../controllers\";\nimport { applyMixins } from \"../helpers\";\n\ninterface LoginIDMfa extends MFA, Utils {}\n\nclass LoginIDMfa extends LoginIDBase {\n constructor(config: LoginIDConfig) {\n super(config);\n }\n}\n\napplyMixins(LoginIDMfa, [LoginIDBase, MFA, Utils]);\n\nexport default LoginIDMfa;\n","// Copyright (C) LoginID\n\nimport {\n DeletePasskeyOptions,\n ListPasskeysOptions,\n RenamePasskeyOptions,\n} from \"../types\";\nimport type {\n PasskeyCollection,\n PasskeyRenameRequestBody,\n} from \"@loginid/core/api\";\nimport { LoginIDBase, LoginIDConfig } from \"@loginid/core/controllers\";\n\n/**\n * Extends LoginIDBase to manage Passkeys, including listing, renaming, and deleting passkeys.\n */\nclass PasskeyManager extends LoginIDBase {\n /**\n * Initializes a new instance of PasskeyManager with the provided configuration.\n *\n * @param {LoginIDConfig} config Configuration object for LoginID.\n */\n constructor(config: LoginIDConfig) {\n super(config);\n }\n\n /**\n * This method returns list of passkeys associated with the current user. The user must be fully authorized for this call to succeed.\n *\n * @param {ListPasskeysOptions} options Additional options for listing passkeys.\n * @returns {Promise<PasskeyCollection>} A collection of passkeys.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * // Button click handler for signing in\n * async function handleSigninButtonClick() {\n * const username = \"billy@loginid.io\";\n *\n * try {\n * // Sign in with a passkey\n * await lid.authenticateWithPasskey(username);\n *\n * // List all user credentials\n * const passkeys = await lid.listPasskeys();\n * // Handle the sign-in result\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during obtaining passkeys:\", error);\n * }\n * }\n *\n * // Attach the click handler to a button\n * const signinButton = document.getElementById(\"signinButton\");\n * signinButton.addEventListener(\"click\", handleSigninButtonClick);\n * ```\n */\n async listPasskeys(\n options: ListPasskeysOptions = {},\n ): Promise<PasskeyCollection> {\n const token = this.session.getToken(options);\n\n return await this.service.passkeys.passkeysPasskeysList({\n authorization: token,\n });\n }\n\n /**\n * Renames a specified passkey by ID. The user must be fully authorized for this call to succeed.\n *\n * @param {string} id The ID of the passkey to rename.\n * @param {string} name The new name for the passkey.\n * @param {RenamePasskeyOptions} options Additional options for renaming the passkey.\n * @returns {Promise<void>} A promise that resolves when the operation completes successfully.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * const passkeyId = \"abc123\";\n * const newCredName = \"New Passkey Credential Name\";\n *\n * // Rename the passkey user credential\n * try {\n * // Signin with passkey\n * await lid.authenticateWithPasskey(username);\n *\n * // Find a way to retrieve passkey ID\n * await lid.renamePasskey(passkeyId, newCredName);\n * // Passkey credential successfully renamed\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during passkey credential renaming:\", error);\n * }\n * ```\n */\n async renamePasskey(\n id: string,\n name: string,\n options: RenamePasskeyOptions = {},\n ): Promise<void> {\n const token = this.session.getToken(options);\n\n const passkeyRenameRequestBody: PasskeyRenameRequestBody = {\n name: name,\n };\n\n await this.service.passkeys.passkeysPasskeyRename({\n authorization: token,\n id: id,\n requestBody: passkeyRenameRequestBody,\n });\n }\n\n /**\n * Delete a specified passkey by ID from LoginID. The user must be fully authorized for this call to succeed.\n *\n * @param {string} id The ID of the passkey to delete.\n * @param {DeletePasskeyOptions} options Additional options for deleting the passkey.\n * @returns {Promise<void>} A promise that resolves when the operation completes successfully.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * const passkeyId = \"abc123\";\n *\n * // Delete the passkey user credential\n * try {\n * // Signin with passkey\n * const signinResult = await lid.authenticateWithPasskey(username);\n *\n * // Find a way to retrieve passkey ID\n * await lid.deletePasskey(passkeyId);\n * // Passkey credential successfully deleted\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error deleting passkey:\", error);\n * }\n * ```\n */\n async deletePasskey(\n id: string,\n options: DeletePasskeyOptions = {},\n ): Promise<void> {\n const token = this.session.getToken(options);\n\n await this.service.passkeys.passkeysPasskeyDelete({\n authorization: token,\n id: id,\n });\n }\n}\n\nexport default PasskeyManager;\n","// Copyright (C) LoginID\n\nimport {\n AllOptions,\n AuthResult,\n Complete,\n ConfirmTransactionOptions,\n} from \"../types\";\nimport { randomUUID } from \"@loginid/core/utils/crypto\";\nimport { JWT } from \"@loginid/core/api\";\n\n/**\n * Merges provided options with default values for passkey options.\n *\n * @param {string} username Username for which the passkey options are being created.\n * @param {string} authzToken Authorization token for the passkey options.\n * @param {PasskeyOptions} options Options to merge with default values.\n * @returns {Complete<PasskeyOptions>} The complete set of passkey options with defaults applied.\n */\nexport const passkeyOptions = (\n username: string,\n authzToken: string,\n options: AllOptions,\n): Complete<AllOptions> => {\n return {\n ...options,\n authzToken: authzToken || options.authzToken || \"\",\n usernameType: options.usernameType || \"other\",\n displayName: options.displayName || username,\n callbacks: options.callbacks || {},\n };\n};\n\n/**\n * Merges provided options with default values for transaction confirmation options.\n *\n * @param {string} username Username for which the transaction confirmation options are being created.\n * @param {ConfirmTransactionOptions} options Options to merge with default values.\n * @returns {Complete<ConfirmTransactionOptions>} The complete set of transaction confirmation options with defaults applied.\n */\nexport const confirmTransactionOptions = (\n username: string,\n options: ConfirmTransactionOptions,\n): Complete<ConfirmTransactionOptions> => {\n return {\n ...passkeyOptions(username, \"\", options),\n txType: options.txType || \"raw\",\n nonce: options.nonce || randomUUID(),\n };\n};\n\n/**\n * Constructs an `AuthResult` object using the provided JWT access token and authentication status.\n *\n * @param {JWT} authResponse - The authentication response containing user details and the JWT access token.\n * @param {boolean} [isAuthenticated=true] - Indicates whether the user is authenticated. Defaults to **`true`**.\n * @param {boolean} [isFallback=false] - Indicates whether the authentication attempt is a fallback method. Defaults to **`false`**.\n * @returns {AuthResult} - The authentication result, including the user ID, token, authentication status, and fallback indication.\n */\nexport const toAuthResult = (\n authResponse: JWT,\n isAuthenticated = true,\n isFallback = false,\n): AuthResult => {\n return {\n userId: authResponse.userId,\n token: authResponse.jwtAccess,\n passkeyId: authResponse.passkeyId,\n isAuthenticated: isAuthenticated,\n isFallback: isFallback,\n };\n};\n","// Copyright (C) LoginID\n\nimport { AuthInit } from \"@loginid/core/api\";\nimport { FallbackOptions } from \"../types\";\n\n/**\n * Combines the fallback and cross-authentication methods from the authentication initialization response\n * into a single array representing all available alternative authentication methods.\n *\n * @param {AuthInit} authInitRes The authentication initialization response containing available methods.\n * @returns {FallbackOptions} An array representing both fallback and cross-authentication methods.\n */\nexport const mergeFallbackOptions = (\n authInitRes: AuthInit,\n): FallbackOptions => {\n return [...authInitRes.crossAuthMethods, ...authInitRes.fallbackMethods];\n};\n","// Copyright (C) LoginID\n\nimport {\n AuthResult,\n Message,\n RequestAndSendOtpOptions,\n ValidateOtpOptions,\n} from \"../types\";\nimport {\n AuthCodeRequestSMSRequestBody,\n AuthCodeVerifyRequestBody,\n} from \"@loginid/core/api\";\nimport { LoginIDBase, LoginIDConfig } from \"@loginid/core/controllers\";\nimport { AbortControllerManager } from \"@loginid/core/webauthn\";\nimport { passkeyOptions, toAuthResult } from \"../lib/defaults\";\n\n/**\n * Extends LoginIDBase to support OTP methods.\n */\nclass OTP extends LoginIDBase {\n /**\n * Initializes a new instance of OTP with the provided configuration.\n *\n * @param {LoginIDConfig} config Configuration object for LoginID.\n */\n constructor(config: LoginIDConfig) {\n super(config);\n }\n\n /**\n * This method verifies the OTP and returns an authorization token, which can be used with the `passkeyCreate()`\n * method to create a new passkey. The authorization token has a short validity period and should be used immediately.\n *\n * @param {string} username Username to validate with.\n * @param {string} otp OTP to validate.\n * @param {ValidateOtpOptions} options Additional authentication options.\n * @returns {Promise<AuthResult>} Result of the authentication operation.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * // Button click handler to generate a code with passkey\n * async function handleRequestOTPButtonClick() {\n * const username = \"billy@loginid.io\";\n *\n * try {\n * // Request OTP with passkey\n * const result = await lid.requestOtp(username);\n * // Extract the OTP from the response\n * const otp = result.code;\n *\n * // Authenticate with the OTP\n * // You can authenticate on another device with this OTP\n * const authenticateResult = await lid.validateOtp(username, otp);\n * // Handle the authentication result\n * console.log(\"Authentication Result:\", authenticateResult);\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during authentication:\", error);\n * }\n * }\n *\n * // Attach the click handler to a button\n * const requestOtpButton = document.getElementById(\"requestOtpButton\");\n * requestOtpButton.addEventListener(\"click\", handleRequestOTPButtonClick);\n * ```\n */\n async validateOtp(\n username: string,\n otp: string,\n options: ValidateOtpOptions = {},\n ): Promise<AuthResult> {\n const opts = passkeyOptions(username, \"\", options);\n const request: AuthCodeVerifyRequestBody = {\n authCode: otp,\n user: {\n username: username,\n usernameType: opts.usernameType,\n },\n };\n\n const response = await this.service.auth.authAuthCodeVerify({\n requestBody: request,\n });\n\n const result = toAuthResult(response);\n\n // Renew abort controller since authentication is complete\n AbortControllerManager.renewWebAuthnAbortController();\n\n this.session.setJwtCookie(result.token);\n\n return result;\n }\n\n /**\n * This method requests an OTP from the backend to be sent via the selected method. The method of delivery should be based on\n * the user's choice from the list of available options. This can be found in the result of `authenticateWithPasskey`\n * method as `fallbackOptions`.\n *\n * @param {string} username Username to request and send the OTP to.\n * @param {Message} method Method to send the code, either 'email' or 'sms'. Default is 'email'.\n * @param {RequestAndSendOtpOptions} options Additional options for sending the OTP.\n * @returns {Promise<void>} A promise that resolves when the operation completes successfully.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * const username = \"billy@loginid.io\";\n *\n * async function sendUserOTPHandler() {\n * try {\n * // Send OTP to a user via email\n * await lid.requestAndSendOtp(username, \"email\");\n * console.log(\"OTP sent successfully.\");\n * } catch (error) {\n * console.error(\"Error sending code:\", error);\n * }\n * }\n *\n * const sendOtpButton = document.getElementById(\"button\");\n * sendOtpButton.addEventListener(\"click\", sendUserOTPHandler);\n * ```\n */\n async requestAndSendOtp(\n username: string,\n method: Message = \"email\",\n options: RequestAndSendOtpOptions = {},\n ): Promise<void> {\n const opts = passkeyOptions(username, \"\", options);\n const request: AuthCodeRequestSMSRequestBody = {\n user: {\n username: username,\n usernameType: opts.usernameType,\n },\n };\n\n switch (method) {\n case \"email\":\n await this.service.auth.authAuthCodeRequestEmail({\n requestBody: request,\n });\n break;\n\n case \"sms\":\n await this.service.auth.authAuthCodeRequestSms({\n requestBody: request,\n });\n break;\n\n default:\n throw new Error(\"Invalid message method\");\n }\n }\n}\n\nexport default OTP;\n","// Copyright (C) LoginID\n\nimport type {\n AuthenticateWithPasskeyAutofillOptions,\n AuthenticateWithPasskeysOptions,\n AuthResult,\n ConfirmTransactionOptions,\n CreatePasskeyOptions,\n Otp,\n RequestOtpOptions,\n} from \"../types\";\nimport {\n AuthInit,\n AuthInitRequestBody,\n JWT,\n RegInitRequestBody,\n TxComplete,\n TxCompleteRequestBody,\n TxInitRequestBody,\n} from \"@loginid/core/api\";\nimport {\n confirmTransactionOptions,\n passkeyOptions,\n toAuthResult,\n} from \"../lib/defaults\";\nimport { NO_LOGIN_OPTIONS_ERROR, WebAuthnHelper } from \"@loginid/core/webauthn\";\nimport { defaultDeviceInfo } from \"@loginid/core/utils/browser\";\nimport { DeviceStore, TrustStore } from \"@loginid/core/store\";\nimport { LoginIDConfig } from \"@loginid/core/controllers\";\nimport { parseJwt } from \"@loginid/core/utils/crypto\";\nimport { mergeFallbackOptions } from \"../lib/utils\";\nimport OTP from \"./otp\";\n\n/**\n * Extends LoginIDBase to support creation and authentication of passkeys.\n */\nclass Passkeys extends OTP {\n /**\n * Initializes a new Passkeys instance with the provided configuration.\n *\n * @param {LoginIDConfig} config Configuration object for LoginID.\n *\n */\n constructor(config: LoginIDConfig) {\n super(config);\n }\n\n /**\n * This method helps to create a passkey. The only required parameter is the username, but additional attributes can be provided in the options parameter.\n * Note: While the authorization token is optional, it must always be used in a production environment. You can skip it during development by adjusting\n * the app configuration in the LoginID dashboard.\n *\n * A short-lived authorization token is returned, allowing access to protected resources for the given user such as listing, renaming or deleting passkeys.\n *\n * @param {string} username Username to register.\n * @param {string} authzToken Authorization token for passkey creation.\n * @param {CreatePasskeyOptions} options Additional passkey creation options.\n * @returns {Promise<AuthResult>} Result of the passkey creation operation.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * // Button click handler\n * async function handleSignupButtonClick() {\n * const username = \"billy@loginid.io\";\n *\n * try {\n * // Sign up with a passkey\n * const signupResult = await lid.createPasskey(username);\n * // Handle the signup result\n * console.log(\"Signup Result:\", signupResult);\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during signup:\", error);\n * }\n * }\n *\n * // Attach the click handler to a button\n * const signinButton = document.getElementById(\"signinButton\");\n * signinButton.addEventListener(\"click\", handleSigninButtonClick);\n * ```\n */\n async createPasskey(\n username: string,\n authzToken: string = \"\",\n options: CreatePasskeyOptions = {},\n ): Promise<AuthResult> {\n const appId = this.config.getAppId();\n const deviceId = DeviceStore.getDeviceId(appId);\n const deviceInfo = defaultDeviceInfo(deviceId);\n const trustStore = new TrustStore(appId);\n const opts = passkeyOptions(username, authzToken, options);\n\n opts.authzToken = this.session.getToken(opts);\n if (opts.authzToken) {\n // guard against username mismatch\n const parsedToken = parseJwt(opts.authzToken);\n if (parsedToken.username !== username) {\n opts.authzToken = \"\";\n }\n }\n\n const trustInfo = await trustStore.setOrSignWithTrustId(username);\n\n const regInitRequestBody: RegInitRequestBody = {\n app: {\n id: appId,\n },\n deviceInfo: deviceInfo,\n user: {\n username: username,\n usernameType: opts.usernameType,\n displayName: opts.displayName,\n },\n ...(trustInfo && { trustItems: { auth: trustInfo } }),\n };\n\n const regInitResponseBody = await this.service.reg.regRegInit({\n requestBody: regInitRequestBody,\n ...(opts.authzToken && { authorization: opts.authzToken }),\n });\n\n const regCompleteRequestBody =\n await WebAuthnHelper.createNavigatorCredential(regInitResponseBody);\n\n const regCompleteResponse = await this.service.reg.regRegComplete({\n requestBody: regCompleteRequestBody,\n });\n\n const result: AuthResult = toAuthResult(regCompleteResponse);\n\n this.session.setJwtCookie(regCompleteResponse.jwtAccess);\n DeviceStore.persistDeviceId(\n appId,\n deviceId || regCompleteResponse.deviceId,\n );\n\n return result;\n }\n\n /**\n * This method authenticates a user with a passkey and may trigger additional browser dialogs to guide the user through the process.\n *\n * A short-lived authorization token is returned, allowing access to protected resources for the given user such as listing, renaming or deleting passkeys.\n *\n * @param {string} username Username to authenticate. When empty, usernameless passkey authentication is performed.\n * @param {AuthenticateWithPasskeysOptions} options Additional authentication options.\n * @returns {Promise<AuthResult>} Result of the passkey authentication operation.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * // Button click handler\n * async function handleSignupButtonClick() {\n * const username = \"billy@loginid.io\";\n *\n * try {\n * // Sign in with a passkey\n * const signinResult = await lid.authenticateWithPasskey(username);\n * // Handle the signin result\n * console.log(\"Signin Result:\", signinResult);\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during signin:\", error);\n * }\n * }\n *\n * // Attach the click handler to a button\n * const signinButton = document.getElementById(\"signinButton\");\n * signinButton.addEventListener(\"click\", handleSigninButtonClick);\n * ```\n */\n async authenticateWithPasskey(\n username = \"\",\n options: AuthenticateWithPasskeysOptions = {},\n ): Promise<AuthResult> {\n const appId = this.config.getAppId();\n const deviceInfo = defaultDeviceInfo(DeviceStore.getDeviceId(appId));\n const trustStore = new TrustStore(appId);\n const opts = passkeyOptions(username, \"\", options);\n\n const trustInfo = await trustStore.setOrSignWithTrustId(\n options.autoFill ? \"\" : username,\n );\n\n const authInitRequestBody: AuthInitRequestBody = {\n app: {\n id: appId,\n },\n deviceInfo: deviceInfo,\n user: {\n username: username,\n usernameType: opts.usernameType,\n },\n ...(trustInfo && { trustItems: { auth: trustInfo } }),\n };\n\n const authInitResponseBody = await this.service.auth.authAuthInit({\n requestBody: authInitRequestBody,\n });\n\n switch (authInitResponseBody.action) {\n case \"proceed\": {\n // We can send original options here because WebAuthn options currently don't need to be defaulted\n const authCompleteRequestBody =\n await WebAuthnHelper.getNavigatorCredential(\n authInitResponseBody,\n options,\n );\n\n const authCompleteResponse = await this.service.auth.authAuthComplete({\n requestBody: authCompleteRequestBody,\n });\n\n const result = toAuthResult(authCompleteResponse);\n\n this.session.setJwtCookie(result.token);\n\n DeviceStore.persistDeviceId(appId, authCompleteResponse.deviceId);\n\n if (opts?.callbacks?.onSuccess) {\n await opts.callbacks.onSuccess(result);\n }\n\n return result;\n }\n\n case \"crossAuth\":\n case \"fallback\": {\n if (opts?.callbacks?.onFallback) {\n const fallbackOptions = mergeFallbackOptions(authInitResponseBody);\n\n await opts.callbacks.onFallback(username, fallbackOptions);\n }\n\n const emptyResponse: JWT = { userId: \"\", jwtAccess: \"\" };\n return toAuthResult(emptyResponse, false, true);\n }\n\n default:\n throw NO_LOGIN_OPTIONS_ERROR;\n }\n }\n\n /**\n * Authenticates a user by utilizing the browser's passkey autofill capabilities.\n *\n * A short-lived authorization token is returned, allowing access to protected resources for the given user such as listing, renaming or deleting passkeys.\n *\n * @param {AuthenticateWithPasskeyAutofillOptions} options Additional authentication options.\n * @returns {Promise<AuthResult>} Result of the passkey authentication operation.\n * @example\n * * import { isConditionalUIAvailable, LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * window.addEventListener(\"load\", async (event) => {\n * try {\n * const result = await isConditionalUIAvailable();\n * if (!result) {\n * // If conditional UI is not supported then continue without it or handle what to do\n * // next here.\n * return;\n * }\n *\n * const result = await lid.authenticateWithPasskeyAutofill();\n * console.log(\"Authentication Result:\", result);\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during authentication:\", error);\n * }\n * });\n */\n async authenticateWithPasskeyAutofill(\n options: AuthenticateWithPasskeyAutofillOptions = {},\n ): Promise<AuthResult> {\n options.autoFill = true;\n return await this.authenticateWithPasskey(\"\", options);\n }\n\n /**\n * This method returns a one-time OTP to be displayed on the current device. The user must be authenticated on this device.\n * The OTP is meant for cross-authentication, where the user reads the OTP from the screen and enters it on the target device.\n *\n * @param {string} username The username used for passkey authentication and OTP request.\n * @param {RequestOtpOptions} options Additional request OTP options.\n * @returns {Promise<Otp>} Result of the request OTP operation returning an OTP and expiry time.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * // Obtain credentials from LoginID\n * const BASE_URL = process.env.BASE_URL;\n *\n * // Initialize the SDK with your configuration\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * // Use the SDK components for signup and signin\n * const lid = new LoginIDWebSDK(config);\n *\n * // Button click handler\n * async function handleRequestOTPButtonClick() {\n * const username = \"billy@loginid.io\";\n *\n * try {\n * // Request OTP with passkey\n * const result = await lid.requestOtp(username);\n * const otp = result.code;\n * console.log(\"The OTP is: \", otp);\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during authentication:\", error);\n * }\n * }\n *\n * // Attach the click handler to a button\n * const requestOTPButton = document.getElementById(\"requestOTPButton\");\n * requestOTPButton.addEventListener(\"click\", handleRequestOTPButtonClick);\n * ```\n */\n async requestOtp(\n username: string,\n options: RequestOtpOptions = {},\n ): Promise<Otp> {\n options.authzToken = this.session.getToken(options);\n // if no token is found, perform authentication\n if (!options.authzToken) {\n const result = await this.authenticateWithPasskey(username, options);\n // get token after authentication\n options.authzToken = result.token;\n }\n\n const result: Otp = await this.service.auth.authAuthCodeRequest({\n authorization: options.authzToken,\n });\n\n return result;\n }\n\n /**\n * This method initiates a non-repudiation signature process by generating a transaction-specific challenge\n * and then expects the client to provide an assertion response using a passkey.\n *\n * This method is useful for confirming actions such as payments\n * or changes to sensitive account information, ensuring that the transaction is being authorized\n * by the rightful owner of the passkey.\n *\n * For a more detailed guide click [here](https://docs.loginid.io/scenarios/transaction-confirmation).\n *\n * @param {string} username The username of the user confirming the transaction.\n * @param {string} txPayload The transaction-specific payload, which could include details\n * such as the transaction amount, recipient, and other metadata necessary for the transaction.\n * @param {ConfirmTransactionOptions} options Optional parameters for transaction confirmation.\n * @returns {Promise<TxComplete>} A promise that resolves with the result of the transaction confirmation operation.\n * The result includes details about the transaction's details and includes a new JWT access token.\n * @example\n * ```javascript\n * import { LoginIDWebSDK } from \"@loginid/websdk3\";\n *\n * const config = {\n * baseUrl: BASE_URL,\n * };\n *\n * const lid = new LoginIDWebSDK(config);\n *\n * const username = \"jane@securelogin.com\";\n * const txPayload = JSON.stringify({\n * amount: 100,\n * recipient: \"bob@securepay.com\",\n * });\n * // Unique transaction nonce\n * const nonce = \"f846bb01-492e-422b-944a-44b04adc441e\";\n *\n * async function handleTransactionConfirmation() {\n * try {\n * // Confirm the transaction\n * const confirmationResult = await lid.confirmTransaction(\n * username,\n * txPayload,\n * nonce\n * );\n * // Handle the transaction confirmation result\n * console.log(\"Transaction Confirmation Result:\", confirmationResult);\n *\n * // Check nonce\n * const { nonce: resultNonce } = confirmationResult;\n * if (nonce !== resultNonce) {\n * throw new Error(\"Nonce mismatch\");\n * }\n * } catch (error) {\n * // Handle errors\n * console.error(\"Error during transaction confirmation:\", error);\n * }\n * }\n *\n * // Attach the click handler to a button for transaction confirmation\n * const confirmTransactionButton = document.getElementById(\n * \"confirmTransactionButton\"\n * );\n * confirmTransactionButton.addEventListener(\n * \"click\",\n * handleTransactionConfirmation\n * );\n * ```\n */\n async confirmTransaction(\n username: string,\n txPayload: string,\n options: ConfirmTransactionOptions = {},\n ): Promise<TxComplete> {\n const opts = confirmTransactionOptions(username, options);\n const txInitRequestBody: TxInitRequestBody = {\n username: username,\n txPayload: txPayload,\n nonce: opts.nonce,\n txType: opts.txType,\n };\n\n const { assertionOptions, session } = await this.service.tx.txTxInit({\n requestBody: txInitRequestBody,\n });\n\n const authInitResponseBody: AuthInit = {\n action: \"proceed\",\n crossAuthMethods: [],\n fallbackMethods: [],\n assertionOptions: assertionOptions,\n session: session,\n };\n\n const { assertionResult } =\n await WebAuthnHelper.getNavigatorCredential(authInitResponseBody);\n\n const txCompleteRequestBody: TxCompleteRequestBody = {\n authenticatorData: assertionResult.authenticatorData,\n clientData: assertionResult.clientDataJSON,\n keyHandle: assertionResult.credentialId,\n session: session,\n signature: assertionResult.signature,\n };\n\n const result = await this.service.tx.txTxComplete({\n requestBody: txCompleteRequestBody,\n });\n\n return result;\n }\n}\n\nexport default Passkeys;\n","// Copyright (C) LoginID\n\nimport { LoginIDBase, Utils } from \"@loginid/core/controllers\";\nimport PasskeyManager from \"./controllers/passkey-manager\";\nimport { LoginIDConfig } from \"@loginid/core/controllers\";\nimport { applyMixins } from \"@loginid/core/helpers\";\nimport Passkeys from \"./controllers/passkeys\";\nimport OTP from \"./controllers/otp\";\n\ninterface LoginIDWebSDK extends Passkeys, OTP, PasskeyManager, Utils {}\n\nclass LoginIDWebSDK extends LoginIDBase {\n constructor(config: LoginIDConfig) {\n super(config);\n }\n}\n\napplyMixins(LoginIDWebSDK, [LoginIDBase, Passkeys, OTP, PasskeyManager, Utils]);\n\nexport default LoginIDWebSDK;\n"],"mappings":"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","names":["index_exports","__export","t","d","s","loginid_default","c","m","b","index_default","h","r","o","__toCommonJS","defaultDeviceInfo","deviceId","device","isPlatformAuthenticatorAvailable","isConditionalUIAvailable","getCookie","name","parts","setCookie","cookie","deleteCookie","AbortError","message","LoginIDError","PasskeyError","code","originalError","StorageError","base64EncodeUrl","str","b2a","input","base64Chars","encodedArray","inputIndex","char1","char2","char3","combined","result","padding","a2b","charToValueMap","fromCharCode","i","accumulator","accumulatorBits","decodedString","char","charValue","bufferToBase64Url","data","binary","bytes","base64","base64UrlToBuffer","parseJwt","token","jsonPayload","c","e","generateRandomId","length","characters","generateES256KeyPair","exportPublicKeyJwk","keyPair","signWithES256PrivateKey","privateKey","tokenData","buffer","generateRandomString","array","byte","randomUUID","AbortControllerManager","_AbortControllerManager","error","AbortError","controller","identifyCreateError","options","name","publicKey","PasskeyError","rpId","identifyGetError","USER_NO_OP_ERROR","LoginIDError","NO_LOGIN_OPTIONS_ERROR","createPasskeyCredential","init","excludeCredentials","cred","transformedCred","base64UrlToBuffer","pubKeyCredParams","credential","e","getPasskeyCredential","allowCredentials","credOptions","WebAuthnHelper","authInitResponseBody","assertionOptions","session","response","bufferToBase64Url","regInitResponseBody","registrationRequestOptions","publicKeyAlg","authenticatorData","transports","PasskeysService","httpRequest","authorization","id","requestBody","aaguid","BaseHttpRequest","config","CancelError","message","CancelablePromise","#isResolved","#isRejected","#isCancelled","#cancelHandlers","#promise","#resolve","#reject","executor","resolve","reject","onResolve","value","onReject","reason","onCancel","cancelHandler","onFulfilled","onRejected","onFinally","error","ApiError","request","response","isDefined","isString","isStringWithValue","isBlob","isFormData","base64","str","getQueryString","params","qs","append","key","process","v","k","getUrl","options","encoder","path","substring","group","url","getFormData","formData","_","resolver","getHeaders","token","username","password","additionalHeaders","headers","credentials","getRequestBody","sendRequest","body","controller","getResponseHeader","responseHeader","content","getResponseBody","contentType","type","catchErrorCodes","result","errorStatus","errorStatusText","errorBody","responseBody","FetchHttpRequest","AuthService","userAgent","MfaService","RegService","TxService","LoginIDService","HttpRequest","mfaOptions","username","options","toMfaInfo","mfaNextResult","toMfaSessionDetails","info","tokenSet","remainingFactors","factor","name","label","desc","result","option","passkeyOption","nextAction","LoginIDConfigValidator","config","pattern","match","LoginIDParamValidator","_LoginIDParamValidator","factorName","info","options","session","payload","LoginIDError","canFindPayloadInInfo","factor","f","getFactorPayload","key","selectedOption","option","parseJwt","SessionManager","config","LoginIDConfigValidator","options","data","parseJwt","jwt","token","expiry","cookie","setCookie","getCookie","deleteCookie","result","accessToken","idToken","payloadSignature","refreshToken","setTokenCookie","name","tokenPayload","tokenType","tokenName","applyMixins","derivedCtor","constructors","baseCtor","name","toTrustIDPayload","id","generateRandomId","signJwtWithJwk","payload","publicKeyJwk","privateKey","encodedHeader","base64EncodeUrl","b2a","encodedPayload","unsignedToken","signature","signWithES256PrivateKey","LocalStorageWrapper","key","value","data","deviceStorageKey","appId","DeviceStore","LocalStorageWrapper","deviceId","IndexedDBWrapper","dbName","dbVersion","storeKey","indexes","open","db","store","name","keyPath","options","indexName","value","resolve","reject","request","StorageError","result","cursor","record","id","walletTrustIdDbName","walletTrustIdStorageKey","BaseCheckoutStore","IndexedDBWrapper","dbName","trustStorageKey","dbVersion","keyPair","generateES256KeyPair","publicKey","exportPublicKeyJwk","token","randomUUID","checkoutId","signJwtWithJwk","record","error","StorageError","WalletTrustIdStore","BaseCheckoutStore","walletTrustIdDbName","walletTrustIdStorageKey","dbVersion","appIdIndex","nameIndex","dbName","trustStorageKey","appIdUsernameCompositeIndex","TrustStore","IndexedDBWrapper","appId","username","keyPair","generateES256KeyPair","publicKey","exportPublicKeyJwk","token","toTrustIDPayload","trustId","signJwtWithJwk","record","error","StorageError","deletePromises","mfaStorageKey","MfaStore","_MfaStore","LocalStorageWrapper","info","session","LoginIDBase","config","LoginIDConfigValidator","LoginIDService","SessionManager","Utils","result","requestBody","defaultDeviceInfo","error","ApiError","appId","MfaStore","MFA","username","options","deviceId","DeviceStore","deviceInfo","opts","mfaOptions","walletTrustId","WalletTrustIdStore","trustId","TrustStore","mfaBeginRequestBody","mfaNextResult","mfaInfo","toMfaInfo","toMfaSessionDetails","factorName","info","payload","session","LoginIDParamValidator","requestOptions","authCompleteRequestBody","WebAuthnHelper","regCompleteRequestBody","newSession","LoginIDError","tokenSet","fn","mfaSuccessResult","newMfaInfo","LoginIDMfa","LoginIDBase","config","applyMixins","MFA","Utils","mfa_default","PasskeyManager","u","config","options","token","id","name","passkeyRenameRequestBody","passkey_manager_default","passkeyOptions","username","authzToken","options","confirmTransactionOptions","A","toAuthResult","authResponse","isAuthenticated","isFallback","mergeFallbackOptions","authInitRes","OTP","u","config","username","otp","options","opts","passkeyOptions","request","response","result","toAuthResult","c","method","otp_default","Passkeys","otp_default","config","username","authzToken","options","appId","deviceId","w","deviceInfo","n","trustStore","k","opts","passkeyOptions","trustInfo","regInitRequestBody","regInitResponseBody","regCompleteRequestBody","m","regCompleteResponse","result","toAuthResult","authInitRequestBody","authInitResponseBody","authCompleteRequestBody","authCompleteResponse","fallbackOptions","mergeFallbackOptions","S","txPayload","confirmTransactionOptions","txInitRequestBody","assertionOptions","session","assertionResult","txCompleteRequestBody","passkeys_default","LoginIDWebSDK","u","config","l","passkeys_default","otp_default","passkey_manager_default","x","loginid_default","index_default","loginid_default"]}