@clerk/expo-passkeys 1.0.0-canary.ve1452ef66284a606b54b0103ff69e6960d6992bb → 1.0.0-snapshot.v20251203203405

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +1027 -0
  2. package/README.md +3 -3
  3. package/{build → dist}/ClerkExpoPasskeys.types.d.ts +1 -1
  4. package/dist/ClerkExpoPasskeys.types.d.ts.map +1 -0
  5. package/dist/ClerkExpoPasskeys.types.js +17 -0
  6. package/dist/ClerkExpoPasskeys.types.js.map +1 -0
  7. package/dist/ClerkExpoPasskeysModule.js +26 -0
  8. package/dist/ClerkExpoPasskeysModule.js.map +1 -0
  9. package/dist/ClerkExpoPasskeysModule.web.js +25 -0
  10. package/dist/ClerkExpoPasskeysModule.web.js.map +1 -0
  11. package/{build → dist}/index.d.ts.map +1 -1
  12. package/dist/index.js +181 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/tsconfig.declarations.tsbuildinfo +1 -0
  15. package/{build → dist}/utils.d.ts +5 -5
  16. package/dist/utils.d.ts.map +1 -0
  17. package/dist/utils.js +122 -0
  18. package/dist/utils.js.map +1 -0
  19. package/package.json +21 -22
  20. package/src/ClerkExpoPasskeys.types.ts +1 -1
  21. package/src/ClerkExpoPasskeysModule.ts +1 -1
  22. package/src/index.ts +3 -2
  23. package/src/utils.ts +3 -3
  24. package/tsconfig.declarations.json +12 -0
  25. package/tsconfig.json +22 -5
  26. package/tsup.config.ts +30 -0
  27. package/.eslintrc.js +0 -7
  28. package/build/ClerkExpoPasskeys.types.d.ts.map +0 -1
  29. package/build/ClerkExpoPasskeys.types.js +0 -2
  30. package/build/ClerkExpoPasskeys.types.js.map +0 -1
  31. package/build/ClerkExpoPasskeysModule.js +0 -5
  32. package/build/ClerkExpoPasskeysModule.js.map +0 -1
  33. package/build/ClerkExpoPasskeysModule.web.js +0 -2
  34. package/build/ClerkExpoPasskeysModule.web.js.map +0 -1
  35. package/build/index.js +0 -143
  36. package/build/index.js.map +0 -1
  37. package/build/utils.d.ts.map +0 -1
  38. package/build/utils.js +0 -81
  39. package/build/utils.js.map +0 -1
  40. /package/{build → dist}/ClerkExpoPasskeysModule.d.ts +0 -0
  41. /package/{build → dist}/ClerkExpoPasskeysModule.d.ts.map +0 -0
  42. /package/{build → dist}/ClerkExpoPasskeysModule.web.d.ts +0 -0
  43. /package/{build → dist}/ClerkExpoPasskeysModule.web.d.ts.map +0 -0
  44. /package/{build → dist}/index.d.ts +0 -0
@@ -1,13 +1,13 @@
1
1
  import { ClerkWebAuthnError } from '@clerk/shared/error';
2
2
  export { ClerkWebAuthnError };
3
- export declare function encodeBase64(data: ArrayLike<number> | ArrayBufferLike): string;
4
- export declare function encodeBase64Url(data: ArrayLike<number> | ArrayBufferLike): string;
5
- export declare function decodeBase64Url(data: string): Uint8Array;
3
+ export declare function encodeBase64(data: ArrayBufferLike): string;
4
+ export declare function encodeBase64Url(data: ArrayBufferLike): string;
5
+ export declare function decodeBase64Url(data: string): Uint8Array<ArrayBuffer>;
6
6
  export declare function decodeToken(data: string): any;
7
- export declare function decodeBase64(data: string): Uint8Array;
7
+ export declare function decodeBase64(data: string): Uint8Array<ArrayBuffer>;
8
8
  export declare function utf8Decode(buffer: BufferSource): string;
9
9
  export declare function toArrayBuffer(bufferSource: BufferSource): ArrayBufferLike;
10
10
  export declare function base64urlToArrayBuffer(base64url: string): ArrayBuffer;
11
- export declare function arrayBufferToBase64Url(buffer: any): string;
11
+ export declare function arrayBufferToBase64Url(buffer: ArrayBufferLike): string;
12
12
  export declare function mapNativeErrorToClerkWebAuthnErrorCode(code: string, message: string, action: 'get' | 'create'): ClerkWebAuthnError;
13
13
  //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,UAEjD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,UAEpD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,2BAE3C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,OASvC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,2BAExC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,UAG9C;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,mBAQvD;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,eAcvD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,UAa7D;AAED,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,KAAK,GAAG,QAAQ,GACvB,kBAAkB,CAyBpB"}
package/dist/utils.js ADDED
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var utils_exports = {};
20
+ __export(utils_exports, {
21
+ ClerkWebAuthnError: () => import_error.ClerkWebAuthnError,
22
+ arrayBufferToBase64Url: () => arrayBufferToBase64Url,
23
+ base64urlToArrayBuffer: () => base64urlToArrayBuffer,
24
+ decodeBase64: () => decodeBase64,
25
+ decodeBase64Url: () => decodeBase64Url,
26
+ decodeToken: () => decodeToken,
27
+ encodeBase64: () => encodeBase64,
28
+ encodeBase64Url: () => encodeBase64Url,
29
+ mapNativeErrorToClerkWebAuthnErrorCode: () => mapNativeErrorToClerkWebAuthnErrorCode,
30
+ toArrayBuffer: () => toArrayBuffer,
31
+ utf8Decode: () => utf8Decode
32
+ });
33
+ module.exports = __toCommonJS(utils_exports);
34
+ var import_error = require("@clerk/shared/error");
35
+ var import_buffer = require("buffer");
36
+ function encodeBase64(data) {
37
+ return btoa(String.fromCharCode(...new Uint8Array(data)));
38
+ }
39
+ function encodeBase64Url(data) {
40
+ return encodeBase64(data).replaceAll("=", "").replaceAll("+", "-").replaceAll("/", "_");
41
+ }
42
+ function decodeBase64Url(data) {
43
+ return decodeBase64(data.replaceAll("-", "+").replaceAll("_", "/"));
44
+ }
45
+ function decodeToken(data) {
46
+ const base64 = data.replace(/-/g, "+").replace(/_/g, "/");
47
+ const jsonPayload = decodeURIComponent(
48
+ atob(base64).split("").map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join("")
49
+ );
50
+ return JSON.parse(jsonPayload);
51
+ }
52
+ function decodeBase64(data) {
53
+ return Uint8Array.from(atob(data).split(""), (x) => x.charCodeAt(0));
54
+ }
55
+ function utf8Decode(buffer) {
56
+ const textDecoder = new TextDecoder();
57
+ return textDecoder.decode(buffer);
58
+ }
59
+ function toArrayBuffer(bufferSource) {
60
+ if (bufferSource instanceof ArrayBuffer) {
61
+ return bufferSource;
62
+ } else if (ArrayBuffer.isView(bufferSource)) {
63
+ return bufferSource.buffer;
64
+ } else {
65
+ throw new TypeError("Expected a BufferSource, but received an incompatible type.");
66
+ }
67
+ }
68
+ function base64urlToArrayBuffer(base64url) {
69
+ const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
70
+ const binaryString = import_buffer.Buffer.from(base64, "base64").toString("binary");
71
+ const len = binaryString.length;
72
+ const buffer = new ArrayBuffer(len);
73
+ const uintArray = new Uint8Array(buffer);
74
+ for (let i = 0; i < len; i++) {
75
+ uintArray[i] = binaryString.charCodeAt(i);
76
+ }
77
+ return buffer;
78
+ }
79
+ function arrayBufferToBase64Url(buffer) {
80
+ const bytes = new Uint8Array(buffer);
81
+ let binary = "";
82
+ for (let i = 0; i < bytes.length; i++) {
83
+ binary += String.fromCharCode(bytes[i]);
84
+ }
85
+ const base64String = btoa(binary);
86
+ const base64Url = base64String.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
87
+ return base64Url;
88
+ }
89
+ function mapNativeErrorToClerkWebAuthnErrorCode(code, message, action) {
90
+ if (code === "1000" || code === "1004" || code === "CreatePublicKeyCredentialDomException") {
91
+ return new import_error.ClerkWebAuthnError(message, {
92
+ code: action === "create" ? "passkey_registration_failed" : "passkey_retrieval_failed"
93
+ });
94
+ }
95
+ if (code === "1001" || code === "CreateCredentialCancellationException" || code === "GetCredentialCancellationException") {
96
+ return new import_error.ClerkWebAuthnError(message, { code: "passkey_registration_cancelled" });
97
+ }
98
+ if (code === "1002") {
99
+ return new import_error.ClerkWebAuthnError(message, { code: "passkey_invalid_rpID_or_domain" });
100
+ }
101
+ if (code === "1003" || code === "CreateCredentialInterruptedException") {
102
+ return new import_error.ClerkWebAuthnError(message, { code: "passkey_operation_aborted" });
103
+ }
104
+ return new import_error.ClerkWebAuthnError(message, {
105
+ code: action === "create" ? "passkey_registration_failed" : "passkey_retrieval_failed"
106
+ });
107
+ }
108
+ // Annotate the CommonJS export names for ESM import in node:
109
+ 0 && (module.exports = {
110
+ ClerkWebAuthnError,
111
+ arrayBufferToBase64Url,
112
+ base64urlToArrayBuffer,
113
+ decodeBase64,
114
+ decodeBase64Url,
115
+ decodeToken,
116
+ encodeBase64,
117
+ encodeBase64Url,
118
+ mapNativeErrorToClerkWebAuthnErrorCode,
119
+ toArrayBuffer,
120
+ utf8Decode
121
+ });
122
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { ClerkWebAuthnError } from '@clerk/shared/error';\nimport { Buffer } from 'buffer';\nexport { ClerkWebAuthnError };\n\nexport function encodeBase64(data: ArrayBufferLike) {\n return btoa(String.fromCharCode(...new Uint8Array(data)));\n}\n\nexport function encodeBase64Url(data: ArrayBufferLike) {\n return encodeBase64(data).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_');\n}\n\nexport function decodeBase64Url(data: string) {\n return decodeBase64(data.replaceAll('-', '+').replaceAll('_', '/'));\n}\n\nexport function decodeToken(data: string) {\n const base64 = data.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n );\n return JSON.parse(jsonPayload);\n}\n\nexport function decodeBase64(data: string) {\n return Uint8Array.from(atob(data).split(''), x => x.charCodeAt(0));\n}\n\nexport function utf8Decode(buffer: BufferSource) {\n const textDecoder = new TextDecoder();\n return textDecoder.decode(buffer);\n}\n\nexport function toArrayBuffer(bufferSource: BufferSource) {\n if (bufferSource instanceof ArrayBuffer) {\n return bufferSource; // It's already an ArrayBuffer\n } else if (ArrayBuffer.isView(bufferSource)) {\n return bufferSource.buffer; // Extract the ArrayBuffer from the typed array\n } else {\n throw new TypeError('Expected a BufferSource, but received an incompatible type.');\n }\n}\n\nexport function base64urlToArrayBuffer(base64url: string) {\n const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');\n\n const binaryString = Buffer.from(base64, 'base64').toString('binary');\n\n const len = binaryString.length;\n const buffer = new ArrayBuffer(len);\n const uintArray = new Uint8Array(buffer);\n\n for (let i = 0; i < len; i++) {\n uintArray[i] = binaryString.charCodeAt(i);\n }\n\n return buffer;\n}\n\nexport function arrayBufferToBase64Url(buffer: ArrayBufferLike) {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n\n const base64String = btoa(binary);\n\n const base64Url = base64String.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\n return base64Url;\n}\n\nexport function mapNativeErrorToClerkWebAuthnErrorCode(\n code: string,\n message: string,\n action: 'get' | 'create',\n): ClerkWebAuthnError {\n if (code === '1000' || code === '1004' || code === 'CreatePublicKeyCredentialDomException') {\n return new ClerkWebAuthnError(message, {\n code: action === 'create' ? 'passkey_registration_failed' : 'passkey_retrieval_failed',\n });\n }\n if (\n code === '1001' ||\n code === 'CreateCredentialCancellationException' ||\n code === 'GetCredentialCancellationException'\n ) {\n return new ClerkWebAuthnError(message, { code: 'passkey_registration_cancelled' });\n }\n\n if (code === '1002') {\n return new ClerkWebAuthnError(message, { code: 'passkey_invalid_rpID_or_domain' });\n }\n\n if (code === '1003' || code === 'CreateCredentialInterruptedException') {\n return new ClerkWebAuthnError(message, { code: 'passkey_operation_aborted' });\n }\n\n return new ClerkWebAuthnError(message, {\n code: action === 'create' ? 'passkey_registration_failed' : 'passkey_retrieval_failed',\n });\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerk/expo-passkeys",
3
- "version": "1.0.0-canary.ve1452ef66284a606b54b0103ff69e6960d6992bb",
3
+ "version": "1.0.0-snapshot.v20251203203405",
4
4
  "description": "Passkeys library to be used with Clerk for expo",
5
5
  "keywords": [
6
6
  "react-native",
@@ -17,31 +17,30 @@
17
17
  "repository": "git+https://github.com/clerk/javascript.git",
18
18
  "license": "MIT",
19
19
  "author": "Clerk",
20
- "main": "build/index.js",
21
- "types": "build/index.d.ts",
22
- "scripts": {
23
- "build": "EXPO_NONINTERACTIVE=1 expo-module build",
24
- "build:watch": "expo-module build",
25
- "clean": "expo-module clean",
26
- "expo-module": "expo-module",
27
- "lint": "expo-module lint",
28
- "open:android": "open -a \"Android Studio\" example/android",
29
- "open:ios": "xed example/ios",
30
- "prepare": "expo-module prepare",
31
- "prepublishOnly": "expo-module prepublishOnly"
32
- },
20
+ "main": "dist/index.js",
21
+ "types": "dist/index.d.ts",
33
22
  "dependencies": {
34
- "@clerk/shared": "2.10.1-snapshot.va96a299",
35
- "@clerk/types": "4.28.0-snapshot.va96a299"
23
+ "@clerk/shared": "^4.0.0-snapshot.v20251203203405"
36
24
  },
37
25
  "devDependencies": {
38
- "expo-module-scripts": "^3.5.2",
39
- "expo-modules-core": "^1.12.19"
26
+ "expo": "~52.0.47"
40
27
  },
41
28
  "peerDependencies": {
42
- "expo": "*",
43
- "react": "*",
29
+ "expo": ">=53 <55",
30
+ "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0",
44
31
  "react-native": "*"
45
32
  },
46
- "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
47
- }
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "build:declarations": "tsc -p tsconfig.declarations.json",
36
+ "clean": "rimraf ./dist",
37
+ "dev": "tsup --watch",
38
+ "dev:publish": "pnpm dev -- --env.publish",
39
+ "format": "node ../../scripts/format-package.mjs",
40
+ "format:check": "node ../../scripts/format-package.mjs --check",
41
+ "lint": "eslint src",
42
+ "open:android": "open -a \"Android Studio\" example/android",
43
+ "open:ios": "xed example/ios",
44
+ "publish:local": "pnpm yalc push --replace --sig"
45
+ }
46
+ }
@@ -4,7 +4,7 @@ import type {
4
4
  PublicKeyCredentialRequestOptionsWithoutExtensions,
5
5
  PublicKeyCredentialWithAuthenticatorAssertionResponse as ClerkPublicKeyCredentialWithAuthenticatorAssertionResponse,
6
6
  PublicKeyCredentialWithAuthenticatorAttestationResponse as ClerkPublicKeyCredentialWithAuthenticatorAttestationResponse,
7
- } from '@clerk/types';
7
+ } from '@clerk/shared/types';
8
8
 
9
9
  export type {
10
10
  PublicKeyCredentialRequestOptionsWithoutExtensions,
@@ -1,4 +1,4 @@
1
- import { requireNativeModule } from 'expo-modules-core';
1
+ import { requireNativeModule } from 'expo';
2
2
 
3
3
  // It loads the native module object from the JSI or falls back to
4
4
  // the bridge module (from NativeModulesProxy) if the remote debugger is on.
package/src/index.ts CHANGED
@@ -86,7 +86,7 @@ export async function create(
86
86
  publicKeyCredential: makeSerializedCreateResponse(typeof response === 'string' ? JSON.parse(response) : response),
87
87
  error: null,
88
88
  };
89
- } catch (error) {
89
+ } catch (error: any) {
90
90
  return {
91
91
  publicKeyCredential: null,
92
92
  error: mapNativeErrorToClerkWebAuthnErrorCode(error.code, error.message, 'create'),
@@ -125,6 +125,7 @@ export async function get({
125
125
 
126
126
  const serializedPublicCredential: SerializedPublicKeyCredentialRequestOptions = {
127
127
  ...publicKeyOptions,
128
+ // @ts-expect-error FIXME
128
129
  challenge: arrayBufferToBase64Url(publicKeyOptions.challenge),
129
130
  };
130
131
 
@@ -147,7 +148,7 @@ export async function get({
147
148
  publicKeyCredential: makeSerializedGetResponse(typeof response === 'string' ? JSON.parse(response) : response),
148
149
  error: null,
149
150
  };
150
- } catch (error) {
151
+ } catch (error: any) {
151
152
  return {
152
153
  publicKeyCredential: null,
153
154
  error: mapNativeErrorToClerkWebAuthnErrorCode(error.code, error.message, 'get'),
package/src/utils.ts CHANGED
@@ -2,11 +2,11 @@ import { ClerkWebAuthnError } from '@clerk/shared/error';
2
2
  import { Buffer } from 'buffer';
3
3
  export { ClerkWebAuthnError };
4
4
 
5
- export function encodeBase64(data: ArrayLike<number> | ArrayBufferLike) {
5
+ export function encodeBase64(data: ArrayBufferLike) {
6
6
  return btoa(String.fromCharCode(...new Uint8Array(data)));
7
7
  }
8
8
 
9
- export function encodeBase64Url(data: ArrayLike<number> | ArrayBufferLike) {
9
+ export function encodeBase64Url(data: ArrayBufferLike) {
10
10
  return encodeBase64(data).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_');
11
11
  }
12
12
 
@@ -60,7 +60,7 @@ export function base64urlToArrayBuffer(base64url: string) {
60
60
  return buffer;
61
61
  }
62
62
 
63
- export function arrayBufferToBase64Url(buffer) {
63
+ export function arrayBufferToBase64Url(buffer: ArrayBufferLike) {
64
64
  const bytes = new Uint8Array(buffer);
65
65
  let binary = '';
66
66
 
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "skipLibCheck": true,
5
+ "noEmit": false,
6
+ "declaration": true,
7
+ "emitDeclarationOnly": true,
8
+ "declarationMap": true,
9
+ "sourceMap": false,
10
+ "declarationDir": "./dist"
11
+ }
12
+ }
package/tsconfig.json CHANGED
@@ -1,9 +1,26 @@
1
- // @generated by expo-module-scripts
2
1
  {
3
- "extends": "expo-module-scripts/tsconfig.base",
4
2
  "compilerOptions": {
5
- "outDir": "./build"
3
+ "allowJs": true,
4
+ "baseUrl": ".",
5
+ "declaration": true,
6
+ "declarationMap": false,
7
+ "esModuleInterop": true,
8
+ "importHelpers": true,
9
+ "incremental": true,
10
+ "jsx": "react-jsx",
11
+ "lib": ["ESNext", "dom"],
12
+ "module": "NodeNext",
13
+ "moduleResolution": "NodeNext",
14
+ "noEmitOnError": false,
15
+ "noImplicitReturns": true,
16
+ "noUnusedLocals": true,
17
+ "noUnusedParameters": true,
18
+ "outDir": "dist",
19
+ "resolveJsonModule": true,
20
+ "skipLibCheck": true,
21
+ "sourceMap": false,
22
+ "strict": true,
23
+ "target": "ES2019"
6
24
  },
7
- "include": ["./src"],
8
- "exclude": ["**/__mocks__/*", "**/__tests__/*"]
25
+ "include": ["src"]
9
26
  }
package/tsup.config.ts ADDED
@@ -0,0 +1,30 @@
1
+ import type { Options } from 'tsup';
2
+ import { defineConfig } from 'tsup';
3
+
4
+ import { runAfterLast } from '../../scripts/utils';
5
+ import { version as clerkJsVersion } from '../clerk-js/package.json';
6
+ import { name, version } from './package.json';
7
+
8
+ export default defineConfig(overrideOptions => {
9
+ const isWatch = !!overrideOptions.watch;
10
+ const shouldPublish = !!overrideOptions.env?.publish;
11
+
12
+ const options: Options = {
13
+ format: 'cjs',
14
+ outDir: './dist',
15
+ entry: ['./src/**/*.{ts,tsx,js,jsx}'],
16
+ bundle: false,
17
+ clean: true,
18
+ minify: false,
19
+ sourcemap: true,
20
+ legacyOutput: true,
21
+ define: {
22
+ PACKAGE_NAME: `"${name}"`,
23
+ PACKAGE_VERSION: `"${version}"`,
24
+ JS_PACKAGE_VERSION: `"${clerkJsVersion}"`,
25
+ __DEV__: `${isWatch}`,
26
+ },
27
+ };
28
+
29
+ return runAfterLast(['pnpm build:declarations', shouldPublish && 'pnpm publish:local'])(options);
30
+ });
package/.eslintrc.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- extends: ['@clerk/custom/node', '@clerk/custom/typescript', '@clerk/custom/react'],
4
- settings: {
5
- 'import/ignore': ['node_modules/react-native/index\\.js$'],
6
- },
7
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClerkExpoPasskeys.types.d.ts","sourceRoot":"","sources":["../src/ClerkExpoPasskeys.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,mDAAmD,EACnD,kDAAkD,EAClD,qDAAqD,IAAI,0DAA0D,EACnH,uDAAuD,IAAI,4DAA4D,EACxH,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,kDAAkD,EAClD,mDAAmD,EACnD,gBAAgB,GACjB,CAAC;AAEF,KAAK,4BAA4B,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,KAAK,CAAC;AAE3G,UAAU,iCAAiC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,uBAAuB,CAAC;IAC9B,UAAU,CAAC,EAAE,4BAA4B,EAAE,CAAC;CAC7C;AAGD,MAAM,MAAM,4CAA4C,GAAG,IAAI,CAC7D,mDAAmD,EACnD,wBAAwB,GAAG,kBAAkB,CAC9C,GAAG;IACF,EAAE,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,iCAAiC,EAAE,CAAC;CAC1D,CAAC;AAGF,MAAM,MAAM,2CAA2C,GAAG,IAAI,CAC5D,kDAAkD,EAClD,WAAW,CACZ,GAAG;IACF,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,kCAAkC,CAAC;IAC7C,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,sBAAsB,EAAE,qCAAqC,CAAC;IAC9D,IAAI,EAAE,uBAAuB,CAAC;CAC/B;AAGD,MAAM,MAAM,uDAAuD,GACjE,4DAA4D,GAAG;IAC7D,MAAM,EAAE,MAAM,GAAG,CAAC;CACnB,CAAC;AAEJ,UAAU,kCAAkC;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,MAAM,qDAAqD,GAC/D,0DAA0D,GAAG;IAC3D,MAAM,EAAE,MAAM,GAAG,CAAC;CACnB,CAAC;AAEJ,UAAU,oCAAoC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,4BAA4B,EAAE,CAAC;IAC5C,kBAAkB,CAAC,EAAE,uBAAuB,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,oCAAoC,CAAC;IAC/C,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,sBAAsB,EAAE,qCAAqC,CAAC;IAC9D,IAAI,EAAE,uBAAuB,CAAC;CAC/B"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ClerkExpoPasskeys.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClerkExpoPasskeys.types.js","sourceRoot":"","sources":["../src/ClerkExpoPasskeys.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n CredentialReturn,\n PublicKeyCredentialCreationOptionsWithoutExtensions,\n PublicKeyCredentialRequestOptionsWithoutExtensions,\n PublicKeyCredentialWithAuthenticatorAssertionResponse as ClerkPublicKeyCredentialWithAuthenticatorAssertionResponse,\n PublicKeyCredentialWithAuthenticatorAttestationResponse as ClerkPublicKeyCredentialWithAuthenticatorAttestationResponse,\n} from '@clerk/types';\n\nexport type {\n PublicKeyCredentialRequestOptionsWithoutExtensions,\n PublicKeyCredentialCreationOptionsWithoutExtensions,\n CredentialReturn,\n};\n\ntype AuthenticatorTransportFuture = 'ble' | 'cable' | 'hybrid' | 'internal' | 'nfc' | 'smart-card' | 'usb';\n\ninterface PublicKeyCredentialDescriptorJSON {\n id: string;\n type: PublicKeyCredentialType;\n transports?: AuthenticatorTransportFuture[];\n}\n\n// The serialized JSON to send to \"create\" native module\nexport type SerializedPublicKeyCredentialCreationOptions = Pick<\n PublicKeyCredentialCreationOptionsWithoutExtensions,\n 'authenticatorSelection' | 'pubKeyCredParams'\n> & {\n rp: { id: string; name: string };\n user: {\n id: string;\n displayName: string;\n name: string;\n };\n challenge: string;\n excludeCredentials?: PublicKeyCredentialDescriptorJSON[];\n};\n\n// The serialized JSON to send to \"get\" native module\nexport type SerializedPublicKeyCredentialRequestOptions = Omit<\n PublicKeyCredentialRequestOptionsWithoutExtensions,\n 'challenge'\n> & {\n challenge: string;\n};\n\n// The return type from the \"get\" native module.\nexport interface AuthenticationResponseJSON {\n id: string;\n rawId: string;\n response: AuthenticatorAssertionResponseJSON;\n authenticatorAttachment?: AuthenticatorAttachment;\n clientExtensionResults: AuthenticationExtensionsClientOutputs;\n type: PublicKeyCredentialType;\n}\n\n// The serialized response of the native module \"create\" response to be send back to clerk\nexport type PublicKeyCredentialWithAuthenticatorAttestationResponse =\n ClerkPublicKeyCredentialWithAuthenticatorAttestationResponse & {\n toJSON: () => any;\n };\n\ninterface AuthenticatorAssertionResponseJSON {\n clientDataJSON: string;\n authenticatorData: string;\n signature: string;\n userHandle?: string;\n}\n\n// The serialized response of the native module \"get\" response to be send back to clerk\nexport type PublicKeyCredentialWithAuthenticatorAssertionResponse =\n ClerkPublicKeyCredentialWithAuthenticatorAssertionResponse & {\n toJSON: () => any;\n };\n\ninterface AuthenticatorAttestationResponseJSON {\n clientDataJSON: string;\n attestationObject: string;\n authenticatorData?: string;\n transports?: AuthenticatorTransportFuture[];\n publicKeyAlgorithm?: COSEAlgorithmIdentifier;\n publicKey?: string;\n}\n\n// The type is returned from from native module \"create\" response\nexport interface RegistrationResponseJSON {\n id: string;\n rawId: string;\n response: AuthenticatorAttestationResponseJSON;\n authenticatorAttachment?: AuthenticatorAttachment;\n clientExtensionResults: AuthenticationExtensionsClientOutputs;\n type: PublicKeyCredentialType;\n}\n"]}
@@ -1,5 +0,0 @@
1
- import { requireNativeModule } from 'expo-modules-core';
2
- // It loads the native module object from the JSI or falls back to
3
- // the bridge module (from NativeModulesProxy) if the remote debugger is on.
4
- export default requireNativeModule('ClerkExpoPasskeys');
5
- //# sourceMappingURL=ClerkExpoPasskeysModule.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClerkExpoPasskeysModule.js","sourceRoot":"","sources":["../src/ClerkExpoPasskeysModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,kEAAkE;AAClE,4EAA4E;AAC5E,eAAe,mBAAmB,CAAC,mBAAmB,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\n// It loads the native module object from the JSI or falls back to\n// the bridge module (from NativeModulesProxy) if the remote debugger is on.\nexport default requireNativeModule('ClerkExpoPasskeys');\n"]}
@@ -1,2 +0,0 @@
1
- export default {};
2
- //# sourceMappingURL=ClerkExpoPasskeysModule.web.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClerkExpoPasskeysModule.web.js","sourceRoot":"","sources":["../src/ClerkExpoPasskeysModule.web.ts"],"names":[],"mappings":"AAAA,eAAe,EAAE,CAAC","sourcesContent":["export default {};\n"]}
package/build/index.js DELETED
@@ -1,143 +0,0 @@
1
- import { Platform } from 'react-native';
2
- import ClerkExpoPasskeys from './ClerkExpoPasskeysModule';
3
- import { arrayBufferToBase64Url, base64urlToArrayBuffer, ClerkWebAuthnError, encodeBase64Url, mapNativeErrorToClerkWebAuthnErrorCode, toArrayBuffer, } from './utils';
4
- const makeSerializedCreateResponse = (publicCredential) => ({
5
- id: publicCredential.id,
6
- rawId: base64urlToArrayBuffer(publicCredential.rawId),
7
- response: {
8
- getTransports: () => publicCredential?.response?.transports,
9
- attestationObject: base64urlToArrayBuffer(publicCredential.response.attestationObject),
10
- clientDataJSON: base64urlToArrayBuffer(publicCredential.response.clientDataJSON),
11
- },
12
- type: publicCredential.type,
13
- authenticatorAttachment: publicCredential.authenticatorAttachment || null,
14
- toJSON: () => publicCredential,
15
- });
16
- export async function create(publicKey) {
17
- if (!publicKey || !publicKey.rp.id) {
18
- throw new Error('Invalid public key or RpID');
19
- }
20
- const createOptions = {
21
- rp: { id: publicKey.rp.id, name: publicKey.rp.name },
22
- user: {
23
- id: encodeBase64Url(toArrayBuffer(publicKey.user.id)),
24
- displayName: publicKey.user.displayName,
25
- name: publicKey.user.name,
26
- },
27
- pubKeyCredParams: publicKey.pubKeyCredParams,
28
- challenge: encodeBase64Url(toArrayBuffer(publicKey.challenge)),
29
- authenticatorSelection: {
30
- authenticatorAttachment: 'platform',
31
- requireResidentKey: true,
32
- residentKey: 'required',
33
- userVerification: 'required',
34
- },
35
- excludeCredentials: publicKey.excludeCredentials.map(c => ({
36
- type: 'public-key',
37
- id: encodeBase64Url(toArrayBuffer(c.id)),
38
- })),
39
- };
40
- const createPasskeyModule = Platform.select({
41
- android: async () => ClerkExpoPasskeys.create(JSON.stringify(createOptions)),
42
- ios: async () => ClerkExpoPasskeys.create(createOptions.challenge, createOptions.rp.id, createOptions.user.id, createOptions.user.displayName),
43
- default: null,
44
- });
45
- if (!createPasskeyModule) {
46
- throw new Error('Platform not supported');
47
- }
48
- try {
49
- const response = await createPasskeyModule();
50
- return {
51
- publicKeyCredential: makeSerializedCreateResponse(typeof response === 'string' ? JSON.parse(response) : response),
52
- error: null,
53
- };
54
- }
55
- catch (error) {
56
- return {
57
- publicKeyCredential: null,
58
- error: mapNativeErrorToClerkWebAuthnErrorCode(error.code, error.message, 'create'),
59
- };
60
- }
61
- }
62
- const makeSerializedGetResponse = (publicKeyCredential) => {
63
- return {
64
- type: publicKeyCredential.type,
65
- id: publicKeyCredential.id,
66
- rawId: base64urlToArrayBuffer(publicKeyCredential.rawId),
67
- authenticatorAttachment: publicKeyCredential?.authenticatorAttachment || null,
68
- response: {
69
- clientDataJSON: base64urlToArrayBuffer(publicKeyCredential.response.clientDataJSON),
70
- authenticatorData: base64urlToArrayBuffer(publicKeyCredential.response.authenticatorData),
71
- signature: base64urlToArrayBuffer(publicKeyCredential.response.signature),
72
- userHandle: publicKeyCredential?.response.userHandle
73
- ? base64urlToArrayBuffer(publicKeyCredential?.response.userHandle)
74
- : null,
75
- },
76
- toJSON: () => publicKeyCredential,
77
- };
78
- };
79
- export async function get({ publicKeyOptions, }) {
80
- if (!publicKeyOptions) {
81
- throw new Error('publicKeyCredential has not been provided');
82
- }
83
- const serializedPublicCredential = {
84
- ...publicKeyOptions,
85
- challenge: arrayBufferToBase64Url(publicKeyOptions.challenge),
86
- };
87
- const getPasskeyModule = Platform.select({
88
- android: async () => ClerkExpoPasskeys.get(JSON.stringify(serializedPublicCredential)),
89
- ios: async () => ClerkExpoPasskeys.get(serializedPublicCredential.challenge, serializedPublicCredential.rpId),
90
- default: null,
91
- });
92
- if (!getPasskeyModule) {
93
- return {
94
- publicKeyCredential: null,
95
- error: new ClerkWebAuthnError('Platform is not supported', { code: 'passkey_not_supported' }),
96
- };
97
- }
98
- try {
99
- const response = await getPasskeyModule();
100
- return {
101
- publicKeyCredential: makeSerializedGetResponse(typeof response === 'string' ? JSON.parse(response) : response),
102
- error: null,
103
- };
104
- }
105
- catch (error) {
106
- return {
107
- publicKeyCredential: null,
108
- error: mapNativeErrorToClerkWebAuthnErrorCode(error.code, error.message, 'get'),
109
- };
110
- }
111
- }
112
- const ANDROID_9 = 28;
113
- const IOS_15 = 15;
114
- export function isSupported() {
115
- if (Platform.OS === 'android') {
116
- return Platform.Version >= ANDROID_9;
117
- }
118
- if (Platform.OS === 'ios') {
119
- return parseInt(Platform.Version, 10) > IOS_15;
120
- }
121
- return false;
122
- }
123
- // FIX:The autofill function has been implemented for iOS only, but the pop-up is not showing up.
124
- // This seems to be an issue with Expo that we haven't been able to resolve yet.
125
- // Further investigation and possibly reaching out to Expo support may be necessary.
126
- // async function autofill(): Promise<AuthenticationResponseJSON | null> {
127
- // if (Platform.OS === 'android') {
128
- // throw new Error('Not supported');
129
- // } else if (Platform.OS === 'ios') {
130
- // throw new Error('Not supported');
131
- // } else {
132
- // throw new Error('Not supported');
133
- // }
134
- // }
135
- export const passkeys = {
136
- create,
137
- get,
138
- isSupported,
139
- isAutoFillSupported: () => {
140
- throw new Error('Not supported');
141
- },
142
- };
143
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAaxC,OAAO,iBAAiB,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,sCAAsC,EACtC,aAAa,GACd,MAAM,SAAS,CAAC;AAEjB,MAAM,4BAA4B,GAAG,CACnC,gBAA0C,EACe,EAAE,CAAC,CAAC;IAC7D,EAAE,EAAE,gBAAgB,CAAC,EAAE;IACvB,KAAK,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,KAAK,CAAC;IACrD,QAAQ,EAAE;QACR,aAAa,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE,QAAQ,EAAE,UAAsB;QACvE,iBAAiB,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACtF,cAAc,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,cAAc,CAAC;KACjF;IACD,IAAI,EAAE,gBAAgB,CAAC,IAAI;IAC3B,uBAAuB,EAAE,gBAAgB,CAAC,uBAAuB,IAAI,IAAI;IACzE,MAAM,EAAE,GAAG,EAAE,CAAC,gBAAgB;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,SAA8D;IAE9D,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,aAAa,GAAiD;QAClE,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QACpD,IAAI,EAAE;YACJ,EAAE,EAAE,eAAe,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrD,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW;YACvC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI;SAC1B;QACD,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;QAC5C,SAAS,EAAE,eAAe,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9D,sBAAsB,EAAE;YACtB,uBAAuB,EAAE,UAAU;YACnC,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,UAAU;YACvB,gBAAgB,EAAE,UAAU;SAC7B;QACD,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzD,IAAI,EAAE,YAAY;YAClB,EAAE,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACzC,CAAC,CAAC;KACJ,CAAC;IAEF,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC1C,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC5E,GAAG,EAAE,KAAK,IAAI,EAAE,CACd,iBAAiB,CAAC,MAAM,CACtB,aAAa,CAAC,SAAS,EACvB,aAAa,CAAC,EAAE,CAAC,EAAE,EACnB,aAAa,CAAC,IAAI,CAAC,EAAE,EACrB,aAAa,CAAC,IAAI,CAAC,WAAW,CAC/B;QACH,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IAEH,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAC;QAC7C,OAAO;YACL,mBAAmB,EAAE,4BAA4B,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YACjH,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,mBAAmB,EAAE,IAAI;YACzB,KAAK,EAAE,sCAAsC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC;SACnF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,yBAAyB,GAAG,CAChC,mBAA+C,EACQ,EAAE;IACzD,OAAO;QACL,IAAI,EAAE,mBAAmB,CAAC,IAAI;QAC9B,EAAE,EAAE,mBAAmB,CAAC,EAAE;QAC1B,KAAK,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,KAAK,CAAC;QACxD,uBAAuB,EAAE,mBAAmB,EAAE,uBAAuB,IAAI,IAAI;QAC7E,QAAQ,EAAE;YACR,cAAc,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,cAAc,CAAC;YACnF,iBAAiB,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACzF,SAAS,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC;YACzE,UAAU,EAAE,mBAAmB,EAAE,QAAQ,CAAC,UAAU;gBAClD,CAAC,CAAC,sBAAsB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,UAAU,CAAC;gBAClE,CAAC,CAAC,IAAI;SACT;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,mBAAmB;KAClC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,EACxB,gBAAgB,GAGjB;IACC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,0BAA0B,GAAgD;QAC9E,GAAG,gBAAgB;QACnB,SAAS,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,SAAS,CAAC;KAC9D,CAAC;IAEF,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC;QACvC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACtF,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,0BAA0B,CAAC,SAAS,EAAE,0BAA0B,CAAC,IAAI,CAAC;QAC7G,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IAEH,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO;YACL,mBAAmB,EAAE,IAAI;YACzB,KAAK,EAAE,IAAI,kBAAkB,CAAC,2BAA2B,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;SAC9F,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC;QAC1C,OAAO;YACL,mBAAmB,EAAE,yBAAyB,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC9G,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,mBAAmB,EAAE,IAAI;YACzB,KAAK,EAAE,sCAAsC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC;SAChF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,MAAM,GAAG,EAAE,CAAC;AAElB,MAAM,UAAU,WAAW;IACzB,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC,OAAO,IAAI,SAAS,CAAC;IACvC,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC;IACjD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iGAAiG;AACjG,gFAAgF;AAChF,oFAAoF;AAEpF,0EAA0E;AAC1E,qCAAqC;AACrC,wCAAwC;AACxC,wCAAwC;AACxC,wCAAwC;AACxC,aAAa;AACb,wCAAwC;AACxC,MAAM;AACN,IAAI;AAEJ,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,MAAM;IACN,GAAG;IACH,WAAW;IACX,mBAAmB,EAAE,GAAG,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;CACF,CAAC","sourcesContent":["import { Platform } from 'react-native';\n\nimport type {\n AuthenticationResponseJSON,\n CredentialReturn,\n PublicKeyCredentialCreationOptionsWithoutExtensions,\n PublicKeyCredentialRequestOptionsWithoutExtensions,\n PublicKeyCredentialWithAuthenticatorAssertionResponse,\n PublicKeyCredentialWithAuthenticatorAttestationResponse,\n RegistrationResponseJSON,\n SerializedPublicKeyCredentialCreationOptions,\n SerializedPublicKeyCredentialRequestOptions,\n} from './ClerkExpoPasskeys.types';\nimport ClerkExpoPasskeys from './ClerkExpoPasskeysModule';\nimport {\n arrayBufferToBase64Url,\n base64urlToArrayBuffer,\n ClerkWebAuthnError,\n encodeBase64Url,\n mapNativeErrorToClerkWebAuthnErrorCode,\n toArrayBuffer,\n} from './utils';\n\nconst makeSerializedCreateResponse = (\n publicCredential: RegistrationResponseJSON,\n): PublicKeyCredentialWithAuthenticatorAttestationResponse => ({\n id: publicCredential.id,\n rawId: base64urlToArrayBuffer(publicCredential.rawId),\n response: {\n getTransports: () => publicCredential?.response?.transports as string[],\n attestationObject: base64urlToArrayBuffer(publicCredential.response.attestationObject),\n clientDataJSON: base64urlToArrayBuffer(publicCredential.response.clientDataJSON),\n },\n type: publicCredential.type,\n authenticatorAttachment: publicCredential.authenticatorAttachment || null,\n toJSON: () => publicCredential,\n});\n\nexport async function create(\n publicKey: PublicKeyCredentialCreationOptionsWithoutExtensions,\n): Promise<CredentialReturn<PublicKeyCredentialWithAuthenticatorAttestationResponse>> {\n if (!publicKey || !publicKey.rp.id) {\n throw new Error('Invalid public key or RpID');\n }\n\n const createOptions: SerializedPublicKeyCredentialCreationOptions = {\n rp: { id: publicKey.rp.id, name: publicKey.rp.name },\n user: {\n id: encodeBase64Url(toArrayBuffer(publicKey.user.id)),\n displayName: publicKey.user.displayName,\n name: publicKey.user.name,\n },\n pubKeyCredParams: publicKey.pubKeyCredParams,\n challenge: encodeBase64Url(toArrayBuffer(publicKey.challenge)),\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n requireResidentKey: true,\n residentKey: 'required',\n userVerification: 'required',\n },\n excludeCredentials: publicKey.excludeCredentials.map(c => ({\n type: 'public-key',\n id: encodeBase64Url(toArrayBuffer(c.id)),\n })),\n };\n\n const createPasskeyModule = Platform.select({\n android: async () => ClerkExpoPasskeys.create(JSON.stringify(createOptions)),\n ios: async () =>\n ClerkExpoPasskeys.create(\n createOptions.challenge,\n createOptions.rp.id,\n createOptions.user.id,\n createOptions.user.displayName,\n ),\n default: null,\n });\n\n if (!createPasskeyModule) {\n throw new Error('Platform not supported');\n }\n\n try {\n const response = await createPasskeyModule();\n return {\n publicKeyCredential: makeSerializedCreateResponse(typeof response === 'string' ? JSON.parse(response) : response),\n error: null,\n };\n } catch (error) {\n return {\n publicKeyCredential: null,\n error: mapNativeErrorToClerkWebAuthnErrorCode(error.code, error.message, 'create'),\n };\n }\n}\n\nconst makeSerializedGetResponse = (\n publicKeyCredential: AuthenticationResponseJSON,\n): PublicKeyCredentialWithAuthenticatorAssertionResponse => {\n return {\n type: publicKeyCredential.type,\n id: publicKeyCredential.id,\n rawId: base64urlToArrayBuffer(publicKeyCredential.rawId),\n authenticatorAttachment: publicKeyCredential?.authenticatorAttachment || null,\n response: {\n clientDataJSON: base64urlToArrayBuffer(publicKeyCredential.response.clientDataJSON),\n authenticatorData: base64urlToArrayBuffer(publicKeyCredential.response.authenticatorData),\n signature: base64urlToArrayBuffer(publicKeyCredential.response.signature),\n userHandle: publicKeyCredential?.response.userHandle\n ? base64urlToArrayBuffer(publicKeyCredential?.response.userHandle)\n : null,\n },\n toJSON: () => publicKeyCredential,\n };\n};\n\nexport async function get({\n publicKeyOptions,\n}: {\n publicKeyOptions: PublicKeyCredentialRequestOptionsWithoutExtensions;\n}): Promise<CredentialReturn<PublicKeyCredentialWithAuthenticatorAssertionResponse>> {\n if (!publicKeyOptions) {\n throw new Error('publicKeyCredential has not been provided');\n }\n\n const serializedPublicCredential: SerializedPublicKeyCredentialRequestOptions = {\n ...publicKeyOptions,\n challenge: arrayBufferToBase64Url(publicKeyOptions.challenge),\n };\n\n const getPasskeyModule = Platform.select({\n android: async () => ClerkExpoPasskeys.get(JSON.stringify(serializedPublicCredential)),\n ios: async () => ClerkExpoPasskeys.get(serializedPublicCredential.challenge, serializedPublicCredential.rpId),\n default: null,\n });\n\n if (!getPasskeyModule) {\n return {\n publicKeyCredential: null,\n error: new ClerkWebAuthnError('Platform is not supported', { code: 'passkey_not_supported' }),\n };\n }\n\n try {\n const response = await getPasskeyModule();\n return {\n publicKeyCredential: makeSerializedGetResponse(typeof response === 'string' ? JSON.parse(response) : response),\n error: null,\n };\n } catch (error) {\n return {\n publicKeyCredential: null,\n error: mapNativeErrorToClerkWebAuthnErrorCode(error.code, error.message, 'get'),\n };\n }\n}\n\nconst ANDROID_9 = 28;\nconst IOS_15 = 15;\n\nexport function isSupported() {\n if (Platform.OS === 'android') {\n return Platform.Version >= ANDROID_9;\n }\n\n if (Platform.OS === 'ios') {\n return parseInt(Platform.Version, 10) > IOS_15;\n }\n\n return false;\n}\n\n// FIX:The autofill function has been implemented for iOS only, but the pop-up is not showing up.\n// This seems to be an issue with Expo that we haven't been able to resolve yet.\n// Further investigation and possibly reaching out to Expo support may be necessary.\n\n// async function autofill(): Promise<AuthenticationResponseJSON | null> {\n// if (Platform.OS === 'android') {\n// throw new Error('Not supported');\n// } else if (Platform.OS === 'ios') {\n// throw new Error('Not supported');\n// } else {\n// throw new Error('Not supported');\n// }\n// }\n\nexport const passkeys = {\n create,\n get,\n isSupported,\n isAutoFillSupported: () => {\n throw new Error('Not supported');\n },\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,eAAe,UAErE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,eAAe,UAExE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,cAE3C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,OASvC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,cAExC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,UAG9C;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,mBAQvD;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,eAcvD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,KAAA,UAa5C;AAED,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,KAAK,GAAG,QAAQ,GACvB,kBAAkB,CAyBpB"}