faire-auth 1.0.0

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 (221) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +34 -0
  3. package/dist/access-B5bBI4uT.mjs +39 -0
  4. package/dist/access-Crt-IJ2P.cjs +51 -0
  5. package/dist/adapter-factory-BXei1QRX.mjs +881 -0
  6. package/dist/adapter-factory-DT-_2aHJ.cjs +893 -0
  7. package/dist/adapters/drizzle-adapter/index.cjs +208 -0
  8. package/dist/adapters/drizzle-adapter/index.d.cts +48 -0
  9. package/dist/adapters/drizzle-adapter/index.d.mts +48 -0
  10. package/dist/adapters/drizzle-adapter/index.mjs +207 -0
  11. package/dist/adapters/index.cjs +23 -0
  12. package/dist/adapters/index.d.cts +157 -0
  13. package/dist/adapters/index.d.mts +157 -0
  14. package/dist/adapters/index.mjs +17 -0
  15. package/dist/adapters/kysely-adapter/index.cjs +11 -0
  16. package/dist/adapters/kysely-adapter/index.d.cts +52 -0
  17. package/dist/adapters/kysely-adapter/index.d.mts +52 -0
  18. package/dist/adapters/kysely-adapter/index.mjs +9 -0
  19. package/dist/adapters/memory-adapter/index.cjs +9 -0
  20. package/dist/adapters/memory-adapter/index.d.cts +15 -0
  21. package/dist/adapters/memory-adapter/index.d.mts +15 -0
  22. package/dist/adapters/memory-adapter/index.mjs +9 -0
  23. package/dist/adapters/mongodb-adapter/index.cjs +9 -0
  24. package/dist/adapters/mongodb-adapter/index.d.cts +4 -0
  25. package/dist/adapters/mongodb-adapter/index.d.mts +4 -0
  26. package/dist/adapters/mongodb-adapter/index.mjs +9 -0
  27. package/dist/adapters/prisma-adapter/index.cjs +156 -0
  28. package/dist/adapters/prisma-adapter/index.d.cts +35 -0
  29. package/dist/adapters/prisma-adapter/index.d.mts +35 -0
  30. package/dist/adapters/prisma-adapter/index.mjs +155 -0
  31. package/dist/adapters/test.cjs +797 -0
  32. package/dist/adapters/test.d.cts +82 -0
  33. package/dist/adapters/test.d.mts +82 -0
  34. package/dist/adapters/test.mjs +793 -0
  35. package/dist/api/index.cjs +20 -0
  36. package/dist/api/index.d.cts +3 -0
  37. package/dist/api/index.d.mts +3 -0
  38. package/dist/api/index.mjs +20 -0
  39. package/dist/api/middleware/index.cjs +16 -0
  40. package/dist/api/middleware/index.d.cts +16 -0
  41. package/dist/api/middleware/index.d.mts +16 -0
  42. package/dist/api/middleware/index.mjs +11 -0
  43. package/dist/api-Bm89BLgN.cjs +1899 -0
  44. package/dist/api-_B7qO28y.mjs +1892 -0
  45. package/dist/auth-Bo9PDt5j.cjs +739 -0
  46. package/dist/auth-Ds4AG4h4.mjs +709 -0
  47. package/dist/bearer-0SeEmaS4.mjs +54 -0
  48. package/dist/bearer-CHeREcGT.cjs +60 -0
  49. package/dist/bun-sqlite-dialect-CfkBo2v5.mjs +155 -0
  50. package/dist/bun-sqlite-dialect-wuaC2-gh.cjs +156 -0
  51. package/dist/chunk-Ceigfy4P.mjs +39 -0
  52. package/dist/chunk-oakRccI5.cjs +60 -0
  53. package/dist/client/index.cjs +22 -0
  54. package/dist/client/index.d.cts +8 -0
  55. package/dist/client/index.d.mts +8 -0
  56. package/dist/client/index.mjs +19 -0
  57. package/dist/client/lynx/index.cjs +79 -0
  58. package/dist/client/lynx/index.d.cts +156 -0
  59. package/dist/client/lynx/index.d.mts +156 -0
  60. package/dist/client/lynx/index.mjs +76 -0
  61. package/dist/client/plugins/index.cjs +11 -0
  62. package/dist/client/plugins/index.d.cts +17 -0
  63. package/dist/client/plugins/index.d.mts +17 -0
  64. package/dist/client/plugins/index.mjs +10 -0
  65. package/dist/client/react/index.cjs +79 -0
  66. package/dist/client/react/index.d.cts +156 -0
  67. package/dist/client/react/index.d.mts +156 -0
  68. package/dist/client/react/index.mjs +76 -0
  69. package/dist/client/solid/index.cjs +51 -0
  70. package/dist/client/solid/index.d.cts +90 -0
  71. package/dist/client/solid/index.d.mts +90 -0
  72. package/dist/client/solid/index.mjs +50 -0
  73. package/dist/client/svelte/index.cjs +28 -0
  74. package/dist/client/svelte/index.d.cts +110 -0
  75. package/dist/client/svelte/index.d.mts +110 -0
  76. package/dist/client/svelte/index.mjs +28 -0
  77. package/dist/client/vue/index.cjs +68 -0
  78. package/dist/client/vue/index.d.cts +123 -0
  79. package/dist/client/vue/index.d.mts +123 -0
  80. package/dist/client/vue/index.mjs +67 -0
  81. package/dist/cookies-B5xeA6i8.cjs +456 -0
  82. package/dist/cookies-Ch1JfQIz.mjs +367 -0
  83. package/dist/crypto/index.cjs +11 -0
  84. package/dist/crypto/index.d.cts +22 -0
  85. package/dist/crypto/index.d.mts +22 -0
  86. package/dist/crypto/index.mjs +5 -0
  87. package/dist/crypto-CcTxYH82.cjs +57 -0
  88. package/dist/crypto-CyQRFtkq.mjs +41 -0
  89. package/dist/db/index.cjs +40 -0
  90. package/dist/db/index.d.cts +4 -0
  91. package/dist/db/index.d.mts +4 -0
  92. package/dist/db/index.mjs +16 -0
  93. package/dist/db-BTKyYu-_.cjs +1180 -0
  94. package/dist/db-xiJtoDgz.mjs +1119 -0
  95. package/dist/defu-B0Svx_x4.cjs +34 -0
  96. package/dist/defu-SZkpHhbR.mjs +28 -0
  97. package/dist/email-verification-C-AsfJsb.cjs +247 -0
  98. package/dist/email-verification-CWhj2qfb.mjs +228 -0
  99. package/dist/hono-BEq1NYVX.cjs +526 -0
  100. package/dist/hono-Cdukwu5K.cjs +13 -0
  101. package/dist/hono-CoKYWnXA.mjs +7 -0
  102. package/dist/hono-Covz10jU.mjs +508 -0
  103. package/dist/hono-DOM31WQz.d.cts +18 -0
  104. package/dist/hono-DuE14mmj.d.mts +18 -0
  105. package/dist/index-B-WeOMzg.d.cts +13350 -0
  106. package/dist/index-B09P9p5_.d.cts +33 -0
  107. package/dist/index-B5_0QTLg.d.mts +3 -0
  108. package/dist/index-B7SKyR_a.d.cts +3 -0
  109. package/dist/index-BVHscLQl.d.cts +992 -0
  110. package/dist/index-C2-2QDyS.d.cts +35 -0
  111. package/dist/index-CTwrVluH.d.mts +41 -0
  112. package/dist/index-CWAqWfoZ.d.cts +27 -0
  113. package/dist/index-CYSShrFx.d.mts +27 -0
  114. package/dist/index-Qu-iJGNr.d.mts +992 -0
  115. package/dist/index-cs4Sh0En.d.cts +41 -0
  116. package/dist/index-jlessPI0.d.mts +13350 -0
  117. package/dist/index-ppgcFe12.d.mts +33 -0
  118. package/dist/index-to0RO38U.d.mts +35 -0
  119. package/dist/index.cjs +85 -0
  120. package/dist/index.d.cts +5 -0
  121. package/dist/index.d.mts +5 -0
  122. package/dist/index.mjs +27 -0
  123. package/dist/integrations/next-js.cjs +50 -0
  124. package/dist/integrations/next-js.d.cts +23 -0
  125. package/dist/integrations/next-js.d.mts +23 -0
  126. package/dist/integrations/next-js.mjs +49 -0
  127. package/dist/integrations/node.cjs +139 -0
  128. package/dist/integrations/node.d.cts +22 -0
  129. package/dist/integrations/node.d.mts +22 -0
  130. package/dist/integrations/node.mjs +134 -0
  131. package/dist/integrations/react-start.cjs +37 -0
  132. package/dist/integrations/react-start.d.cts +17 -0
  133. package/dist/integrations/react-start.d.mts +17 -0
  134. package/dist/integrations/react-start.mjs +37 -0
  135. package/dist/integrations/solid-start.cjs +14 -0
  136. package/dist/integrations/solid-start.d.cts +13 -0
  137. package/dist/integrations/solid-start.d.mts +13 -0
  138. package/dist/integrations/solid-start.mjs +13 -0
  139. package/dist/integrations/svelte-kit.cjs +52 -0
  140. package/dist/integrations/svelte-kit.d.cts +42 -0
  141. package/dist/integrations/svelte-kit.d.mts +42 -0
  142. package/dist/integrations/svelte-kit.mjs +49 -0
  143. package/dist/ip-B5SwXaMB.cjs +54 -0
  144. package/dist/ip-BjNYspCH.mjs +36 -0
  145. package/dist/json-B1v2qRTQ.mjs +24 -0
  146. package/dist/json-CcJ2HjGo.cjs +30 -0
  147. package/dist/kysely-adapter-Bxi7sPdG.cjs +288 -0
  148. package/dist/kysely-adapter-DRuoT_X8.mjs +270 -0
  149. package/dist/logged-CyGfp8_H.mjs +187 -0
  150. package/dist/logged-DQK3C64b.cjs +193 -0
  151. package/dist/memory-adapter-BlnDIAAX.cjs +154 -0
  152. package/dist/memory-adapter-Db3tsJTn.mjs +148 -0
  153. package/dist/middleware-CE6OhDkq.mjs +29 -0
  154. package/dist/middleware-CWvRH4EW.cjs +47 -0
  155. package/dist/mongodb-adapter-C_qGQED5.mjs +291 -0
  156. package/dist/mongodb-adapter-C_qfK87x.cjs +297 -0
  157. package/dist/node-sqlite-dialect-BfBzyOAg.mjs +155 -0
  158. package/dist/node-sqlite-dialect-mJWC8LWQ.cjs +156 -0
  159. package/dist/oauth2/index.cjs +25 -0
  160. package/dist/oauth2/index.d.cts +42 -0
  161. package/dist/oauth2/index.d.mts +42 -0
  162. package/dist/oauth2/index.mjs +16 -0
  163. package/dist/oauth2-B8M0lW9l.mjs +159 -0
  164. package/dist/oauth2-BLeOEi7Y.cjs +177 -0
  165. package/dist/origin-check-8Gajklvh.mjs +228 -0
  166. package/dist/origin-check-id9lTnqZ.cjs +246 -0
  167. package/dist/parser-CdncAl9i.cjs +83 -0
  168. package/dist/parser-CeAer-RM.mjs +71 -0
  169. package/dist/passkey-B6N20LSS.cjs +512 -0
  170. package/dist/passkey-DJsR_GX3.mjs +505 -0
  171. package/dist/plugins/access/index.cjs +4 -0
  172. package/dist/plugins/access/index.d.cts +2 -0
  173. package/dist/plugins/access/index.d.mts +2 -0
  174. package/dist/plugins/access/index.mjs +3 -0
  175. package/dist/plugins/bearer/index.cjs +7 -0
  176. package/dist/plugins/bearer/index.d.cts +4 -0
  177. package/dist/plugins/bearer/index.d.mts +4 -0
  178. package/dist/plugins/bearer/index.mjs +7 -0
  179. package/dist/plugins/index.cjs +49 -0
  180. package/dist/plugins/index.d.cts +9326 -0
  181. package/dist/plugins/index.d.mts +9326 -0
  182. package/dist/plugins/index.mjs +26 -0
  183. package/dist/plugins/passkey/index.cjs +15 -0
  184. package/dist/plugins/passkey/index.d.cts +4 -0
  185. package/dist/plugins/passkey/index.d.mts +4 -0
  186. package/dist/plugins/passkey/index.mjs +15 -0
  187. package/dist/plugins-C1lm2Wj3.cjs +5254 -0
  188. package/dist/plugins-Dai1QkRU.mjs +5199 -0
  189. package/dist/request-1NL_1lyJ.mjs +58 -0
  190. package/dist/request-CPNlp-DK.cjs +100 -0
  191. package/dist/schema-D-qjygfE.cjs +179 -0
  192. package/dist/schema-DTIwLLmf.mjs +125 -0
  193. package/dist/session-De9POJTW.cjs +641 -0
  194. package/dist/session-rH8ougDl.mjs +538 -0
  195. package/dist/social-providers/index.cjs +10 -0
  196. package/dist/social-providers/index.d.cts +2 -0
  197. package/dist/social-providers/index.d.mts +2 -0
  198. package/dist/social-providers/index.mjs +5 -0
  199. package/dist/social-providers-DcFNUT0S.cjs +13 -0
  200. package/dist/social-providers-DoYJhBe3.mjs +9 -0
  201. package/dist/state--f7fwIGh.cjs +99 -0
  202. package/dist/state-CqJfCIl9.mjs +86 -0
  203. package/dist/test-utils/index.cjs +27492 -0
  204. package/dist/test-utils/index.d.cts +4584 -0
  205. package/dist/test-utils/index.d.mts +4584 -0
  206. package/dist/test-utils/index.mjs +27490 -0
  207. package/dist/types/index.cjs +0 -0
  208. package/dist/types/index.d.cts +3 -0
  209. package/dist/types/index.d.mts +3 -0
  210. package/dist/types/index.mjs +1 -0
  211. package/dist/url-BoUuoIwZ.mjs +88 -0
  212. package/dist/url-D2yvKaM7.cjs +118 -0
  213. package/dist/utils/cookies.cjs +51 -0
  214. package/dist/utils/cookies.d.cts +179 -0
  215. package/dist/utils/cookies.d.mts +179 -0
  216. package/dist/utils/cookies.mjs +7 -0
  217. package/dist/utils-44aDDP8f.cjs +2 -0
  218. package/dist/utils-D4vZd1-9.mjs +4 -0
  219. package/dist/vanilla-Bu2PmFzE.cjs +30 -0
  220. package/dist/vanilla-TfHqeiC7.mjs +25 -0
  221. package/package.json +470 -0
@@ -0,0 +1,83 @@
1
+
2
+ //#region src/client/parser.ts
3
+ const PROTO_POLLUTION_PATTERNS = {
4
+ proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
5
+ constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
6
+ protoShort: /"__proto__"\s*:/,
7
+ constructorShort: /"constructor"\s*:/
8
+ };
9
+ const JSON_SIGNATURE = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
10
+ const SPECIAL_VALUES = {
11
+ true: true,
12
+ false: false,
13
+ null: null,
14
+ undefined: void 0,
15
+ nan: NaN,
16
+ infinity: Number.POSITIVE_INFINITY,
17
+ "-infinity": Number.NEGATIVE_INFINITY
18
+ };
19
+ const ISO_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(?:Z|([+-])(\d{2}):(\d{2}))$/;
20
+ const isValidDate = (date) => date instanceof Date && !Number.isNaN(date.getTime());
21
+ const parseISODate = (value) => {
22
+ const match = ISO_DATE_REGEX.exec(value);
23
+ if (!match) return null;
24
+ const [, year, month, day, hour, minute, second, ms, offsetSign, offsetHour, offsetMinute] = match;
25
+ if (year == null || month == null || day == null || hour == null || minute == null || second == null) return null;
26
+ const date = new Date(Date.UTC(Number.parseInt(year, 10), Number.parseInt(month, 10) - 1, Number.parseInt(day, 10), Number.parseInt(hour, 10), Number.parseInt(minute, 10), Number.parseInt(second, 10), ms != null ? Number.parseInt(ms.padEnd(3, "0"), 10) : 0));
27
+ if (offsetSign != null) {
28
+ if (offsetHour == null || offsetMinute == null) return null;
29
+ const offset = (Number.parseInt(offsetHour, 10) * 60 + Number.parseInt(offsetMinute, 10)) * (offsetSign === "+" ? -1 : 1);
30
+ date.setUTCMinutes(date.getUTCMinutes() + offset);
31
+ }
32
+ return isValidDate(date) ? date : null;
33
+ };
34
+ const betterJSONParse = (value, options = {}) => {
35
+ const { strict = false, warnings = false, reviver, parseDates = true } = options;
36
+ if (typeof value !== "string") return value;
37
+ const trimmed = value.trim();
38
+ if (trimmed.startsWith("\"") && trimmed.endsWith("\"") && !trimmed.slice(1, -1).includes("\"")) return trimmed.slice(1, -1);
39
+ const lowerValue = trimmed.toLowerCase();
40
+ if (lowerValue.length <= 9 && lowerValue in SPECIAL_VALUES) return SPECIAL_VALUES[lowerValue];
41
+ if (!JSON_SIGNATURE.test(trimmed)) {
42
+ if (strict) throw new SyntaxError("[better-json] Invalid JSON");
43
+ return value;
44
+ }
45
+ if (Object.entries(PROTO_POLLUTION_PATTERNS).some(([key, pattern]) => {
46
+ const matches = pattern.test(trimmed);
47
+ if (matches && warnings) console.warn(`[better-json] Detected potential prototype pollution attempt using ${key} pattern`);
48
+ return matches;
49
+ }) && strict) throw new Error("[better-json] Potential prototype pollution attempt detected");
50
+ try {
51
+ const secureReviver = (key, value$1) => {
52
+ if (key === "__proto__" || key === "constructor" && value$1 != null && typeof value$1 === "object" && "prototype" in value$1) {
53
+ if (warnings) console.warn(`[better-json] Dropping "${key}" key to prevent prototype pollution`);
54
+ return;
55
+ }
56
+ if (parseDates && typeof value$1 === "string") {
57
+ const date = parseISODate(value$1);
58
+ if (date) return date;
59
+ }
60
+ return reviver ? reviver(key, value$1) : value$1;
61
+ };
62
+ return JSON.parse(trimmed, secureReviver);
63
+ } catch (error) {
64
+ if (strict) throw error;
65
+ return value;
66
+ }
67
+ };
68
+ const parseJSON = (value, options = { strict: true }) => betterJSONParse(value, options);
69
+ var parser_default = parseJSON;
70
+
71
+ //#endregion
72
+ Object.defineProperty(exports, 'parseJSON', {
73
+ enumerable: true,
74
+ get: function () {
75
+ return parseJSON;
76
+ }
77
+ });
78
+ Object.defineProperty(exports, 'parser_default', {
79
+ enumerable: true,
80
+ get: function () {
81
+ return parser_default;
82
+ }
83
+ });
@@ -0,0 +1,71 @@
1
+ //#region src/client/parser.ts
2
+ const PROTO_POLLUTION_PATTERNS = {
3
+ proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
4
+ constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
5
+ protoShort: /"__proto__"\s*:/,
6
+ constructorShort: /"constructor"\s*:/
7
+ };
8
+ const JSON_SIGNATURE = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
9
+ const SPECIAL_VALUES = {
10
+ true: true,
11
+ false: false,
12
+ null: null,
13
+ undefined: void 0,
14
+ nan: NaN,
15
+ infinity: Number.POSITIVE_INFINITY,
16
+ "-infinity": Number.NEGATIVE_INFINITY
17
+ };
18
+ const ISO_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(?:Z|([+-])(\d{2}):(\d{2}))$/;
19
+ const isValidDate = (date) => date instanceof Date && !Number.isNaN(date.getTime());
20
+ const parseISODate = (value) => {
21
+ const match = ISO_DATE_REGEX.exec(value);
22
+ if (!match) return null;
23
+ const [, year, month, day, hour, minute, second, ms, offsetSign, offsetHour, offsetMinute] = match;
24
+ if (year == null || month == null || day == null || hour == null || minute == null || second == null) return null;
25
+ const date = new Date(Date.UTC(Number.parseInt(year, 10), Number.parseInt(month, 10) - 1, Number.parseInt(day, 10), Number.parseInt(hour, 10), Number.parseInt(minute, 10), Number.parseInt(second, 10), ms != null ? Number.parseInt(ms.padEnd(3, "0"), 10) : 0));
26
+ if (offsetSign != null) {
27
+ if (offsetHour == null || offsetMinute == null) return null;
28
+ const offset = (Number.parseInt(offsetHour, 10) * 60 + Number.parseInt(offsetMinute, 10)) * (offsetSign === "+" ? -1 : 1);
29
+ date.setUTCMinutes(date.getUTCMinutes() + offset);
30
+ }
31
+ return isValidDate(date) ? date : null;
32
+ };
33
+ const betterJSONParse = (value, options = {}) => {
34
+ const { strict = false, warnings = false, reviver, parseDates = true } = options;
35
+ if (typeof value !== "string") return value;
36
+ const trimmed = value.trim();
37
+ if (trimmed.startsWith("\"") && trimmed.endsWith("\"") && !trimmed.slice(1, -1).includes("\"")) return trimmed.slice(1, -1);
38
+ const lowerValue = trimmed.toLowerCase();
39
+ if (lowerValue.length <= 9 && lowerValue in SPECIAL_VALUES) return SPECIAL_VALUES[lowerValue];
40
+ if (!JSON_SIGNATURE.test(trimmed)) {
41
+ if (strict) throw new SyntaxError("[better-json] Invalid JSON");
42
+ return value;
43
+ }
44
+ if (Object.entries(PROTO_POLLUTION_PATTERNS).some(([key, pattern]) => {
45
+ const matches = pattern.test(trimmed);
46
+ if (matches && warnings) console.warn(`[better-json] Detected potential prototype pollution attempt using ${key} pattern`);
47
+ return matches;
48
+ }) && strict) throw new Error("[better-json] Potential prototype pollution attempt detected");
49
+ try {
50
+ const secureReviver = (key, value$1) => {
51
+ if (key === "__proto__" || key === "constructor" && value$1 != null && typeof value$1 === "object" && "prototype" in value$1) {
52
+ if (warnings) console.warn(`[better-json] Dropping "${key}" key to prevent prototype pollution`);
53
+ return;
54
+ }
55
+ if (parseDates && typeof value$1 === "string") {
56
+ const date = parseISODate(value$1);
57
+ if (date) return date;
58
+ }
59
+ return reviver ? reviver(key, value$1) : value$1;
60
+ };
61
+ return JSON.parse(trimmed, secureReviver);
62
+ } catch (error) {
63
+ if (strict) throw error;
64
+ return value;
65
+ }
66
+ };
67
+ const parseJSON = (value, options = { strict: true }) => betterJSONParse(value, options);
68
+ var parser_default = parseJSON;
69
+
70
+ //#endregion
71
+ export { parser_default as n, parseJSON as t };
@@ -0,0 +1,512 @@
1
+ const require_chunk = require('./chunk-oakRccI5.cjs');
2
+ const require_cookies = require('./cookies-B5xeA6i8.cjs');
3
+ const require_session = require('./session-De9POJTW.cjs');
4
+ const require_schema = require('./schema-D-qjygfE.cjs');
5
+ let __faire_auth_core_env = require("@faire-auth/core/env");
6
+ let __faire_auth_core_factory = require("@faire-auth/core/factory");
7
+ let __faire_auth_core_static = require("@faire-auth/core/static");
8
+ let __faire_auth_core_utils = require("@faire-auth/core/utils");
9
+ let __faire_auth_core_datatypes = require("@faire-auth/core/datatypes");
10
+ let zod = require("zod");
11
+ zod = require_chunk.__toESM(zod);
12
+ let __simplewebauthn_server = require("@simplewebauthn/server");
13
+ let __faire_auth_core_crypto = require("@faire-auth/core/crypto");
14
+
15
+ //#region src/plugins/passkey/index.ts
16
+ const getRpID = (options, baseURL) => options.rpID || (baseURL ? new URL(baseURL).hostname : "localhost");
17
+ const passkeySchema = zod.object({
18
+ id: zod.string(),
19
+ name: zod.string().optional(),
20
+ publicKey: zod.string(),
21
+ userId: zod.string(),
22
+ credentialID: zod.string(),
23
+ counter: zod.number().int().nonnegative(),
24
+ deviceType: zod.enum(["singleDevice", "multiDevice"]),
25
+ backedUp: zod.boolean(),
26
+ transports: zod.string().optional(),
27
+ createdAt: zod.date().or(zod.iso.datetime()),
28
+ aaguid: zod.string().optional()
29
+ });
30
+ const passkey = (options) => {
31
+ const opts = {
32
+ origin: null,
33
+ ...options,
34
+ advanced: {
35
+ webAuthnChallengeCookie: "better-auth-passkey",
36
+ ...options?.advanced
37
+ }
38
+ };
39
+ const expirationTime = new Date(Date.now() + 1e3 * 60 * 5);
40
+ const currentTime = /* @__PURE__ */ new Date();
41
+ const maxAgeInSeconds = Math.floor((expirationTime.getTime() - currentTime.getTime()) / 1e3);
42
+ const ERROR_CODES = {
43
+ CHALLENGE_NOT_FOUND: "Challenge not found",
44
+ YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: "You are not allowed to register this passkey",
45
+ FAILED_TO_VERIFY_REGISTRATION: "Failed to verify registration",
46
+ PASSKEY_NOT_FOUND: "Passkey not found",
47
+ AUTHENTICATION_FAILED: "Authentication failed",
48
+ UNABLE_TO_CREATE_SESSION: "Unable to create session",
49
+ FAILED_TO_UPDATE_PASSKEY: "Failed to update passkey"
50
+ };
51
+ return {
52
+ id: "passkey",
53
+ routes: {
54
+ generatePasskeyRegistrationOptions: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
55
+ operationId: "generatePasskeyRegistrationOptions",
56
+ method: "get",
57
+ path: "/passkey/generate-register-options",
58
+ client: false,
59
+ description: "Generate registration options for a new passkey",
60
+ middleware: [require_session.freshSessionMiddleware],
61
+ request: (0, __faire_auth_core_factory.req)().qry(zod.object({
62
+ authenticatorAttachment: zod.enum(["platform", "cross-platform"]).optional().openapi({ description: `Type of authenticator to use for registration.
63
+ "platform" for device-specific authenticators,
64
+ "cross-platform" for authenticators that can be used across devices.` }),
65
+ name: zod.string().optional().openapi({ description: `Optional custom name for the passkey.
66
+ This can help identify the passkey when managing multiple credentials.` })
67
+ })).bld(),
68
+ responses: (0, __faire_auth_core_factory.res)(zod.object({
69
+ challenge: zod.base64url(),
70
+ timeout: zod.number().optional(),
71
+ rp: zod.object({
72
+ name: zod.string(),
73
+ id: zod.string().optional()
74
+ }),
75
+ user: zod.object({
76
+ id: zod.string(),
77
+ name: zod.string(),
78
+ displayName: zod.string()
79
+ }),
80
+ pubKeyCredParams: zod.array(zod.object({
81
+ type: zod.string(),
82
+ alg: zod.number()
83
+ })),
84
+ excludeCredentials: zod.array(zod.object({
85
+ id: zod.string(),
86
+ type: zod.string(),
87
+ transports: zod.array(zod.enum([
88
+ "ble",
89
+ "cable",
90
+ "hybrid",
91
+ "internal",
92
+ "nfc",
93
+ "smart-card",
94
+ "usb"
95
+ ])).optional()
96
+ })).optional(),
97
+ authenticatorSelection: zod.object({
98
+ authenticatorAttachment: zod.string(),
99
+ requireResidentKey: zod.boolean(),
100
+ userVerification: zod.string()
101
+ }).partial().optional(),
102
+ attestation: zod.string(),
103
+ extensions: zod.record(zod.string(), zod.any())
104
+ }).transform(__faire_auth_core_utils.toSuccess)).err(401).bld()
105
+ }), (authOptions) => async (ctx) => {
106
+ const session = ctx.get("session");
107
+ const { name, authenticatorAttachment } = ctx.req.valid("query");
108
+ const userPasskeys = await ctx.get("context").adapter.findMany({
109
+ model: "passkey",
110
+ where: [{
111
+ field: "userId",
112
+ value: session.user.id
113
+ }]
114
+ });
115
+ const userID = new TextEncoder().encode((0, __faire_auth_core_crypto.generateRandomString)(32, "a-z", "0-9"));
116
+ let options$1;
117
+ options$1 = await (0, __simplewebauthn_server.generateRegistrationOptions)({
118
+ rpName: opts.rpName || ctx.get("context").appName,
119
+ rpID: getRpID(opts, authOptions.baseURL),
120
+ userID,
121
+ userName: name ?? session.user.email ?? session.user.id,
122
+ userDisplayName: session.user.email ?? session.user.id,
123
+ attestationType: "none",
124
+ excludeCredentials: userPasskeys.map((passkey$1) => ({
125
+ id: passkey$1.credentialID,
126
+ transports: passkey$1.transports?.split(",")
127
+ })),
128
+ authenticatorSelection: {
129
+ residentKey: "preferred",
130
+ userVerification: "preferred",
131
+ ...opts.authenticatorSelection ?? {},
132
+ ...authenticatorAttachment && { authenticatorAttachment }
133
+ }
134
+ });
135
+ const id = (0, __faire_auth_core_crypto.generateId)(32);
136
+ const webAuthnCookie = ctx.get("context").createAuthCookie(opts.advanced.webAuthnChallengeCookie);
137
+ await (0, require_cookies.cookies_exports.setSignedCookie)(ctx, webAuthnCookie.name, id, ctx.get("context").secret, {
138
+ ...webAuthnCookie.attributes,
139
+ maxAge: maxAgeInSeconds
140
+ });
141
+ await ctx.get("context").internalAdapter.createVerificationValue({
142
+ identifier: id,
143
+ value: JSON.stringify({
144
+ expectedChallenge: options$1.challenge,
145
+ userData: { id: session.user.id }
146
+ }),
147
+ expiresAt: expirationTime
148
+ });
149
+ return ctx.render(options$1, 200);
150
+ }),
151
+ generatePasskeyAuthenticationOptions: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
152
+ operationId: "generatePasskeyAuthenticationOptions",
153
+ method: "post",
154
+ path: "/passkey/generate-authenticate-options",
155
+ description: "Generate authentication options for a passkey",
156
+ request: (0, __faire_auth_core_factory.req)().bdy(zod.object({ email: __faire_auth_core_factory.emailSchema.openapi({ description: "The email address of the user" }).optional() })).bld(),
157
+ responses: (0, __faire_auth_core_factory.res)(zod.object({
158
+ challenge: zod.base64url(),
159
+ timeout: zod.number().optional(),
160
+ rpId: zod.string().optional(),
161
+ allowCredentials: zod.array(zod.object({
162
+ id: zod.string(),
163
+ type: zod.string(),
164
+ transports: zod.array(zod.enum([
165
+ "ble",
166
+ "cable",
167
+ "hybrid",
168
+ "internal",
169
+ "nfc",
170
+ "smart-card",
171
+ "usb"
172
+ ])).optional()
173
+ })).optional(),
174
+ userVerification: zod.enum([
175
+ "discouraged",
176
+ "preferred",
177
+ "required"
178
+ ]).optional(),
179
+ extensions: zod.record(zod.string(), zod.any()).optional()
180
+ }).transform(__faire_auth_core_utils.toSuccess)).bld()
181
+ }), (authOptions) => async (ctx) => {
182
+ const session = await require_session.getSessionFromCtx(ctx);
183
+ let userPasskeys = [];
184
+ if (!(session instanceof Response)) userPasskeys = await ctx.get("context").adapter.findMany({
185
+ model: "passkey",
186
+ where: [{
187
+ field: "userId",
188
+ value: session.user.id
189
+ }]
190
+ });
191
+ const options$1 = await (0, __simplewebauthn_server.generateAuthenticationOptions)({
192
+ rpID: getRpID(opts, authOptions.baseURL),
193
+ userVerification: "preferred",
194
+ ...userPasskeys.length > 0 && { allowCredentials: userPasskeys.map((passkey$1) => ({
195
+ id: passkey$1.credentialID,
196
+ transports: passkey$1.transports?.split(",")
197
+ })) }
198
+ });
199
+ const data = {
200
+ expectedChallenge: options$1.challenge,
201
+ userData: { id: "user" in session ? session.user.id : "" }
202
+ };
203
+ const id = (0, __faire_auth_core_crypto.generateId)(32);
204
+ const webAuthnCookie = ctx.get("context").createAuthCookie(opts.advanced.webAuthnChallengeCookie);
205
+ await (0, require_cookies.cookies_exports.setSignedCookie)(ctx, webAuthnCookie.name, id, ctx.get("context").secret, {
206
+ ...webAuthnCookie.attributes,
207
+ maxAge: maxAgeInSeconds
208
+ });
209
+ await ctx.get("context").internalAdapter.createVerificationValue({
210
+ identifier: id,
211
+ value: JSON.stringify(data),
212
+ expiresAt: expirationTime
213
+ });
214
+ return ctx.render(options$1, 200);
215
+ }),
216
+ verifyPasskeyRegistration: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
217
+ operationId: "verifyPasskeyRegistration",
218
+ method: "post",
219
+ path: "/passkey/verify-registration",
220
+ description: "Verify registration of a new passkey",
221
+ middleware: [require_session.freshSessionMiddleware],
222
+ request: (0, __faire_auth_core_factory.req)().bdy(zod.object({
223
+ response: zod.any(),
224
+ name: zod.string().openapi({ description: "Name of the passkey" }).optional()
225
+ })).bld(),
226
+ responses: (0, __faire_auth_core_factory.res)(passkeySchema.transform(__faire_auth_core_utils.toSuccess)).err(400).err(401).err(500, "Failed to verify registration").bld()
227
+ }), (authOptions) => async (ctx) => {
228
+ const origin = options?.origin ?? ctx.req.header("origin") ?? "";
229
+ if (!origin) return ctx.render({ success: __faire_auth_core_static.False }, 400);
230
+ const session = ctx.get("session");
231
+ const { response } = ctx.req.valid("json");
232
+ const webAuthnCookie = ctx.get("context").createAuthCookie(opts.advanced.webAuthnChallengeCookie);
233
+ const challengeId = await (0, require_cookies.cookies_exports.getSignedCookie)(ctx, ctx.get("context").secret, webAuthnCookie.name);
234
+ if (!challengeId) return ctx.render({
235
+ success: __faire_auth_core_static.False,
236
+ message: ERROR_CODES.CHALLENGE_NOT_FOUND
237
+ }, 400);
238
+ const data = await ctx.get("context").internalAdapter.findVerificationValue(challengeId);
239
+ if (!data) return ctx.render({
240
+ success: __faire_auth_core_static.False,
241
+ message: ERROR_CODES.FAILED_TO_VERIFY_REGISTRATION
242
+ }, 400);
243
+ const { expectedChallenge, userData } = JSON.parse(data.value);
244
+ if (userData.id !== session.user.id) return ctx.render({
245
+ success: __faire_auth_core_static.False,
246
+ message: ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY
247
+ }, 401);
248
+ try {
249
+ const { verified, registrationInfo } = await (0, __simplewebauthn_server.verifyRegistrationResponse)({
250
+ response,
251
+ expectedChallenge,
252
+ expectedOrigin: origin,
253
+ expectedRPID: getRpID(opts, authOptions.baseURL),
254
+ requireUserVerification: false
255
+ });
256
+ if (!verified || !registrationInfo) return ctx.render({
257
+ success: __faire_auth_core_static.False,
258
+ message: ERROR_CODES.FAILED_TO_VERIFY_REGISTRATION
259
+ }, 400);
260
+ const { aaguid, credentialDeviceType, credentialBackedUp, credential } = registrationInfo;
261
+ const pubKey = __faire_auth_core_datatypes.base64.encode(credential.publicKey);
262
+ const newPasskey = {
263
+ name: ctx.body.name,
264
+ userId: userData.id,
265
+ credentialID: credential.id,
266
+ publicKey: pubKey,
267
+ counter: credential.counter,
268
+ deviceType: credentialDeviceType,
269
+ transports: response.response.transports.join(","),
270
+ backedUp: credentialBackedUp,
271
+ createdAt: /* @__PURE__ */ new Date(),
272
+ aaguid
273
+ };
274
+ const newPasskeyRes = await ctx.get("context").adapter.create({
275
+ model: "passkey",
276
+ data: newPasskey
277
+ });
278
+ return ctx.render(newPasskeyRes, 200);
279
+ } catch (e) {
280
+ __faire_auth_core_env.logger.error(String(e));
281
+ return ctx.render({
282
+ success: __faire_auth_core_static.False,
283
+ message: ERROR_CODES.FAILED_TO_VERIFY_REGISTRATION
284
+ }, 500);
285
+ }
286
+ }),
287
+ verifyPasskeyAuthentication: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
288
+ operationId: "verifyPasskeyAuthentication",
289
+ method: "post",
290
+ path: "/passkey/verify-authentication",
291
+ description: "Verify authentication of a passkey",
292
+ $Infer: { body: {} },
293
+ request: (0, __faire_auth_core_factory.req)().bdy(zod.object({ response: zod.record(zod.string(), zod.any()) })).bld(),
294
+ responses: (0, __faire_auth_core_factory.res)(__faire_auth_core_static.SCHEMAS[__faire_auth_core_static.Definitions.SESSION_RESPONSE].default).err(400, "Origin missing, challenge not found, or auth failed").err(401, "Passkey not found or auth failed").err(500, "User not found or unable to create session").bld()
295
+ }), (authOptions) => async (ctx) => {
296
+ const origin = options?.origin ?? ctx.req.header("origin") ?? "";
297
+ if (!origin) return ctx.render({
298
+ success: __faire_auth_core_static.False,
299
+ message: "Origin missing"
300
+ }, 400);
301
+ const { response } = ctx.req.valid("json");
302
+ const webAuthnCookie = ctx.get("context").createAuthCookie(opts.advanced.webAuthnChallengeCookie);
303
+ const challengeId = await (0, require_cookies.cookies_exports.getSignedCookie)(ctx, ctx.get("context").secret, webAuthnCookie.name);
304
+ if (!challengeId) return ctx.render({
305
+ success: __faire_auth_core_static.False,
306
+ message: ERROR_CODES.CHALLENGE_NOT_FOUND
307
+ }, 400);
308
+ const data = await ctx.get("context").internalAdapter.findVerificationValue(challengeId);
309
+ if (!data) return ctx.render({
310
+ success: __faire_auth_core_static.False,
311
+ message: ERROR_CODES.CHALLENGE_NOT_FOUND
312
+ }, 400);
313
+ const { expectedChallenge } = JSON.parse(data.value);
314
+ const passkey$1 = await ctx.get("context").adapter.findOne({
315
+ model: "passkey",
316
+ where: [{
317
+ field: "credentialID",
318
+ value: response["id"]
319
+ }]
320
+ });
321
+ if (!passkey$1) return ctx.render({
322
+ success: __faire_auth_core_static.False,
323
+ message: ERROR_CODES.PASSKEY_NOT_FOUND
324
+ }, 401);
325
+ try {
326
+ const verification = await (0, __simplewebauthn_server.verifyAuthenticationResponse)({
327
+ response,
328
+ expectedChallenge,
329
+ expectedOrigin: origin,
330
+ expectedRPID: getRpID(opts, authOptions.baseURL),
331
+ credential: {
332
+ id: passkey$1.credentialID,
333
+ publicKey: __faire_auth_core_datatypes.base64.decode(passkey$1.publicKey),
334
+ counter: passkey$1.counter,
335
+ transports: passkey$1.transports?.split(",")
336
+ },
337
+ requireUserVerification: false
338
+ });
339
+ const { verified } = verification;
340
+ if (!verified) return ctx.render({
341
+ success: __faire_auth_core_static.False,
342
+ message: ERROR_CODES.AUTHENTICATION_FAILED
343
+ }, 401);
344
+ await ctx.get("context").adapter.update({
345
+ model: "passkey",
346
+ where: [{
347
+ field: "id",
348
+ value: passkey$1.id
349
+ }],
350
+ update: { counter: verification.authenticationInfo.newCounter }
351
+ });
352
+ const s = await ctx.get("context").internalAdapter.createSession(passkey$1.userId);
353
+ if (!s) return ctx.render({
354
+ success: __faire_auth_core_static.False,
355
+ message: ERROR_CODES.UNABLE_TO_CREATE_SESSION
356
+ }, 500);
357
+ const user = await ctx.get("context").internalAdapter.findUserById(passkey$1.userId);
358
+ if (!user) return ctx.render({
359
+ success: __faire_auth_core_static.False,
360
+ message: "User not found"
361
+ }, 500);
362
+ await require_cookies.setSessionCookie(ctx, authOptions, {
363
+ session: s,
364
+ user
365
+ });
366
+ return ctx.render(s, 200);
367
+ } catch (e) {
368
+ ctx.get("context").logger.error("Failed to verify authentication", e);
369
+ return ctx.render({
370
+ success: __faire_auth_core_static.False,
371
+ message: ERROR_CODES.AUTHENTICATION_FAILED
372
+ }, 400);
373
+ }
374
+ }),
375
+ listPasskeys: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
376
+ operationId: "listPasskeys",
377
+ method: "get",
378
+ path: "/passkey/list-user-passkeys",
379
+ description: "List all passkeys for the authenticated user",
380
+ middleware: [require_session.sessionMiddleware()],
381
+ responses: (0, __faire_auth_core_factory.res)(zod.array(passkeySchema).openapi({ description: "Array of passkey objects associated with the user" }).transform(__faire_auth_core_utils.toSuccess)).err(401).bld()
382
+ }), (_authOptions) => async (ctx) => {
383
+ const session = ctx.get("session");
384
+ const passkeys = await ctx.get("context").adapter.findMany({
385
+ model: "passkey",
386
+ where: [{
387
+ field: "userId",
388
+ value: session.user.id
389
+ }]
390
+ });
391
+ return ctx.render(passkeys, 200);
392
+ }),
393
+ deletePasskey: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
394
+ operationId: "deletePasskey",
395
+ method: "post",
396
+ path: "/passkey/delete-passkey",
397
+ description: "Delete a specific passkey",
398
+ middleware: [require_session.sessionMiddleware()],
399
+ request: (0, __faire_auth_core_factory.req)().bdy(zod.object({ id: zod.string().openapi({ description: "The ID of the passkey to delete. Eg: \"some-passkey-id\"" }) })).bld(),
400
+ responses: (0, __faire_auth_core_factory.res)(__faire_auth_core_static.SCHEMAS[__faire_auth_core_static.Definitions.SUCCESS].default, "Passkey deleted successfully").err(401).bld()
401
+ }), (_authOptions) => async (ctx) => {
402
+ await ctx.get("context").adapter.delete({
403
+ model: "passkey",
404
+ where: [{
405
+ field: "id",
406
+ value: ctx.req.valid("json").id
407
+ }]
408
+ });
409
+ return ctx.render({ success: __faire_auth_core_static.True }, 200);
410
+ }),
411
+ updatePasskey: require_session.createEndpoint((0, __faire_auth_core_factory.createRoute)({
412
+ operationId: "updatePasskey",
413
+ method: "post",
414
+ path: "/passkey/update-passkey",
415
+ description: "Update a specific passkey's name",
416
+ middleware: [require_session.sessionMiddleware()],
417
+ request: (0, __faire_auth_core_factory.req)().bdy(zod.object({
418
+ id: zod.string().openapi({ description: `The ID of the passkey which will be updated. Eg: \"passkey-id\"` }),
419
+ name: zod.string().openapi({ description: `The new name which the passkey will be updated to. Eg: \"my-new-passkey-name\"` })
420
+ })).bld(),
421
+ responses: (0, __faire_auth_core_factory.res)(passkeySchema.transform(__faire_auth_core_utils.toSuccess)).err(401, "Invalid session or not allowed to register").err(404, "Passkey not found").err(500, "Failed to update passkey").bld()
422
+ }), (_authOptions) => async (ctx) => {
423
+ const session = ctx.get("session");
424
+ const { id, name } = ctx.req.valid("json");
425
+ const passkey$1 = await ctx.get("context").adapter.findOne({
426
+ model: "passkey",
427
+ where: [{
428
+ field: "id",
429
+ value: id
430
+ }]
431
+ });
432
+ if (!passkey$1) return ctx.render({
433
+ success: __faire_auth_core_static.False,
434
+ message: ERROR_CODES.PASSKEY_NOT_FOUND
435
+ }, 404);
436
+ if (passkey$1.userId !== session.user.id) return ctx.render({
437
+ success: __faire_auth_core_static.False,
438
+ message: ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY
439
+ }, 401);
440
+ const updatedPasskey = await ctx.get("context").adapter.update({
441
+ model: "passkey",
442
+ where: [{
443
+ field: "id",
444
+ value: id
445
+ }],
446
+ update: { name }
447
+ });
448
+ if (!updatedPasskey) return ctx.render({
449
+ success: __faire_auth_core_static.False,
450
+ message: ERROR_CODES.FAILED_TO_UPDATE_PASSKEY
451
+ }, 500);
452
+ return ctx.render(updatedPasskey, 200);
453
+ })
454
+ },
455
+ schema: require_schema.mergeSchema(schema, options?.schema),
456
+ $ERROR_CODES: ERROR_CODES
457
+ };
458
+ };
459
+ const schema = { passkey: { fields: {
460
+ name: {
461
+ type: "string",
462
+ required: false
463
+ },
464
+ publicKey: {
465
+ type: "string",
466
+ required: true
467
+ },
468
+ userId: {
469
+ type: "string",
470
+ references: {
471
+ model: "user",
472
+ field: "id"
473
+ },
474
+ required: true
475
+ },
476
+ credentialID: {
477
+ type: "string",
478
+ required: true
479
+ },
480
+ counter: {
481
+ type: "number",
482
+ required: true
483
+ },
484
+ deviceType: {
485
+ type: "string",
486
+ required: true
487
+ },
488
+ backedUp: {
489
+ type: "boolean",
490
+ required: true
491
+ },
492
+ transports: {
493
+ type: "string",
494
+ required: false
495
+ },
496
+ createdAt: {
497
+ type: "date",
498
+ required: false
499
+ },
500
+ aaguid: {
501
+ type: "string",
502
+ required: false
503
+ }
504
+ } } };
505
+
506
+ //#endregion
507
+ Object.defineProperty(exports, 'passkey', {
508
+ enumerable: true,
509
+ get: function () {
510
+ return passkey;
511
+ }
512
+ });