{"version":3,"file":"passkeys.mjs","names":[],"sources":["../../../../src/internal/clerk-js/passkeys.ts"],"sourcesContent":["import type { ClerkRuntimeError } from '../../error';\nimport { ClerkWebAuthnError } from '../../error';\nimport type {\n CredentialReturn,\n PublicKeyCredentialCreationOptionsJSON,\n PublicKeyCredentialCreationOptionsWithoutExtensions,\n PublicKeyCredentialRequestOptionsJSON,\n PublicKeyCredentialRequestOptionsWithoutExtensions,\n PublicKeyCredentialWithAuthenticatorAssertionResponse,\n PublicKeyCredentialWithAuthenticatorAttestationResponse,\n} from '../../types';\n\ntype WebAuthnCreateCredentialReturn = CredentialReturn;\ntype WebAuthnGetCredentialReturn = CredentialReturn;\n\nclass Base64Converter {\n static encode(buffer: ArrayBuffer): string {\n return btoa(String.fromCharCode(...new Uint8Array(buffer)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n }\n\n static decode(base64url: string): ArrayBuffer {\n const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n\n const binaryString = atob(base64);\n const length = binaryString.length;\n const bytes = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n }\n}\n\nasync function webAuthnCreateCredential(\n publicKeyOptions: PublicKeyCredentialCreationOptionsWithoutExtensions,\n): Promise {\n try {\n // Typescript types are not aligned with the spec. These type assertions are required to comply with the spec.\n const credential = (await navigator.credentials.create({\n publicKey: publicKeyOptions,\n })) as PublicKeyCredentialWithAuthenticatorAttestationResponse | null;\n\n if (!credential) {\n return {\n error: new ClerkWebAuthnError('Browser failed to create credential', {\n code: 'passkey_registration_failed',\n }),\n publicKeyCredential: null,\n };\n }\n\n return { publicKeyCredential: credential, error: null };\n } catch (e) {\n return { error: handlePublicKeyCreateError(e as Error), publicKeyCredential: null };\n }\n}\n\nclass WebAuthnAbortService {\n private controller: AbortController | undefined;\n\n private __abort() {\n if (!this.controller) {\n return;\n }\n const abortError = new Error();\n abortError.name = 'AbortError';\n this.controller.abort(abortError);\n }\n\n createAbortSignal() {\n this.__abort();\n const newController = new AbortController();\n this.controller = newController;\n return newController.signal;\n }\n\n abort() {\n this.__abort();\n this.controller = undefined;\n }\n}\n\nconst __internal_WebAuthnAbortService = new WebAuthnAbortService();\n\nasync function webAuthnGetCredential({\n publicKeyOptions,\n conditionalUI,\n}: {\n publicKeyOptions: PublicKeyCredentialRequestOptionsWithoutExtensions;\n conditionalUI: boolean;\n}): Promise {\n try {\n // Typescript types are not aligned with the spec. These type assertions are required to comply with the spec.\n const credential = (await navigator.credentials.get({\n publicKey: publicKeyOptions,\n mediation: conditionalUI ? 'conditional' : 'optional',\n signal: __internal_WebAuthnAbortService.createAbortSignal(),\n })) as PublicKeyCredentialWithAuthenticatorAssertionResponse | null;\n\n if (!credential) {\n return {\n error: new ClerkWebAuthnError('Browser failed to get credential', { code: 'passkey_retrieval_failed' }),\n publicKeyCredential: null,\n };\n }\n\n return { publicKeyCredential: credential, error: null };\n } catch (e) {\n return { error: handlePublicKeyGetError(e as Error), publicKeyCredential: null };\n }\n}\n\nfunction handlePublicKeyError(error: Error): ClerkWebAuthnError | ClerkRuntimeError | Error {\n if (error.name === 'AbortError') {\n return new ClerkWebAuthnError(error.message, { code: 'passkey_operation_aborted' });\n }\n if (error.name === 'SecurityError') {\n return new ClerkWebAuthnError(error.message, { code: 'passkey_invalid_rpID_or_domain' });\n }\n return error;\n}\n\n/**\n * Map webauthn errors from `navigator.credentials.create()` to Clerk-js errors\n *\n * @param error\n */\nfunction handlePublicKeyCreateError(error: Error): ClerkWebAuthnError | ClerkRuntimeError | Error {\n if (error.name === 'InvalidStateError') {\n // Note: Firefox will throw 'NotAllowedError' when passkeys exists\n return new ClerkWebAuthnError(error.message, { code: 'passkey_already_exists' });\n }\n if (error.name === 'NotAllowedError') {\n return new ClerkWebAuthnError(error.message, { code: 'passkey_registration_cancelled' });\n }\n return handlePublicKeyError(error);\n}\n\n/**\n * Map webauthn errors from `navigator.credentials.get()` to Clerk-js errors\n *\n * @param error\n */\nfunction handlePublicKeyGetError(error: Error): ClerkWebAuthnError | ClerkRuntimeError | Error {\n if (error.name === 'NotAllowedError') {\n return new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_cancelled' });\n }\n return handlePublicKeyError(error);\n}\n\nfunction convertJSONToPublicKeyCreateOptions(jsonPublicKey: PublicKeyCredentialCreationOptionsJSON) {\n const userIdBuffer = base64UrlToBuffer(jsonPublicKey.user.id);\n const challengeBuffer = base64UrlToBuffer(jsonPublicKey.challenge);\n\n const excludeCredentialsWithBuffer = (jsonPublicKey.excludeCredentials || []).map(cred => ({\n ...cred,\n id: base64UrlToBuffer(cred.id),\n }));\n\n return {\n ...jsonPublicKey,\n excludeCredentials: excludeCredentialsWithBuffer,\n challenge: challengeBuffer,\n user: {\n ...jsonPublicKey.user,\n id: userIdBuffer,\n },\n } as PublicKeyCredentialCreationOptionsWithoutExtensions;\n}\n\nfunction convertJSONToPublicKeyRequestOptions(jsonPublicKey: PublicKeyCredentialRequestOptionsJSON) {\n const challengeBuffer = base64UrlToBuffer(jsonPublicKey.challenge);\n\n const allowCredentialsWithBuffer = (jsonPublicKey.allowCredentials || []).map(cred => ({\n ...cred,\n id: base64UrlToBuffer(cred.id),\n }));\n\n return {\n ...jsonPublicKey,\n allowCredentials: allowCredentialsWithBuffer,\n challenge: challengeBuffer,\n } as PublicKeyCredentialRequestOptionsWithoutExtensions;\n}\n\nfunction __serializePublicKeyCredential>(pkc: T) {\n return {\n type: pkc.type,\n id: pkc.id,\n rawId: bufferToBase64Url(pkc.rawId),\n authenticatorAttachment: pkc.authenticatorAttachment,\n };\n}\n\nfunction serializePublicKeyCredential(pkc: PublicKeyCredentialWithAuthenticatorAttestationResponse) {\n const response = pkc.response;\n return {\n ...__serializePublicKeyCredential(pkc),\n response: {\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n attestationObject: bufferToBase64Url(response.attestationObject),\n transports: response.getTransports(),\n },\n };\n}\n\nfunction serializePublicKeyCredentialAssertion(pkc: PublicKeyCredentialWithAuthenticatorAssertionResponse) {\n const response = pkc.response;\n return {\n ...__serializePublicKeyCredential(pkc),\n response: {\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n authenticatorData: bufferToBase64Url(response.authenticatorData),\n signature: bufferToBase64Url(response.signature),\n userHandle: response.userHandle ? bufferToBase64Url(response.userHandle) : null,\n },\n };\n}\n\nconst bufferToBase64Url = Base64Converter.encode.bind(Base64Converter);\nconst base64UrlToBuffer = Base64Converter.decode.bind(Base64Converter);\n\nexport {\n base64UrlToBuffer,\n bufferToBase64Url,\n handlePublicKeyCreateError,\n webAuthnCreateCredential,\n webAuthnGetCredential,\n convertJSONToPublicKeyCreateOptions,\n convertJSONToPublicKeyRequestOptions,\n serializePublicKeyCredential,\n serializePublicKeyCredentialAssertion,\n __internal_WebAuthnAbortService,\n};\n"],"mappings":"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"}