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,177 @@
1
+ const require_chunk = require('./chunk-oakRccI5.cjs');
2
+ const require_crypto = require('./crypto-CcTxYH82.cjs');
3
+ const require_email_verification = require('./email-verification-C-AsfJsb.cjs');
4
+ let __faire_auth_core_env = require("@faire-auth/core/env");
5
+ let __faire_auth_core_error = require("@faire-auth/core/error");
6
+
7
+ //#region src/oauth2/utils.ts
8
+ const decryptOAuthToken = (token, ctx, options) => {
9
+ if (!token) return token;
10
+ if (options.account?.encryptOAuthTokens) return (0, require_crypto.crypto_exports.symmetricDecrypt)({
11
+ key: ctx.get("context").secret,
12
+ data: token
13
+ });
14
+ return token;
15
+ };
16
+ const setTokenUtil = (token, ctx, options) => {
17
+ if (options.account?.encryptOAuthTokens && token) return (0, require_crypto.crypto_exports.symmetricEncrypt)({
18
+ key: ctx.get("context").secret,
19
+ data: token
20
+ });
21
+ return token;
22
+ };
23
+
24
+ //#endregion
25
+ //#region src/oauth2/link-account.ts
26
+ const handleOAuthUserInfo = async (ctx, { userInfo, account, callbackURL, disableSignUp, overrideUserInfo }, options) => {
27
+ const context = ctx.get("context");
28
+ const redirectOnError = (reason) => {
29
+ const errorURL = options.onAPIError?.errorURL ?? `${context.baseURL}/error`;
30
+ return {
31
+ type: "redirect",
32
+ response: ctx.redirect(`${errorURL}?error=${reason}`, 302)
33
+ };
34
+ };
35
+ const dbUser = await context.internalAdapter.findOAuthUser(userInfo.email.toLowerCase(), account.accountId, account.providerId).catch((e) => {
36
+ __faire_auth_core_env.logger.error("Better auth was unable to query your database.\nError: ", e);
37
+ return "error";
38
+ });
39
+ if (dbUser === "error") return redirectOnError("internal_server_error");
40
+ let user = dbUser?.user ?? null;
41
+ const isRegister = user == null;
42
+ if (dbUser) {
43
+ const hasBeenLinked = dbUser.accounts.find((a) => a.providerId === account.providerId && a.accountId === account.accountId);
44
+ if (!hasBeenLinked) {
45
+ if (!(options.account?.accountLinking?.trustedProviders)?.includes(account.providerId) && !userInfo.emailVerified || options.account?.accountLinking?.enabled === false) {
46
+ if ((0, __faire_auth_core_env.isDevelopment)()) __faire_auth_core_env.logger.warn(`User already exist but account isn't linked to ${account.providerId}. To read more about how account linking works in Faire Auth see https://www.faire-auth.com/docs/concepts/users-accounts#account-linking.`);
47
+ return {
48
+ type: "error",
49
+ reason: "account_not_linked"
50
+ };
51
+ }
52
+ try {
53
+ await context.internalAdapter.linkAccount({
54
+ providerId: account.providerId,
55
+ accountId: userInfo.id.toString(),
56
+ userId: dbUser.user.id,
57
+ accessToken: await setTokenUtil(account.accessToken, ctx, options),
58
+ refreshToken: await setTokenUtil(account.refreshToken, ctx, options),
59
+ idToken: account.idToken,
60
+ accessTokenExpiresAt: account.accessTokenExpiresAt,
61
+ refreshTokenExpiresAt: account.refreshTokenExpiresAt,
62
+ scope: account.scope
63
+ });
64
+ } catch (e) {
65
+ __faire_auth_core_env.logger.error("Unable to link account", e);
66
+ return {
67
+ type: "error",
68
+ reason: "unable_to_link_account"
69
+ };
70
+ }
71
+ if (userInfo.emailVerified && !dbUser.user.emailVerified && userInfo.email.toLowerCase() === dbUser.user.email) await context.internalAdapter.updateUser(dbUser.user.id, { emailVerified: true });
72
+ } else {
73
+ if (options.account?.updateAccountOnSignIn !== false) {
74
+ const updateData = Object.fromEntries(Object.entries({
75
+ idToken: account.idToken,
76
+ accessToken: await setTokenUtil(account.accessToken, ctx, options),
77
+ refreshToken: await setTokenUtil(account.refreshToken, ctx, options),
78
+ accessTokenExpiresAt: account.accessTokenExpiresAt,
79
+ refreshTokenExpiresAt: account.refreshTokenExpiresAt,
80
+ scope: account.scope
81
+ }).filter(([, value]) => value !== void 0 && value !== ""));
82
+ if (Object.keys(updateData).length > 0) await context.internalAdapter.updateAccount(hasBeenLinked.id, updateData);
83
+ }
84
+ if (userInfo.emailVerified && !dbUser.user.emailVerified && userInfo.email.toLowerCase() === dbUser.user.email) await context.internalAdapter.updateUser(dbUser.user.id, { emailVerified: true });
85
+ }
86
+ if (overrideUserInfo === true) {
87
+ const { id: _,...restUserInfo } = userInfo;
88
+ await context.internalAdapter.updateUser(dbUser.user.id, {
89
+ ...restUserInfo,
90
+ email: userInfo.email.toLowerCase(),
91
+ emailVerified: userInfo.email.toLowerCase() === dbUser.user.email ? dbUser.user.emailVerified || userInfo.emailVerified : userInfo.emailVerified
92
+ });
93
+ }
94
+ } else {
95
+ if (disableSignUp === true) return {
96
+ type: "error",
97
+ reason: "signup_disabled",
98
+ isRegister: false
99
+ };
100
+ try {
101
+ const { id: _,...restUserInfo } = userInfo;
102
+ user = await context.internalAdapter.createOAuthUser({
103
+ ...restUserInfo,
104
+ email: userInfo.email.toLowerCase()
105
+ }, {
106
+ accessToken: await setTokenUtil(account.accessToken, ctx, options),
107
+ refreshToken: await setTokenUtil(account.refreshToken, ctx, options),
108
+ idToken: account.idToken,
109
+ accessTokenExpiresAt: account.accessTokenExpiresAt,
110
+ refreshTokenExpiresAt: account.refreshTokenExpiresAt,
111
+ scope: account.scope,
112
+ providerId: account.providerId,
113
+ accountId: userInfo.id.toString()
114
+ }).then((res) => res.user);
115
+ if (!userInfo.emailVerified && user && options.emailVerification?.sendOnSignUp === true) {
116
+ const token = await require_email_verification.createEmailVerificationToken(context.secret, user.email, void 0, options.emailVerification.expiresIn);
117
+ const url = `${context.baseURL}/verify-email?token=${token}${callbackURL ? `&callbackURL=${callbackURL}` : ""}`;
118
+ await options.emailVerification.sendVerificationEmail?.({
119
+ user,
120
+ url,
121
+ token
122
+ }, ctx);
123
+ }
124
+ } catch (e) {
125
+ __faire_auth_core_env.logger.error(e instanceof Error ? e.message : String(e), e);
126
+ if (e instanceof __faire_auth_core_error.APIError) return {
127
+ type: "error",
128
+ reason: e.message,
129
+ isRegister: false
130
+ };
131
+ return {
132
+ type: "error",
133
+ reason: "unable_to_create_user",
134
+ isRegister: false
135
+ };
136
+ }
137
+ }
138
+ if (!user) return {
139
+ type: "error",
140
+ reason: "unable_to_create_user",
141
+ isRegister: false
142
+ };
143
+ const session = await context.internalAdapter.createSession(user.id);
144
+ if (!session) return {
145
+ type: "error",
146
+ reason: "unable_to_create_session",
147
+ isRegister: false
148
+ };
149
+ return {
150
+ type: "success",
151
+ data: {
152
+ session,
153
+ user
154
+ },
155
+ isRegister
156
+ };
157
+ };
158
+
159
+ //#endregion
160
+ Object.defineProperty(exports, 'decryptOAuthToken', {
161
+ enumerable: true,
162
+ get: function () {
163
+ return decryptOAuthToken;
164
+ }
165
+ });
166
+ Object.defineProperty(exports, 'handleOAuthUserInfo', {
167
+ enumerable: true,
168
+ get: function () {
169
+ return handleOAuthUserInfo;
170
+ }
171
+ });
172
+ Object.defineProperty(exports, 'setTokenUtil', {
173
+ enumerable: true,
174
+ get: function () {
175
+ return setTokenUtil;
176
+ }
177
+ });
@@ -0,0 +1,228 @@
1
+ import { a as getTrustedOrigins, i as getProtocol, n as getHost, r as getOrigin } from "./url-BoUuoIwZ.mjs";
2
+ import { r as createMiddleware } from "./middleware-CE6OhDkq.mjs";
3
+ import { logger } from "@faire-auth/core/env";
4
+ import { False, isPromise } from "@faire-auth/core/static";
5
+
6
+ //#region src/utils/wildcard.ts
7
+ /**
8
+ * Escapes a character if it has a special meaning in regular expressions
9
+ * and returns the character as is if it doesn't
10
+ */
11
+ const escapeRegExpChar = (char) => {
12
+ if (char === "-" || char === "^" || char === "$" || char === "+" || char === "." || char === "(" || char === ")" || char === "|" || char === "[" || char === "]" || char === "{" || char === "}" || char === "*" || char === "?" || char === "\\") return `\\${char}`;
13
+ return char;
14
+ };
15
+ /**
16
+ * Escapes all characters in a given string that have a special meaning in regular expressions
17
+ */
18
+ const escapeRegExpString = (str) => {
19
+ let result = "";
20
+ for (const char of str) result += escapeRegExpChar(char);
21
+ return result;
22
+ };
23
+ /**
24
+ * Transforms one or more glob patterns into a RegExp pattern
25
+ */
26
+ const transform = (pattern, separator = true) => {
27
+ if (Array.isArray(pattern)) return `(?:${pattern.map((p) => `^${transform(p, separator)}$`).join("|")})`;
28
+ const truthySeparator = typeof separator === "string" || separator;
29
+ let separatorSplitter = "";
30
+ let separatorMatcher = "";
31
+ let wildcard = ".";
32
+ if (separator === true) {
33
+ separatorSplitter = "/";
34
+ separatorMatcher = "[/\\\\]";
35
+ wildcard = "[^/\\\\]";
36
+ } else if (typeof separator === "string") {
37
+ separatorSplitter = separator;
38
+ separatorMatcher = escapeRegExpString(separatorSplitter);
39
+ if (separatorMatcher.length > 1) {
40
+ separatorMatcher = `(?:${separatorMatcher})`;
41
+ wildcard = `((?!${separatorMatcher}).)`;
42
+ } else wildcard = `[^${separatorMatcher}]`;
43
+ }
44
+ const requiredSeparator = truthySeparator ? `${separatorMatcher}+?` : "";
45
+ const optionalSeparator = truthySeparator ? `${separatorMatcher}*?` : "";
46
+ const segments = truthySeparator ? pattern.split(separatorSplitter) : [pattern];
47
+ let result = "";
48
+ for (let s = 0; s < segments.length; s++) {
49
+ const segment = segments[s];
50
+ const nextSegment = segments[s + 1];
51
+ let currentSeparator = "";
52
+ if (segment == null && s > 0) continue;
53
+ if (truthySeparator) if (s === segments.length - 1) currentSeparator = optionalSeparator;
54
+ else if (nextSegment !== "**") currentSeparator = requiredSeparator;
55
+ else currentSeparator = "";
56
+ if (truthySeparator && segment === "**") {
57
+ if (currentSeparator) {
58
+ result += s === 0 ? "" : currentSeparator;
59
+ result += `(?:${wildcard}*?${currentSeparator})*?`;
60
+ }
61
+ continue;
62
+ }
63
+ if (segment != null) for (let c = 0; c < segment.length; c++) {
64
+ const char = segment[c];
65
+ switch (char) {
66
+ case "\\":
67
+ if (c < segment.length - 1) {
68
+ result += escapeRegExpChar(segment[c + 1]);
69
+ c++;
70
+ }
71
+ break;
72
+ case "?":
73
+ result += wildcard;
74
+ break;
75
+ case "*":
76
+ result += `${wildcard}*?`;
77
+ break;
78
+ default: if (char != null) result += escapeRegExpChar(char);
79
+ }
80
+ }
81
+ result += currentSeparator;
82
+ }
83
+ return result;
84
+ };
85
+ const isMatch = (regexp, sample) => {
86
+ if (typeof sample !== "string") throw new TypeError(`Sample must be a string, but ${typeof sample} given`);
87
+ return regexp.test(sample);
88
+ };
89
+ /**
90
+ * Compiles one or more glob patterns into a RegExp and returns an isMatch function.
91
+ * The isMatch function takes a sample string as its only argument and returns `true`
92
+ * if the string matches the pattern(s).
93
+ *
94
+ * ```js
95
+ * wildcardMatch('src/*.js')('src/index.js') //=> true
96
+ * ```
97
+ *
98
+ * ```js
99
+ * const isMatch = wildcardMatch('*.example.com', '.')
100
+ * isMatch('foo.example.com') //=> true
101
+ * isMatch('foo.bar.com') //=> false
102
+ * ```
103
+ */
104
+ function wildcardMatch(pattern, options) {
105
+ if (typeof pattern !== "string" && !Array.isArray(pattern)) throw new TypeError(`The first argument must be a single pattern string or an array of patterns, but ${typeof pattern} given`);
106
+ if (typeof options === "string" || typeof options === "boolean") options = { separator: options };
107
+ if (arguments.length === 2 && !(typeof options === "undefined" || typeof options === "object" && options !== null && !Array.isArray(options))) throw new TypeError(`The second argument must be an options object or a string/boolean separator, but ${typeof options} given`);
108
+ options = options ?? {};
109
+ if (options.separator === "\\") throw new Error("\\ is not a valid separator because it is used for escaping. Try setting the separator to `true` instead");
110
+ const regexpPattern = transform(pattern, options.separator);
111
+ const regexp = new RegExp(`^${regexpPattern}$`, options.flags);
112
+ const fn = isMatch.bind(null, regexp);
113
+ fn.options = options;
114
+ fn.pattern = pattern;
115
+ fn.regexp = regexp;
116
+ return fn;
117
+ }
118
+
119
+ //#endregion
120
+ //#region src/api/middleware/origin-check.ts
121
+ const RELATIVE_PATH_RE = /^\/(?!\/|\\|%2f|%5c)[\w\-.\+/@]*(?:\?[\w\-.\+/=&%@]*)?$/;
122
+ const matchesPattern = (url, pattern) => {
123
+ if (url.startsWith("/")) return false;
124
+ if (pattern.includes("*")) {
125
+ if (pattern.includes("://")) return wildcardMatch(pattern)(getOrigin(url) || url);
126
+ return wildcardMatch(pattern)(getHost(url));
127
+ }
128
+ const protocol = getProtocol(url);
129
+ return protocol === "http:" || protocol === "https:" || !protocol ? pattern === getOrigin(url) : url.startsWith(pattern);
130
+ };
131
+ const validateURL = (url, label, trustedOrigins, logger$1, ctx) => {
132
+ if (url == null) return null;
133
+ let isTrustedOrigin = false;
134
+ trustedOrigins.forEach((origin) => {
135
+ if (isTrustedOrigin === false && (matchesPattern(url, origin) || url.startsWith("/") && label !== "origin" && RELATIVE_PATH_RE.test(url))) isTrustedOrigin = true;
136
+ });
137
+ if (!isTrustedOrigin) {
138
+ logger$1.error(`Invalid ${label}: ${url}`);
139
+ logger$1.info(`If it's a valid URL, please add ${url} to trustedOrigins in your auth config\n`, `Current list of trustedOrigins: ${[...trustedOrigins].join(", ")}`);
140
+ return ctx.json({
141
+ success: False,
142
+ message: `Invalid ${label}`
143
+ }, 403);
144
+ }
145
+ return null;
146
+ };
147
+ /**
148
+ * A middleware to validate callbackURL and origin against
149
+ * trustedOrigins.
150
+ */
151
+ const initOriginCheckMiddleware = (options, context) => {
152
+ const log = {
153
+ info: (message, ...args) => options.logger?.log?.("info", message, ...args) ?? logger.info,
154
+ error: (message, ...args) => options.logger?.log?.("error", message, ...args) ?? logger.error
155
+ };
156
+ return createMiddleware()(async (ctx, next) => {
157
+ if (ctx.get("isServer") === true || ctx.req.method !== "POST") return await next();
158
+ const needsBody = [
159
+ "POST",
160
+ "PUT",
161
+ "PATCH"
162
+ ].includes(ctx.req.method);
163
+ const usesCookies = ctx.req.header("cookie") != null;
164
+ const originHeader = ctx.req.header("origin") ?? ctx.req.header("referer");
165
+ const queryCallbackURL = ctx.req.query("callbackURL");
166
+ const { ready, dynamicPromise, trustedOrigins } = getTrustedOrigins(options, context, ctx.req);
167
+ let body = null;
168
+ if (needsBody) try {
169
+ body = await ctx.req.raw.clone().json();
170
+ } catch {}
171
+ const callbackURL = body?.callbackURL ?? queryCallbackURL;
172
+ const redirectURL = body?.redirectTo;
173
+ const errorCallbackURL = body?.errorCallbackURL;
174
+ const newUserCallbackURL = body?.newUserCallbackURL;
175
+ let ret = null;
176
+ if (usesCookies && !options.advanced?.disableCSRFCheck) {
177
+ if (!ready) await dynamicPromise;
178
+ ret = validateURL(originHeader, "origin", trustedOrigins, log, ctx);
179
+ if (ret) return ret;
180
+ }
181
+ if (callbackURL != null) {
182
+ if (!ready) await dynamicPromise;
183
+ ret = validateURL(callbackURL, "callbackURL", trustedOrigins, log, ctx);
184
+ if (ret) return ret;
185
+ }
186
+ if (redirectURL != null) {
187
+ if (!ready) await dynamicPromise;
188
+ ret = validateURL(redirectURL, "redirectURL", trustedOrigins, log, ctx);
189
+ if (ret) return ret;
190
+ }
191
+ if (errorCallbackURL != null) {
192
+ if (!ready) await dynamicPromise;
193
+ ret = validateURL(errorCallbackURL, "errorCallbackURL", trustedOrigins, log, ctx);
194
+ if (ret) return ret;
195
+ }
196
+ if (newUserCallbackURL != null) {
197
+ if (!ready) await dynamicPromise;
198
+ ret = validateURL(newUserCallbackURL, "newUserCallbackURL", trustedOrigins, log, ctx);
199
+ if (ret) return ret;
200
+ }
201
+ return await next();
202
+ });
203
+ };
204
+ /**
205
+ * Validates callback URLs against trusted origins.
206
+ * @template V - The context variables type.
207
+ * @param getValue - Function to get the callback URL(s) from the context.
208
+ * @returns The middleware function.
209
+ */
210
+ const originCheck = (getValue) => {
211
+ return createMiddleware()(async (ctx, next) => {
212
+ if (ctx.get("isServer") === true) return await next();
213
+ const context = ctx.get("context");
214
+ let callbackURL = getValue(ctx);
215
+ if (isPromise(callbackURL)) callbackURL = await callbackURL;
216
+ if (!callbackURL) return await next();
217
+ const callbacks = Array.isArray(callbackURL) ? callbackURL : [callbackURL];
218
+ let ret;
219
+ for (const url of callbacks) {
220
+ ret = validateURL(url, "callbackURL", context.trustedOrigins, context.logger, ctx);
221
+ if (ret) return ret;
222
+ }
223
+ return await next();
224
+ });
225
+ };
226
+
227
+ //#endregion
228
+ export { originCheck as n, wildcardMatch as r, initOriginCheckMiddleware as t };
@@ -0,0 +1,246 @@
1
+ const require_chunk = require('./chunk-oakRccI5.cjs');
2
+ const require_url = require('./url-D2yvKaM7.cjs');
3
+ const require_middleware = require('./middleware-CWvRH4EW.cjs');
4
+ let __faire_auth_core_env = require("@faire-auth/core/env");
5
+ let __faire_auth_core_static = require("@faire-auth/core/static");
6
+
7
+ //#region src/utils/wildcard.ts
8
+ /**
9
+ * Escapes a character if it has a special meaning in regular expressions
10
+ * and returns the character as is if it doesn't
11
+ */
12
+ const escapeRegExpChar = (char) => {
13
+ if (char === "-" || char === "^" || char === "$" || char === "+" || char === "." || char === "(" || char === ")" || char === "|" || char === "[" || char === "]" || char === "{" || char === "}" || char === "*" || char === "?" || char === "\\") return `\\${char}`;
14
+ return char;
15
+ };
16
+ /**
17
+ * Escapes all characters in a given string that have a special meaning in regular expressions
18
+ */
19
+ const escapeRegExpString = (str) => {
20
+ let result = "";
21
+ for (const char of str) result += escapeRegExpChar(char);
22
+ return result;
23
+ };
24
+ /**
25
+ * Transforms one or more glob patterns into a RegExp pattern
26
+ */
27
+ const transform = (pattern, separator = true) => {
28
+ if (Array.isArray(pattern)) return `(?:${pattern.map((p) => `^${transform(p, separator)}$`).join("|")})`;
29
+ const truthySeparator = typeof separator === "string" || separator;
30
+ let separatorSplitter = "";
31
+ let separatorMatcher = "";
32
+ let wildcard = ".";
33
+ if (separator === true) {
34
+ separatorSplitter = "/";
35
+ separatorMatcher = "[/\\\\]";
36
+ wildcard = "[^/\\\\]";
37
+ } else if (typeof separator === "string") {
38
+ separatorSplitter = separator;
39
+ separatorMatcher = escapeRegExpString(separatorSplitter);
40
+ if (separatorMatcher.length > 1) {
41
+ separatorMatcher = `(?:${separatorMatcher})`;
42
+ wildcard = `((?!${separatorMatcher}).)`;
43
+ } else wildcard = `[^${separatorMatcher}]`;
44
+ }
45
+ const requiredSeparator = truthySeparator ? `${separatorMatcher}+?` : "";
46
+ const optionalSeparator = truthySeparator ? `${separatorMatcher}*?` : "";
47
+ const segments = truthySeparator ? pattern.split(separatorSplitter) : [pattern];
48
+ let result = "";
49
+ for (let s = 0; s < segments.length; s++) {
50
+ const segment = segments[s];
51
+ const nextSegment = segments[s + 1];
52
+ let currentSeparator = "";
53
+ if (segment == null && s > 0) continue;
54
+ if (truthySeparator) if (s === segments.length - 1) currentSeparator = optionalSeparator;
55
+ else if (nextSegment !== "**") currentSeparator = requiredSeparator;
56
+ else currentSeparator = "";
57
+ if (truthySeparator && segment === "**") {
58
+ if (currentSeparator) {
59
+ result += s === 0 ? "" : currentSeparator;
60
+ result += `(?:${wildcard}*?${currentSeparator})*?`;
61
+ }
62
+ continue;
63
+ }
64
+ if (segment != null) for (let c = 0; c < segment.length; c++) {
65
+ const char = segment[c];
66
+ switch (char) {
67
+ case "\\":
68
+ if (c < segment.length - 1) {
69
+ result += escapeRegExpChar(segment[c + 1]);
70
+ c++;
71
+ }
72
+ break;
73
+ case "?":
74
+ result += wildcard;
75
+ break;
76
+ case "*":
77
+ result += `${wildcard}*?`;
78
+ break;
79
+ default: if (char != null) result += escapeRegExpChar(char);
80
+ }
81
+ }
82
+ result += currentSeparator;
83
+ }
84
+ return result;
85
+ };
86
+ const isMatch = (regexp, sample) => {
87
+ if (typeof sample !== "string") throw new TypeError(`Sample must be a string, but ${typeof sample} given`);
88
+ return regexp.test(sample);
89
+ };
90
+ /**
91
+ * Compiles one or more glob patterns into a RegExp and returns an isMatch function.
92
+ * The isMatch function takes a sample string as its only argument and returns `true`
93
+ * if the string matches the pattern(s).
94
+ *
95
+ * ```js
96
+ * wildcardMatch('src/*.js')('src/index.js') //=> true
97
+ * ```
98
+ *
99
+ * ```js
100
+ * const isMatch = wildcardMatch('*.example.com', '.')
101
+ * isMatch('foo.example.com') //=> true
102
+ * isMatch('foo.bar.com') //=> false
103
+ * ```
104
+ */
105
+ function wildcardMatch(pattern, options) {
106
+ if (typeof pattern !== "string" && !Array.isArray(pattern)) throw new TypeError(`The first argument must be a single pattern string or an array of patterns, but ${typeof pattern} given`);
107
+ if (typeof options === "string" || typeof options === "boolean") options = { separator: options };
108
+ if (arguments.length === 2 && !(typeof options === "undefined" || typeof options === "object" && options !== null && !Array.isArray(options))) throw new TypeError(`The second argument must be an options object or a string/boolean separator, but ${typeof options} given`);
109
+ options = options ?? {};
110
+ if (options.separator === "\\") throw new Error("\\ is not a valid separator because it is used for escaping. Try setting the separator to `true` instead");
111
+ const regexpPattern = transform(pattern, options.separator);
112
+ const regexp = new RegExp(`^${regexpPattern}$`, options.flags);
113
+ const fn = isMatch.bind(null, regexp);
114
+ fn.options = options;
115
+ fn.pattern = pattern;
116
+ fn.regexp = regexp;
117
+ return fn;
118
+ }
119
+
120
+ //#endregion
121
+ //#region src/api/middleware/origin-check.ts
122
+ const RELATIVE_PATH_RE = /^\/(?!\/|\\|%2f|%5c)[\w\-.\+/@]*(?:\?[\w\-.\+/=&%@]*)?$/;
123
+ const matchesPattern = (url, pattern) => {
124
+ if (url.startsWith("/")) return false;
125
+ if (pattern.includes("*")) {
126
+ if (pattern.includes("://")) return wildcardMatch(pattern)(require_url.getOrigin(url) || url);
127
+ return wildcardMatch(pattern)(require_url.getHost(url));
128
+ }
129
+ const protocol = require_url.getProtocol(url);
130
+ return protocol === "http:" || protocol === "https:" || !protocol ? pattern === require_url.getOrigin(url) : url.startsWith(pattern);
131
+ };
132
+ const validateURL = (url, label, trustedOrigins, logger$1, ctx) => {
133
+ if (url == null) return null;
134
+ let isTrustedOrigin = false;
135
+ trustedOrigins.forEach((origin) => {
136
+ if (isTrustedOrigin === false && (matchesPattern(url, origin) || url.startsWith("/") && label !== "origin" && RELATIVE_PATH_RE.test(url))) isTrustedOrigin = true;
137
+ });
138
+ if (!isTrustedOrigin) {
139
+ logger$1.error(`Invalid ${label}: ${url}`);
140
+ logger$1.info(`If it's a valid URL, please add ${url} to trustedOrigins in your auth config\n`, `Current list of trustedOrigins: ${[...trustedOrigins].join(", ")}`);
141
+ return ctx.json({
142
+ success: __faire_auth_core_static.False,
143
+ message: `Invalid ${label}`
144
+ }, 403);
145
+ }
146
+ return null;
147
+ };
148
+ /**
149
+ * A middleware to validate callbackURL and origin against
150
+ * trustedOrigins.
151
+ */
152
+ const initOriginCheckMiddleware = (options, context) => {
153
+ const log = {
154
+ info: (message, ...args) => options.logger?.log?.("info", message, ...args) ?? __faire_auth_core_env.logger.info,
155
+ error: (message, ...args) => options.logger?.log?.("error", message, ...args) ?? __faire_auth_core_env.logger.error
156
+ };
157
+ return require_middleware.createMiddleware()(async (ctx, next) => {
158
+ if (ctx.get("isServer") === true || ctx.req.method !== "POST") return await next();
159
+ const needsBody = [
160
+ "POST",
161
+ "PUT",
162
+ "PATCH"
163
+ ].includes(ctx.req.method);
164
+ const usesCookies = ctx.req.header("cookie") != null;
165
+ const originHeader = ctx.req.header("origin") ?? ctx.req.header("referer");
166
+ const queryCallbackURL = ctx.req.query("callbackURL");
167
+ const { ready, dynamicPromise, trustedOrigins } = require_url.getTrustedOrigins(options, context, ctx.req);
168
+ let body = null;
169
+ if (needsBody) try {
170
+ body = await ctx.req.raw.clone().json();
171
+ } catch {}
172
+ const callbackURL = body?.callbackURL ?? queryCallbackURL;
173
+ const redirectURL = body?.redirectTo;
174
+ const errorCallbackURL = body?.errorCallbackURL;
175
+ const newUserCallbackURL = body?.newUserCallbackURL;
176
+ let ret = null;
177
+ if (usesCookies && !options.advanced?.disableCSRFCheck) {
178
+ if (!ready) await dynamicPromise;
179
+ ret = validateURL(originHeader, "origin", trustedOrigins, log, ctx);
180
+ if (ret) return ret;
181
+ }
182
+ if (callbackURL != null) {
183
+ if (!ready) await dynamicPromise;
184
+ ret = validateURL(callbackURL, "callbackURL", trustedOrigins, log, ctx);
185
+ if (ret) return ret;
186
+ }
187
+ if (redirectURL != null) {
188
+ if (!ready) await dynamicPromise;
189
+ ret = validateURL(redirectURL, "redirectURL", trustedOrigins, log, ctx);
190
+ if (ret) return ret;
191
+ }
192
+ if (errorCallbackURL != null) {
193
+ if (!ready) await dynamicPromise;
194
+ ret = validateURL(errorCallbackURL, "errorCallbackURL", trustedOrigins, log, ctx);
195
+ if (ret) return ret;
196
+ }
197
+ if (newUserCallbackURL != null) {
198
+ if (!ready) await dynamicPromise;
199
+ ret = validateURL(newUserCallbackURL, "newUserCallbackURL", trustedOrigins, log, ctx);
200
+ if (ret) return ret;
201
+ }
202
+ return await next();
203
+ });
204
+ };
205
+ /**
206
+ * Validates callback URLs against trusted origins.
207
+ * @template V - The context variables type.
208
+ * @param getValue - Function to get the callback URL(s) from the context.
209
+ * @returns The middleware function.
210
+ */
211
+ const originCheck = (getValue) => {
212
+ return require_middleware.createMiddleware()(async (ctx, next) => {
213
+ if (ctx.get("isServer") === true) return await next();
214
+ const context = ctx.get("context");
215
+ let callbackURL = getValue(ctx);
216
+ if ((0, __faire_auth_core_static.isPromise)(callbackURL)) callbackURL = await callbackURL;
217
+ if (!callbackURL) return await next();
218
+ const callbacks = Array.isArray(callbackURL) ? callbackURL : [callbackURL];
219
+ let ret;
220
+ for (const url of callbacks) {
221
+ ret = validateURL(url, "callbackURL", context.trustedOrigins, context.logger, ctx);
222
+ if (ret) return ret;
223
+ }
224
+ return await next();
225
+ });
226
+ };
227
+
228
+ //#endregion
229
+ Object.defineProperty(exports, 'initOriginCheckMiddleware', {
230
+ enumerable: true,
231
+ get: function () {
232
+ return initOriginCheckMiddleware;
233
+ }
234
+ });
235
+ Object.defineProperty(exports, 'originCheck', {
236
+ enumerable: true,
237
+ get: function () {
238
+ return originCheck;
239
+ }
240
+ });
241
+ Object.defineProperty(exports, 'wildcardMatch', {
242
+ enumerable: true,
243
+ get: function () {
244
+ return wildcardMatch;
245
+ }
246
+ });