@masheev/better-auth 0.0.0-stage → 1.7.5

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 (465) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +31 -2
  3. package/TYPE-PATCH-NOTICE.md +9 -0
  4. package/TYPE-PATCH-PROVENANCE.json +267 -0
  5. package/dist/_virtual/_rolldown/runtime.mjs +27 -0
  6. package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
  7. package/dist/adapters/drizzle-adapter/index.mjs +2 -0
  8. package/dist/adapters/index.d.mts +26 -0
  9. package/dist/adapters/index.mjs +9 -0
  10. package/dist/adapters/kysely-adapter/index.d.mts +1 -0
  11. package/dist/adapters/kysely-adapter/index.mjs +2 -0
  12. package/dist/adapters/memory-adapter/index.d.mts +1 -0
  13. package/dist/adapters/memory-adapter/index.mjs +2 -0
  14. package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
  15. package/dist/adapters/mongodb-adapter/index.mjs +2 -0
  16. package/dist/adapters/prisma-adapter/index.d.mts +1 -0
  17. package/dist/adapters/prisma-adapter/index.mjs +2 -0
  18. package/dist/api/dispatch.d.mts +34 -0
  19. package/dist/api/dispatch.mjs +275 -0
  20. package/dist/api/index.d.mts +4053 -0
  21. package/dist/api/index.mjs +220 -0
  22. package/dist/api/middlewares/authorization.d.mts +69 -0
  23. package/dist/api/middlewares/authorization.mjs +78 -0
  24. package/dist/api/middlewares/index.d.mts +2 -0
  25. package/dist/api/middlewares/origin-check.d.mts +17 -0
  26. package/dist/api/middlewares/origin-check.mjs +155 -0
  27. package/dist/api/rate-limiter/index.mjs +318 -0
  28. package/dist/api/routes/account.d.mts +413 -0
  29. package/dist/api/routes/account.mjs +619 -0
  30. package/dist/api/routes/callback.d.mts +32 -0
  31. package/dist/api/routes/callback.mjs +261 -0
  32. package/dist/api/routes/email-verification.d.mts +160 -0
  33. package/dist/api/routes/email-verification.mjs +324 -0
  34. package/dist/api/routes/error.d.mts +27 -0
  35. package/dist/api/routes/error.mjs +387 -0
  36. package/dist/api/routes/index.d.mts +12 -0
  37. package/dist/api/routes/ok.d.mts +35 -0
  38. package/dist/api/routes/ok.mjs +27 -0
  39. package/dist/api/routes/password.d.mts +182 -0
  40. package/dist/api/routes/password.mjs +206 -0
  41. package/dist/api/routes/session.d.mts +450 -0
  42. package/dist/api/routes/session.mjs +481 -0
  43. package/dist/api/routes/sign-in.d.mts +186 -0
  44. package/dist/api/routes/sign-in.mjs +368 -0
  45. package/dist/api/routes/sign-out.d.mts +51 -0
  46. package/dist/api/routes/sign-out.mjs +96 -0
  47. package/dist/api/routes/sign-up.d.mts +159 -0
  48. package/dist/api/routes/sign-up.mjs +275 -0
  49. package/dist/api/routes/update-session.d.mts +74 -0
  50. package/dist/api/routes/update-session.mjs +57 -0
  51. package/dist/api/routes/update-user.d.mts +428 -0
  52. package/dist/api/routes/update-user.mjs +522 -0
  53. package/dist/api/state/oauth.d.mts +53 -0
  54. package/dist/api/state/oauth.mjs +38 -0
  55. package/dist/api/state/should-session-refresh.d.mts +12 -0
  56. package/dist/api/state/should-session-refresh.mjs +13 -0
  57. package/dist/api/to-auth-endpoints.mjs +60 -0
  58. package/dist/auth/base.mjs +66 -0
  59. package/dist/auth/full.d.mts +28 -0
  60. package/dist/auth/full.mjs +29 -0
  61. package/dist/auth/minimal.d.mts +10 -0
  62. package/dist/auth/minimal.mjs +11 -0
  63. package/dist/auth/trusted-origins.mjs +106 -0
  64. package/dist/client/broadcast-channel.d.mts +19 -0
  65. package/dist/client/broadcast-channel.mjs +44 -0
  66. package/dist/client/config.d.mts +90 -0
  67. package/dist/client/config.mjs +113 -0
  68. package/dist/client/equality.d.mts +19 -0
  69. package/dist/client/equality.mjs +42 -0
  70. package/dist/client/fetch-plugins.mjs +17 -0
  71. package/dist/client/focus-manager.d.mts +10 -0
  72. package/dist/client/focus-manager.mjs +30 -0
  73. package/dist/client/index.d.mts +35 -0
  74. package/dist/client/index.mjs +22 -0
  75. package/dist/client/lynx/index.d.mts +43 -0
  76. package/dist/client/lynx/index.mjs +22 -0
  77. package/dist/client/lynx/lynx-store.d.mts +46 -0
  78. package/dist/client/lynx/lynx-store.mjs +44 -0
  79. package/dist/client/online-manager.d.mts +11 -0
  80. package/dist/client/online-manager.mjs +33 -0
  81. package/dist/client/parser.d.mts +10 -0
  82. package/dist/client/parser.mjs +70 -0
  83. package/dist/client/path-to-object.d.mts +113 -0
  84. package/dist/client/plugins/index.d.mts +44 -0
  85. package/dist/client/plugins/index.mjs +30 -0
  86. package/dist/client/plugins/infer-plugin.d.mts +16 -0
  87. package/dist/client/plugins/infer-plugin.mjs +11 -0
  88. package/dist/client/proxy.mjs +78 -0
  89. package/dist/client/query.d.mts +23 -0
  90. package/dist/client/query.mjs +124 -0
  91. package/dist/client/react/index.d.mts +44 -0
  92. package/dist/client/react/index.mjs +22 -0
  93. package/dist/client/react/react-store.d.mts +46 -0
  94. package/dist/client/react/react-store.mjs +44 -0
  95. package/dist/client/session-atom.d.mts +11 -0
  96. package/dist/client/session-atom.mjs +178 -0
  97. package/dist/client/session-refresh.d.mts +20 -0
  98. package/dist/client/session-refresh.mjs +131 -0
  99. package/dist/client/solid/index.d.mts +44 -0
  100. package/dist/client/solid/index.mjs +22 -0
  101. package/dist/client/solid/solid-store.mjs +21 -0
  102. package/dist/client/svelte/index.d.mts +44 -0
  103. package/dist/client/svelte/index.mjs +18 -0
  104. package/dist/client/types.d.mts +51 -0
  105. package/dist/client/vanilla.d.mts +42 -0
  106. package/dist/client/vanilla.mjs +18 -0
  107. package/dist/client/vue/index.d.mts +67 -0
  108. package/dist/client/vue/index.mjs +54 -0
  109. package/dist/client/vue/vue-store.mjs +23 -0
  110. package/dist/context/create-context.mjs +235 -0
  111. package/dist/context/helpers.mjs +158 -0
  112. package/dist/context/init-minimal.mjs +17 -0
  113. package/dist/context/init.mjs +19 -0
  114. package/dist/context/secret-utils.mjs +53 -0
  115. package/dist/context/store-capabilities.mjs +12 -0
  116. package/dist/cookies/cache.mjs +33 -0
  117. package/dist/cookies/cookie-utils.d.mts +72 -0
  118. package/dist/cookies/cookie-utils.mjs +203 -0
  119. package/dist/cookies/index.d.mts +124 -0
  120. package/dist/cookies/index.mjs +350 -0
  121. package/dist/cookies/jwt.mjs +44 -0
  122. package/dist/cookies/session-store.d.mts +32 -0
  123. package/dist/cookies/session-store.mjs +183 -0
  124. package/dist/crypto/buffer.d.mts +7 -0
  125. package/dist/crypto/buffer.mjs +16 -0
  126. package/dist/crypto/index.d.mts +32 -0
  127. package/dist/crypto/index.mjs +69 -0
  128. package/dist/crypto/jwt.d.mts +9 -0
  129. package/dist/crypto/jwt.mjs +141 -0
  130. package/dist/crypto/password.d.mts +13 -0
  131. package/dist/crypto/password.mjs +14 -0
  132. package/dist/crypto/random.d.mts +4 -0
  133. package/dist/crypto/random.mjs +5 -0
  134. package/dist/db/adapter-base.d.mts +7 -0
  135. package/dist/db/adapter-base.mjs +25 -0
  136. package/dist/db/adapter-kysely.d.mts +7 -0
  137. package/dist/db/adapter-kysely.mjs +17 -0
  138. package/dist/db/field-converter.d.mts +7 -0
  139. package/dist/db/field-converter.mjs +19 -0
  140. package/dist/db/field.d.mts +41 -0
  141. package/dist/db/get-migration.d.mts +56 -0
  142. package/dist/db/get-migration.mjs +685 -0
  143. package/dist/db/get-schema.d.mts +13 -0
  144. package/dist/db/get-schema.mjs +39 -0
  145. package/dist/db/index.d.mts +10 -0
  146. package/dist/db/index.mjs +35 -0
  147. package/dist/db/internal-adapter.d.mts +14 -0
  148. package/dist/db/internal-adapter.mjs +951 -0
  149. package/dist/db/revoke-unproven-account-access.d.mts +21 -0
  150. package/dist/db/revoke-unproven-account-access.mjs +58 -0
  151. package/dist/db/schema.d.mts +62 -0
  152. package/dist/db/schema.mjs +161 -0
  153. package/dist/db/to-zod.d.mts +35 -0
  154. package/dist/db/to-zod.mjs +23 -0
  155. package/dist/db/verification-token-storage.mjs +25 -0
  156. package/dist/db/with-hooks.d.mts +37 -0
  157. package/dist/db/with-hooks.mjs +255 -0
  158. package/dist/index.d.mts +30 -0
  159. package/dist/index.mjs +17 -0
  160. package/dist/integrations/cookie-plugin-guard.mjs +18 -0
  161. package/dist/integrations/next-js.d.mts +29 -0
  162. package/dist/integrations/next-js.mjs +105 -0
  163. package/dist/integrations/node.d.mts +11 -0
  164. package/dist/integrations/node.mjs +13 -0
  165. package/dist/integrations/solid-start.d.mts +22 -0
  166. package/dist/integrations/solid-start.mjs +15 -0
  167. package/dist/integrations/svelte-kit.d.mts +38 -0
  168. package/dist/integrations/svelte-kit.mjs +57 -0
  169. package/dist/integrations/tanstack-start-solid.d.mts +33 -0
  170. package/dist/integrations/tanstack-start-solid.mjs +57 -0
  171. package/dist/integrations/tanstack-start.d.mts +33 -0
  172. package/dist/integrations/tanstack-start.mjs +57 -0
  173. package/dist/oauth2/account-key.mjs +43 -0
  174. package/dist/oauth2/errors.mjs +49 -0
  175. package/dist/oauth2/index.d.mts +5 -0
  176. package/dist/oauth2/index.mjs +5 -0
  177. package/dist/oauth2/link-account.d.mts +96 -0
  178. package/dist/oauth2/link-account.mjs +329 -0
  179. package/dist/oauth2/state.d.mts +54 -0
  180. package/dist/oauth2/state.mjs +67 -0
  181. package/dist/oauth2/utils.d.mts +11 -0
  182. package/dist/oauth2/utils.mjs +33 -0
  183. package/dist/package.mjs +4 -0
  184. package/dist/plugins/access/access.d.mts +17 -0
  185. package/dist/plugins/access/access.mjs +78 -0
  186. package/dist/plugins/access/index.d.mts +3 -0
  187. package/dist/plugins/access/index.mjs +2 -0
  188. package/dist/plugins/access/types.d.mts +24 -0
  189. package/dist/plugins/additional-fields/client.d.mts +100 -0
  190. package/dist/plugins/additional-fields/client.mjs +11 -0
  191. package/dist/plugins/admin/access/index.d.mts +2 -0
  192. package/dist/plugins/admin/access/index.mjs +2 -0
  193. package/dist/plugins/admin/access/statement.d.mts +51 -0
  194. package/dist/plugins/admin/access/statement.mjs +52 -0
  195. package/dist/plugins/admin/admin.d.mts +911 -0
  196. package/dist/plugins/admin/admin.mjs +89 -0
  197. package/dist/plugins/admin/client.d.mts +81 -0
  198. package/dist/plugins/admin/client.mjs +39 -0
  199. package/dist/plugins/admin/error-codes.d.mts +30 -0
  200. package/dist/plugins/admin/error-codes.mjs +29 -0
  201. package/dist/plugins/admin/has-permission.mjs +12 -0
  202. package/dist/plugins/admin/index.d.mts +3 -0
  203. package/dist/plugins/admin/index.mjs +2 -0
  204. package/dist/plugins/admin/routes.mjs +919 -0
  205. package/dist/plugins/admin/schema.d.mts +40 -0
  206. package/dist/plugins/admin/schema.mjs +33 -0
  207. package/dist/plugins/admin/types.d.mts +88 -0
  208. package/dist/plugins/anonymous/client.d.mts +32 -0
  209. package/dist/plugins/anonymous/client.mjs +21 -0
  210. package/dist/plugins/anonymous/error-codes.d.mts +15 -0
  211. package/dist/plugins/anonymous/error-codes.mjs +14 -0
  212. package/dist/plugins/anonymous/index.d.mts +175 -0
  213. package/dist/plugins/anonymous/index.mjs +219 -0
  214. package/dist/plugins/anonymous/schema.d.mts +15 -0
  215. package/dist/plugins/anonymous/schema.mjs +9 -0
  216. package/dist/plugins/anonymous/types.d.mts +65 -0
  217. package/dist/plugins/bearer/index.d.mts +45 -0
  218. package/dist/plugins/bearer/index.mjs +74 -0
  219. package/dist/plugins/captcha/constants.d.mts +9 -0
  220. package/dist/plugins/captcha/constants.mjs +27 -0
  221. package/dist/plugins/captcha/error-codes.mjs +13 -0
  222. package/dist/plugins/captcha/index.d.mts +27 -0
  223. package/dist/plugins/captcha/index.mjs +79 -0
  224. package/dist/plugins/captcha/types.d.mts +52 -0
  225. package/dist/plugins/captcha/utils.mjs +9 -0
  226. package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
  227. package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +47 -0
  228. package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +32 -0
  229. package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
  230. package/dist/plugins/custom-session/client.d.mts +17 -0
  231. package/dist/plugins/custom-session/client.mjs +7 -0
  232. package/dist/plugins/custom-session/index.d.mts +73 -0
  233. package/dist/plugins/custom-session/index.mjs +65 -0
  234. package/dist/plugins/device-authorization/client.d.mts +17 -0
  235. package/dist/plugins/device-authorization/client.mjs +18 -0
  236. package/dist/plugins/device-authorization/error-codes.mjs +19 -0
  237. package/dist/plugins/device-authorization/index.d.mts +558 -0
  238. package/dist/plugins/device-authorization/index.mjs +87 -0
  239. package/dist/plugins/device-authorization/routes.d.mts +32 -0
  240. package/dist/plugins/device-authorization/routes.mjs +725 -0
  241. package/dist/plugins/device-authorization/schema.d.mts +18 -0
  242. package/dist/plugins/device-authorization/schema.mjs +63 -0
  243. package/dist/plugins/email-otp/client.d.mts +21 -0
  244. package/dist/plugins/email-otp/client.mjs +17 -0
  245. package/dist/plugins/email-otp/error-codes.d.mts +10 -0
  246. package/dist/plugins/email-otp/error-codes.mjs +9 -0
  247. package/dist/plugins/email-otp/index.d.mts +551 -0
  248. package/dist/plugins/email-otp/index.mjs +145 -0
  249. package/dist/plugins/email-otp/otp-token.mjs +55 -0
  250. package/dist/plugins/email-otp/routes.mjs +784 -0
  251. package/dist/plugins/email-otp/types.d.mts +109 -0
  252. package/dist/plugins/email-otp/utils.mjs +17 -0
  253. package/dist/plugins/generic-oauth/error-codes.mjs +8 -0
  254. package/dist/plugins/generic-oauth/index.d.mts +52 -0
  255. package/dist/plugins/generic-oauth/index.mjs +279 -0
  256. package/dist/plugins/generic-oauth/providers/auth0.d.mts +36 -0
  257. package/dist/plugins/generic-oauth/providers/auth0.mjs +49 -0
  258. package/dist/plugins/generic-oauth/providers/gumroad.d.mts +31 -0
  259. package/dist/plugins/generic-oauth/providers/gumroad.mjs +62 -0
  260. package/dist/plugins/generic-oauth/providers/hubspot.d.mts +36 -0
  261. package/dist/plugins/generic-oauth/providers/hubspot.mjs +62 -0
  262. package/dist/plugins/generic-oauth/providers/index.d.mts +10 -0
  263. package/dist/plugins/generic-oauth/providers/keycloak.d.mts +36 -0
  264. package/dist/plugins/generic-oauth/providers/keycloak.mjs +47 -0
  265. package/dist/plugins/generic-oauth/providers/line.d.mts +54 -0
  266. package/dist/plugins/generic-oauth/providers/line.mjs +93 -0
  267. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +39 -0
  268. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +104 -0
  269. package/dist/plugins/generic-oauth/providers/okta.d.mts +36 -0
  270. package/dist/plugins/generic-oauth/providers/okta.mjs +47 -0
  271. package/dist/plugins/generic-oauth/providers/patreon.d.mts +29 -0
  272. package/dist/plugins/generic-oauth/providers/patreon.mjs +61 -0
  273. package/dist/plugins/generic-oauth/providers/slack.d.mts +29 -0
  274. package/dist/plugins/generic-oauth/providers/slack.mjs +63 -0
  275. package/dist/plugins/generic-oauth/providers/yandex.d.mts +29 -0
  276. package/dist/plugins/generic-oauth/providers/yandex.mjs +67 -0
  277. package/dist/plugins/generic-oauth/types.d.mts +268 -0
  278. package/dist/plugins/haveibeenpwned/index.d.mts +63 -0
  279. package/dist/plugins/haveibeenpwned/index.mjs +81 -0
  280. package/dist/plugins/index.d.mts +69 -0
  281. package/dist/plugins/index.mjs +49 -0
  282. package/dist/plugins/jwt/adapter.mjs +68 -0
  283. package/dist/plugins/jwt/client.d.mts +41 -0
  284. package/dist/plugins/jwt/client.mjs +19 -0
  285. package/dist/plugins/jwt/cookie-cache.mjs +77 -0
  286. package/dist/plugins/jwt/index.d.mts +246 -0
  287. package/dist/plugins/jwt/index.mjs +214 -0
  288. package/dist/plugins/jwt/schema.d.mts +33 -0
  289. package/dist/plugins/jwt/schema.mjs +29 -0
  290. package/dist/plugins/jwt/sign.d.mts +128 -0
  291. package/dist/plugins/jwt/sign.mjs +130 -0
  292. package/dist/plugins/jwt/types.d.mts +256 -0
  293. package/dist/plugins/jwt/utils.d.mts +41 -0
  294. package/dist/plugins/jwt/utils.mjs +64 -0
  295. package/dist/plugins/jwt/verify.d.mts +11 -0
  296. package/dist/plugins/jwt/verify.mjs +45 -0
  297. package/dist/plugins/last-login-method/client.d.mts +48 -0
  298. package/dist/plugins/last-login-method/client.mjs +48 -0
  299. package/dist/plugins/last-login-method/index.d.mts +127 -0
  300. package/dist/plugins/last-login-method/index.mjs +98 -0
  301. package/dist/plugins/magic-link/client.d.mts +10 -0
  302. package/dist/plugins/magic-link/client.mjs +11 -0
  303. package/dist/plugins/magic-link/index.d.mts +213 -0
  304. package/dist/plugins/magic-link/index.mjs +208 -0
  305. package/dist/plugins/magic-link/utils.mjs +9 -0
  306. package/dist/plugins/multi-session/client.d.mts +19 -0
  307. package/dist/plugins/multi-session/client.mjs +19 -0
  308. package/dist/plugins/multi-session/error-codes.d.mts +8 -0
  309. package/dist/plugins/multi-session/error-codes.mjs +5 -0
  310. package/dist/plugins/multi-session/index.d.mts +212 -0
  311. package/dist/plugins/multi-session/index.mjs +217 -0
  312. package/dist/plugins/oauth-popup/client.d.mts +82 -0
  313. package/dist/plugins/oauth-popup/client.mjs +203 -0
  314. package/dist/plugins/oauth-popup/constants.d.mts +11 -0
  315. package/dist/plugins/oauth-popup/constants.mjs +11 -0
  316. package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
  317. package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
  318. package/dist/plugins/oauth-popup/index.d.mts +67 -0
  319. package/dist/plugins/oauth-popup/index.mjs +232 -0
  320. package/dist/plugins/oauth-popup/types.d.mts +30 -0
  321. package/dist/plugins/oauth-proxy/index.d.mts +130 -0
  322. package/dist/plugins/oauth-proxy/index.mjs +407 -0
  323. package/dist/plugins/oauth-proxy/utils.mjs +55 -0
  324. package/dist/plugins/one-tap/client.d.mts +174 -0
  325. package/dist/plugins/one-tap/client.mjs +208 -0
  326. package/dist/plugins/one-tap/index.d.mts +82 -0
  327. package/dist/plugins/one-tap/index.mjs +100 -0
  328. package/dist/plugins/one-time-token/client.d.mts +10 -0
  329. package/dist/plugins/one-time-token/client.mjs +11 -0
  330. package/dist/plugins/one-time-token/index.d.mts +132 -0
  331. package/dist/plugins/one-time-token/index.mjs +107 -0
  332. package/dist/plugins/one-time-token/utils.mjs +9 -0
  333. package/dist/plugins/open-api/generator.d.mts +126 -0
  334. package/dist/plugins/open-api/generator.mjs +557 -0
  335. package/dist/plugins/open-api/index.d.mts +97 -0
  336. package/dist/plugins/open-api/index.mjs +65 -0
  337. package/dist/plugins/open-api/logo.mjs +13 -0
  338. package/dist/plugins/organization/access/index.d.mts +2 -0
  339. package/dist/plugins/organization/access/index.mjs +2 -0
  340. package/dist/plugins/organization/access/statement.d.mts +113 -0
  341. package/dist/plugins/organization/access/statement.mjs +77 -0
  342. package/dist/plugins/organization/adapter.d.mts +815 -0
  343. package/dist/plugins/organization/adapter.mjs +813 -0
  344. package/dist/plugins/organization/call.mjs +15 -0
  345. package/dist/plugins/organization/client.d.mts +375 -0
  346. package/dist/plugins/organization/client.mjs +104 -0
  347. package/dist/plugins/organization/error-codes.d.mts +66 -0
  348. package/dist/plugins/organization/error-codes.mjs +65 -0
  349. package/dist/plugins/organization/has-permission.d.mts +17 -0
  350. package/dist/plugins/organization/has-permission.mjs +34 -0
  351. package/dist/plugins/organization/index.d.mts +6 -0
  352. package/dist/plugins/organization/index.mjs +4 -0
  353. package/dist/plugins/organization/organization.d.mts +420 -0
  354. package/dist/plugins/organization/organization.mjs +886 -0
  355. package/dist/plugins/organization/permission.d.mts +15 -0
  356. package/dist/plugins/organization/permission.mjs +14 -0
  357. package/dist/plugins/organization/routes/crud-access-control.d.mts +511 -0
  358. package/dist/plugins/organization/routes/crud-access-control.mjs +674 -0
  359. package/dist/plugins/organization/routes/crud-invites.d.mts +1154 -0
  360. package/dist/plugins/organization/routes/crud-invites.mjs +602 -0
  361. package/dist/plugins/organization/routes/crud-members.d.mts +1057 -0
  362. package/dist/plugins/organization/routes/crud-members.mjs +518 -0
  363. package/dist/plugins/organization/routes/crud-org.d.mts +918 -0
  364. package/dist/plugins/organization/routes/crud-org.mjs +455 -0
  365. package/dist/plugins/organization/routes/crud-team.d.mts +1238 -0
  366. package/dist/plugins/organization/routes/crud-team.mjs +766 -0
  367. package/dist/plugins/organization/schema.d.mts +390 -0
  368. package/dist/plugins/organization/schema.mjs +65 -0
  369. package/dist/plugins/organization/types.d.mts +691 -0
  370. package/dist/plugins/phone-number/client.d.mts +31 -0
  371. package/dist/plugins/phone-number/client.mjs +19 -0
  372. package/dist/plugins/phone-number/error-codes.d.mts +19 -0
  373. package/dist/plugins/phone-number/error-codes.mjs +18 -0
  374. package/dist/plugins/phone-number/index.d.mts +360 -0
  375. package/dist/plugins/phone-number/index.mjs +57 -0
  376. package/dist/plugins/phone-number/routes.mjs +529 -0
  377. package/dist/plugins/phone-number/schema.d.mts +22 -0
  378. package/dist/plugins/phone-number/schema.mjs +18 -0
  379. package/dist/plugins/phone-number/types.d.mts +116 -0
  380. package/dist/plugins/siwe/client.d.mts +14 -0
  381. package/dist/plugins/siwe/client.mjs +15 -0
  382. package/dist/plugins/siwe/index.d.mts +62 -0
  383. package/dist/plugins/siwe/index.mjs +272 -0
  384. package/dist/plugins/siwe/parse-message.mjs +60 -0
  385. package/dist/plugins/siwe/schema.d.mts +35 -0
  386. package/dist/plugins/siwe/schema.mjs +30 -0
  387. package/dist/plugins/siwe/types.d.mts +43 -0
  388. package/dist/plugins/test-utils/auth-helpers.mjs +33 -0
  389. package/dist/plugins/test-utils/cookie-builder.mjs +55 -0
  390. package/dist/plugins/test-utils/db-helpers.mjs +65 -0
  391. package/dist/plugins/test-utils/factories.mjs +38 -0
  392. package/dist/plugins/test-utils/index.d.mts +73 -0
  393. package/dist/plugins/test-utils/index.mjs +97 -0
  394. package/dist/plugins/test-utils/otp-sink.mjs +21 -0
  395. package/dist/plugins/test-utils/types.d.mts +51 -0
  396. package/dist/plugins/two-factor/backup-codes/index.d.mts +291 -0
  397. package/dist/plugins/two-factor/backup-codes/index.mjs +341 -0
  398. package/dist/plugins/two-factor/client.d.mts +76 -0
  399. package/dist/plugins/two-factor/client.mjs +41 -0
  400. package/dist/plugins/two-factor/constant.mjs +6 -0
  401. package/dist/plugins/two-factor/error-code.d.mts +20 -0
  402. package/dist/plugins/two-factor/error-code.mjs +19 -0
  403. package/dist/plugins/two-factor/index.d.mts +720 -0
  404. package/dist/plugins/two-factor/index.mjs +349 -0
  405. package/dist/plugins/two-factor/otp/index.d.mts +216 -0
  406. package/dist/plugins/two-factor/otp/index.mjs +252 -0
  407. package/dist/plugins/two-factor/schema.d.mts +59 -0
  408. package/dist/plugins/two-factor/schema.mjs +53 -0
  409. package/dist/plugins/two-factor/totp/index.d.mts +219 -0
  410. package/dist/plugins/two-factor/totp/index.mjs +230 -0
  411. package/dist/plugins/two-factor/types.d.mts +111 -0
  412. package/dist/plugins/two-factor/utils.mjs +9 -0
  413. package/dist/plugins/two-factor/verify-two-factor.mjs +205 -0
  414. package/dist/plugins/username/client.d.mts +38 -0
  415. package/dist/plugins/username/client.mjs +17 -0
  416. package/dist/plugins/username/error-codes.d.mts +16 -0
  417. package/dist/plugins/username/error-codes.mjs +15 -0
  418. package/dist/plugins/username/index.d.mts +326 -0
  419. package/dist/plugins/username/index.mjs +312 -0
  420. package/dist/plugins/username/schema.d.mts +50 -0
  421. package/dist/plugins/username/schema.mjs +25 -0
  422. package/dist/social-providers/index.d.mts +1 -0
  423. package/dist/social-providers/index.mjs +2 -0
  424. package/dist/state.d.mts +48 -0
  425. package/dist/state.mjs +149 -0
  426. package/dist/test-utils/headers.d.mts +8 -0
  427. package/dist/test-utils/headers.mjs +17 -0
  428. package/dist/test-utils/http-test-instance.d.mts +413 -0
  429. package/dist/test-utils/http-test-instance.mjs +107 -0
  430. package/dist/test-utils/index.d.mts +4 -0
  431. package/dist/test-utils/index.mjs +4 -0
  432. package/dist/test-utils/test-instance.d.mts +56 -0
  433. package/dist/test-utils/test-instance.mjs +242 -0
  434. package/dist/types/adapter.d.mts +2 -0
  435. package/dist/types/api.d.mts +28 -0
  436. package/dist/types/auth.d.mts +32 -0
  437. package/dist/types/helper.d.mts +26 -0
  438. package/dist/types/index.d.mts +10 -0
  439. package/dist/types/index.mjs +1 -0
  440. package/dist/types/models.d.mts +10 -0
  441. package/dist/types/plugins.d.mts +19 -0
  442. package/dist/utils/boolean.mjs +6 -0
  443. package/dist/utils/constants.mjs +4 -0
  444. package/dist/utils/date.mjs +6 -0
  445. package/dist/utils/hashing.mjs +18 -0
  446. package/dist/utils/hide-metadata.d.mts +6 -0
  447. package/dist/utils/hide-metadata.mjs +4 -0
  448. package/dist/utils/index.d.mts +4 -0
  449. package/dist/utils/is-api-error.d.mts +2 -0
  450. package/dist/utils/is-api-error.mjs +2 -0
  451. package/dist/utils/is-atom.mjs +6 -0
  452. package/dist/utils/is-promise.mjs +6 -0
  453. package/dist/utils/middleware-response.mjs +7 -0
  454. package/dist/utils/password.mjs +32 -0
  455. package/dist/utils/plugin-helper.mjs +14 -0
  456. package/dist/utils/request.mjs +23 -0
  457. package/dist/utils/shim.mjs +22 -0
  458. package/dist/utils/time.d.mts +48 -0
  459. package/dist/utils/time.mjs +98 -0
  460. package/dist/utils/url.d.mts +78 -0
  461. package/dist/utils/url.mjs +238 -0
  462. package/dist/utils/validate-user-info.mjs +44 -0
  463. package/dist/utils/wildcard.mjs +106 -0
  464. package/dist/version.mjs +5 -0
  465. package/package.json +595 -3
@@ -0,0 +1,32 @@
1
+ import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
2
+ //#region src/utils/password.ts
3
+ async function validatePassword(ctx, data) {
4
+ const credentialAccount = await ctx.context.internalAdapter.findCredentialAccount(data.userId);
5
+ const currentPassword = credentialAccount?.password;
6
+ if (!credentialAccount || !currentPassword) return false;
7
+ return await ctx.context.password.verify({
8
+ hash: currentPassword,
9
+ password: data.password
10
+ });
11
+ }
12
+ async function checkPassword(userId, c) {
13
+ const credentialAccount = await c.context.internalAdapter.findCredentialAccount(userId);
14
+ const currentPassword = credentialAccount?.password;
15
+ const password = c.body.password;
16
+ if (!credentialAccount || !currentPassword || !password) {
17
+ if (password) await c.context.password.hash(password);
18
+ throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_PASSWORD);
19
+ }
20
+ if (!await c.context.password.verify({
21
+ hash: currentPassword,
22
+ password
23
+ })) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_PASSWORD);
24
+ return true;
25
+ }
26
+ async function shouldRequirePassword(ctx, userId, allowPasswordless) {
27
+ if (!allowPasswordless) return true;
28
+ const credentialAccount = await ctx.context.internalAdapter.findCredentialAccount(userId);
29
+ return Boolean(credentialAccount?.password);
30
+ }
31
+ //#endregion
32
+ export { checkPassword, shouldRequirePassword, validatePassword };
@@ -0,0 +1,14 @@
1
+ import { isAPIError } from "./is-api-error.mjs";
2
+ //#region src/utils/plugin-helper.ts
3
+ const getEndpointResponse = async (ctx) => {
4
+ const returned = ctx.context.returned;
5
+ if (!returned) return null;
6
+ if (returned instanceof Response) {
7
+ if (returned.status !== 200) return null;
8
+ return await returned.clone().json();
9
+ }
10
+ if (isAPIError(returned)) return null;
11
+ return returned;
12
+ };
13
+ //#endregion
14
+ export { getEndpointResponse };
@@ -0,0 +1,23 @@
1
+ //#region src/utils/request.ts
2
+ function safeCloneRequest(request) {
3
+ if (!request) return;
4
+ try {
5
+ return request.clone();
6
+ } catch {
7
+ return new Request(request.url, {
8
+ cache: request.cache,
9
+ credentials: request.credentials,
10
+ headers: request.headers,
11
+ integrity: request.integrity,
12
+ keepalive: request.keepalive,
13
+ method: request.method,
14
+ mode: request.mode,
15
+ redirect: request.redirect,
16
+ referrer: request.referrer,
17
+ referrerPolicy: request.referrerPolicy,
18
+ signal: request.signal
19
+ });
20
+ }
21
+ }
22
+ //#endregion
23
+ export { safeCloneRequest };
@@ -0,0 +1,22 @@
1
+ //#region src/utils/shim.ts
2
+ const shimContext = (originalObject, newContext) => {
3
+ const shimmedObj = {};
4
+ for (const [key, value] of Object.entries(originalObject)) {
5
+ shimmedObj[key] = (ctx) => {
6
+ return value({
7
+ ...ctx,
8
+ context: {
9
+ ...newContext,
10
+ ...ctx.context
11
+ }
12
+ });
13
+ };
14
+ shimmedObj[key].path = value.path;
15
+ shimmedObj[key].method = value.method;
16
+ shimmedObj[key].options = value.options;
17
+ shimmedObj[key].headers = value.headers;
18
+ }
19
+ return shimmedObj;
20
+ };
21
+ //#endregion
22
+ export { shimContext };
@@ -0,0 +1,48 @@
1
+ //#region src/utils/time.d.ts
2
+ type Years = "years" | "year" | "yrs" | "yr" | "y";
3
+ type Months = "months" | "month" | "mo";
4
+ type Weeks = "weeks" | "week" | "w";
5
+ type Days = "days" | "day" | "d";
6
+ type Hours = "hours" | "hour" | "hrs" | "hr" | "h";
7
+ type Minutes = "minutes" | "minute" | "mins" | "min" | "m";
8
+ type Seconds = "seconds" | "second" | "secs" | "sec" | "s";
9
+ type Unit = Years | Months | Weeks | Days | Hours | Minutes | Seconds;
10
+ type UnitAnyCase = Capitalize<Unit> | Uppercase<Unit> | Unit;
11
+ type Suffix = " ago" | " from now";
12
+ type Prefix = "+" | "-" | "+ " | "- ";
13
+ type BaseTimeString = `${number}${UnitAnyCase}` | `${number} ${UnitAnyCase}`;
14
+ /**
15
+ * A typed string representing a time duration.
16
+ * Supports formats like "7d", "30m", "1 hour", "2 hours ago", "-5m", etc.
17
+ */
18
+ type TimeString = BaseTimeString | `${BaseTimeString}${Suffix}` | `${Prefix}${BaseTimeString}`;
19
+ /**
20
+ * Parse a time string and return the value in milliseconds.
21
+ *
22
+ * @param value - A time string like "7d", "30m", "1 hour", "2 hours ago"
23
+ * @returns The parsed value in milliseconds
24
+ * @throws TypeError if the string format is invalid
25
+ *
26
+ * @example
27
+ * ms("1d") // 86400000
28
+ * ms("2 hours") // 7200000
29
+ * ms("30s") // 30000
30
+ * ms("2 hours ago") // -7200000
31
+ */
32
+ declare function ms(value: TimeString): number;
33
+ /**
34
+ * Parse a time string and return the value in seconds.
35
+ *
36
+ * @param value - A time string like "7d", "30m", "1 hour", "2 hours ago"
37
+ * @returns The parsed value in seconds (rounded)
38
+ * @throws TypeError if the string format is invalid
39
+ *
40
+ * @example
41
+ * sec("1d") // 86400
42
+ * sec("2 hours") // 7200
43
+ * sec("-30s") // -30
44
+ * sec("2 hours ago") // -7200
45
+ */
46
+ declare function sec(value: TimeString): number;
47
+ //#endregion
48
+ export { TimeString, ms, sec };
@@ -0,0 +1,98 @@
1
+ //#region src/utils/time.ts
2
+ const SEC = 1e3;
3
+ const MIN = SEC * 60;
4
+ const HOUR = MIN * 60;
5
+ const DAY = HOUR * 24;
6
+ const WEEK = DAY * 7;
7
+ const MONTH = DAY * 30;
8
+ const YEAR = DAY * 365.25;
9
+ const REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mo|years?|yrs?|y)(?: (ago|from now))?$/i;
10
+ function parse(value) {
11
+ const match = REGEX.exec(value);
12
+ if (!match || match[4] && match[1]) throw new TypeError(`Invalid time string format: "${value}". Use formats like "7d", "30m", "1 hour", etc.`);
13
+ const n = parseFloat(match[2]);
14
+ const unit = match[3].toLowerCase();
15
+ let result;
16
+ switch (unit) {
17
+ case "years":
18
+ case "year":
19
+ case "yrs":
20
+ case "yr":
21
+ case "y":
22
+ result = n * YEAR;
23
+ break;
24
+ case "months":
25
+ case "month":
26
+ case "mo":
27
+ result = n * MONTH;
28
+ break;
29
+ case "weeks":
30
+ case "week":
31
+ case "w":
32
+ result = n * WEEK;
33
+ break;
34
+ case "days":
35
+ case "day":
36
+ case "d":
37
+ result = n * DAY;
38
+ break;
39
+ case "hours":
40
+ case "hour":
41
+ case "hrs":
42
+ case "hr":
43
+ case "h":
44
+ result = n * HOUR;
45
+ break;
46
+ case "minutes":
47
+ case "minute":
48
+ case "mins":
49
+ case "min":
50
+ case "m":
51
+ result = n * MIN;
52
+ break;
53
+ case "seconds":
54
+ case "second":
55
+ case "secs":
56
+ case "sec":
57
+ case "s":
58
+ result = n * SEC;
59
+ break;
60
+ default: throw new TypeError(`Unknown time unit: "${unit}"`);
61
+ }
62
+ if (match[1] === "-" || match[4] === "ago") return -result;
63
+ return result;
64
+ }
65
+ /**
66
+ * Parse a time string and return the value in milliseconds.
67
+ *
68
+ * @param value - A time string like "7d", "30m", "1 hour", "2 hours ago"
69
+ * @returns The parsed value in milliseconds
70
+ * @throws TypeError if the string format is invalid
71
+ *
72
+ * @example
73
+ * ms("1d") // 86400000
74
+ * ms("2 hours") // 7200000
75
+ * ms("30s") // 30000
76
+ * ms("2 hours ago") // -7200000
77
+ */
78
+ function ms(value) {
79
+ return parse(value);
80
+ }
81
+ /**
82
+ * Parse a time string and return the value in seconds.
83
+ *
84
+ * @param value - A time string like "7d", "30m", "1 hour", "2 hours ago"
85
+ * @returns The parsed value in seconds (rounded)
86
+ * @throws TypeError if the string format is invalid
87
+ *
88
+ * @example
89
+ * sec("1d") // 86400
90
+ * sec("2 hours") // 7200
91
+ * sec("-30s") // -30
92
+ * sec("2 hours ago") // -7200
93
+ */
94
+ function sec(value) {
95
+ return Math.round(parse(value) / 1e3);
96
+ }
97
+ //#endregion
98
+ export { ms, sec };
@@ -0,0 +1,78 @@
1
+ import { BaseURLConfig, DynamicBaseURLConfig } from "@better-auth/core";
2
+
3
+ //#region src/utils/url.d.ts
4
+ declare function trimTrailingSlashes(value: string): string;
5
+ declare function getBaseURL(url?: string, path?: string, request?: Request, loadEnv?: boolean, trustedProxyHeaders?: boolean | undefined): string | undefined;
6
+ declare function getOrigin(url: string): string | null;
7
+ declare function getProtocol(url: string): string | null;
8
+ declare function getHost(url: string): string | null;
9
+ /**
10
+ * Checks if the baseURL config is a dynamic config object
11
+ */
12
+ declare function isDynamicBaseURLConfig(config: BaseURLConfig | undefined): config is DynamicBaseURLConfig;
13
+ /**
14
+ * Check if a value is a `Request`
15
+ * - `instanceof`: works for native Request instances
16
+ * - `toString`: handles where instanceof check fails but the object is still a
17
+ * valid Request (e.g. cross-realm, polyfills). Paired with a shape check so
18
+ * an object that only spoofs `Symbol.toStringTag` without the real shape is
19
+ * rejected before downstream code tries to read `.headers` / `.url`.
20
+ *
21
+ * @param value The value to check
22
+ * @returns `true` if the value is a Request instance
23
+ */
24
+ declare function isRequestLike(value: unknown): value is Request;
25
+ /**
26
+ * Extracts the host from a `Request` or `Headers`.
27
+ * Honors `x-forwarded-host` only when `trustedProxyHeaders` is enabled,
28
+ * then falls back to the `host` header and finally the request URL.
29
+ */
30
+ declare function getHostFromSource(source: Request | Headers, trustedProxyHeaders?: boolean): string | null;
31
+ /**
32
+ * Extracts the protocol from a `Request` or `Headers`.
33
+ * Honors `x-forwarded-proto` only when `trustedProxyHeaders` is enabled,
34
+ * then falls back to the request URL, then to "https".
35
+ */
36
+ declare function getProtocolFromSource(source: Request | Headers, configProtocol?: "http" | "https" | "auto" | undefined, trustedProxyHeaders?: boolean): "http" | "https";
37
+ /**
38
+ * Matches a hostname against a host pattern.
39
+ * Supports wildcard patterns like `*.vercel.app` or `preview-*.myapp.com`.
40
+ *
41
+ * @param host The hostname to test (e.g., "myapp.com", "preview-123.vercel.app")
42
+ * @param pattern The host pattern (e.g., "myapp.com", "*.vercel.app")
43
+ * @returns {boolean} true if the host matches the pattern, false otherwise.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * matchesHostPattern("myapp.com", "myapp.com") // true
48
+ * matchesHostPattern("preview-123.vercel.app", "*.vercel.app") // true
49
+ * matchesHostPattern("preview-123.myapp.com", "preview-*.myapp.com") // true
50
+ * matchesHostPattern("evil.com", "myapp.com") // false
51
+ * ```
52
+ */
53
+ declare const matchesHostPattern: (host: string, pattern: string) => boolean;
54
+ /**
55
+ * Resolves the base URL from a dynamic config based on the incoming request.
56
+ * Validates the derived host against the allowedHosts allowlist.
57
+ *
58
+ * @param config The dynamic base URL config
59
+ * @param request The incoming request
60
+ * @param basePath The base path to append
61
+ * @returns The resolved base URL with path
62
+ * @throws BetterAuthError if host is not in allowedHosts and no fallback is set
63
+ */
64
+ declare function resolveDynamicBaseURL(config: DynamicBaseURLConfig, source: Request | Headers, basePath: string, trustedProxyHeaders?: boolean): string;
65
+ /**
66
+ * Resolves the base URL from any config type (static string or dynamic object).
67
+ * This is the main entry point for base URL resolution.
68
+ *
69
+ * @param config The base URL config (string or object)
70
+ * @param basePath The base path to append
71
+ * @param request Optional request for dynamic resolution
72
+ * @param loadEnv Whether to load from environment variables
73
+ * @param trustedProxyHeaders Whether to trust proxy headers (for legacy behavior)
74
+ * @returns The resolved base URL with path
75
+ */
76
+ declare function resolveBaseURL(config: BaseURLConfig | undefined, basePath: string, source?: Request | Headers, loadEnv?: boolean, trustedProxyHeaders?: boolean): string | undefined;
77
+ //#endregion
78
+ export { getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL, trimTrailingSlashes };
@@ -0,0 +1,238 @@
1
+ import { wildcardMatch } from "./wildcard.mjs";
2
+ import { env } from "@better-auth/core/env";
3
+ import { BetterAuthError } from "@better-auth/core/error";
4
+ //#region src/utils/url.ts
5
+ const SLASH_CHAR_CODE = "/".charCodeAt(0);
6
+ /**
7
+ * Minimal loopback check for dev scheme inference only. Reachable from
8
+ * `client/config.ts` via `getBaseURL`, so we MUST NOT import the full
9
+ * `@better-auth/core/utils/host` classifier here: its `utils/ip` dependency
10
+ * on zod would leak into the client bundle (see `e2e/smoke/test/vite.spec.ts`).
11
+ *
12
+ * Server-side SSRF/loopback checks (oauth redirect matching, trusted-origin
13
+ * resolution, electron fetch gate) continue to use the authoritative
14
+ * `isLoopbackHost` from `@better-auth/core/utils/host`. This helper's only
15
+ * job is picking `http` vs `https` for dev ergonomics.
16
+ */
17
+ function isLoopbackForDevScheme(host) {
18
+ const hostname = host.replace(/:\d+$/, "").replace(/^\[|\]$/g, "").toLowerCase();
19
+ return hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "::1" || hostname.startsWith("127.");
20
+ }
21
+ function trimTrailingSlashes(value) {
22
+ let end = value.length;
23
+ while (end > 0 && value.charCodeAt(end - 1) === SLASH_CHAR_CODE) end--;
24
+ return end === value.length ? value : value.slice(0, end);
25
+ }
26
+ function checkHasPath(url) {
27
+ try {
28
+ return (trimTrailingSlashes(new URL(url).pathname) || "/") !== "/";
29
+ } catch {
30
+ throw new BetterAuthError(`Invalid base URL: ${url}. Please provide a valid base URL.`);
31
+ }
32
+ }
33
+ function assertHasProtocol(url) {
34
+ try {
35
+ const parsedUrl = new URL(url);
36
+ if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new BetterAuthError(`Invalid base URL: ${url}. URL must include 'http://' or 'https://'`);
37
+ } catch (error) {
38
+ if (error instanceof BetterAuthError) throw error;
39
+ throw new BetterAuthError(`Invalid base URL: ${url}. Please provide a valid base URL.`, { cause: error });
40
+ }
41
+ }
42
+ function withPath(url, path = "/api/auth") {
43
+ assertHasProtocol(url);
44
+ if (checkHasPath(url)) return url;
45
+ const trimmedUrl = trimTrailingSlashes(url);
46
+ if (!path || path === "/") return trimmedUrl;
47
+ path = path.startsWith("/") ? path : `/${path}`;
48
+ return `${trimmedUrl}${path}`;
49
+ }
50
+ function validateProxyHeader(header, type) {
51
+ if (!header || header.trim() === "") return false;
52
+ if (type === "proto") return header === "http" || header === "https";
53
+ if (type === "host") {
54
+ if ([
55
+ /\.\./,
56
+ /\0/,
57
+ /[\s]/,
58
+ /^[.]/,
59
+ /[<>'"]/,
60
+ /javascript:/i,
61
+ /file:/i,
62
+ /data:/i
63
+ ].some((pattern) => pattern.test(header))) return false;
64
+ return /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*(:[0-9]{1,5})?$/.test(header) || /^(\d{1,3}\.){3}\d{1,3}(:[0-9]{1,5})?$/.test(header) || /^\[[0-9a-fA-F:]+\](:[0-9]{1,5})?$/.test(header) || /^localhost(:[0-9]{1,5})?$/i.test(header);
65
+ }
66
+ return false;
67
+ }
68
+ function getBaseURL(url, path, request, loadEnv, trustedProxyHeaders) {
69
+ if (url) return withPath(url, path);
70
+ if (loadEnv !== false) {
71
+ const fromEnv = env.BETTER_AUTH_URL || env.NEXT_PUBLIC_BETTER_AUTH_URL || env.PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_AUTH_URL || (env.BASE_URL !== "/" ? env.BASE_URL : void 0);
72
+ if (fromEnv) return withPath(fromEnv, path);
73
+ }
74
+ const fromRequest = request?.headers.get("x-forwarded-host");
75
+ const fromRequestProto = request?.headers.get("x-forwarded-proto");
76
+ if (fromRequest && fromRequestProto && trustedProxyHeaders) {
77
+ if (validateProxyHeader(fromRequestProto, "proto") && validateProxyHeader(fromRequest, "host")) try {
78
+ return withPath(`${fromRequestProto}://${fromRequest}`, path);
79
+ } catch (_error) {}
80
+ }
81
+ if (request) {
82
+ const url = getOrigin(request.url);
83
+ if (!url) throw new BetterAuthError("Could not get origin from request. Please provide a valid base URL.");
84
+ return withPath(url, path);
85
+ }
86
+ if (typeof window !== "undefined" && window.location) return withPath(window.location.origin, path);
87
+ }
88
+ function getOrigin(url) {
89
+ try {
90
+ const parsedUrl = new URL(url);
91
+ return parsedUrl.origin === "null" ? null : parsedUrl.origin;
92
+ } catch {
93
+ return null;
94
+ }
95
+ }
96
+ function getProtocol(url) {
97
+ try {
98
+ return new URL(url).protocol;
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+ function getHost(url) {
104
+ try {
105
+ return new URL(url).host;
106
+ } catch {
107
+ return null;
108
+ }
109
+ }
110
+ /**
111
+ * Checks if the baseURL config is a dynamic config object
112
+ */
113
+ function isDynamicBaseURLConfig(config) {
114
+ return typeof config === "object" && config !== null && "allowedHosts" in config && Array.isArray(config.allowedHosts);
115
+ }
116
+ /**
117
+ * Check if a value is a `Request`
118
+ * - `instanceof`: works for native Request instances
119
+ * - `toString`: handles where instanceof check fails but the object is still a
120
+ * valid Request (e.g. cross-realm, polyfills). Paired with a shape check so
121
+ * an object that only spoofs `Symbol.toStringTag` without the real shape is
122
+ * rejected before downstream code tries to read `.headers` / `.url`.
123
+ *
124
+ * @param value The value to check
125
+ * @returns `true` if the value is a Request instance
126
+ */
127
+ function isRequestLike(value) {
128
+ if (value instanceof Request) return true;
129
+ if (typeof value !== "object" || value === null || Object.prototype.toString.call(value) !== "[object Request]") return false;
130
+ const v = value;
131
+ return typeof v.url === "string" && typeof v.headers === "object" && v.headers !== null && typeof v.headers.get === "function";
132
+ }
133
+ /**
134
+ * Extracts the host from a `Request` or `Headers`.
135
+ * Honors `x-forwarded-host` only when `trustedProxyHeaders` is enabled,
136
+ * then falls back to the `host` header and finally the request URL.
137
+ */
138
+ function getHostFromSource(source, trustedProxyHeaders) {
139
+ const headers = isRequestLike(source) ? source.headers : source;
140
+ if (trustedProxyHeaders) {
141
+ const forwardedHost = headers.get("x-forwarded-host");
142
+ if (forwardedHost && validateProxyHeader(forwardedHost, "host")) return forwardedHost;
143
+ }
144
+ const host = headers.get("host");
145
+ if (host && validateProxyHeader(host, "host")) return host;
146
+ if (isRequestLike(source)) try {
147
+ return new URL(source.url).host;
148
+ } catch {
149
+ return null;
150
+ }
151
+ return null;
152
+ }
153
+ /**
154
+ * Extracts the protocol from a `Request` or `Headers`.
155
+ * Honors `x-forwarded-proto` only when `trustedProxyHeaders` is enabled,
156
+ * then falls back to the request URL, then to "https".
157
+ */
158
+ function getProtocolFromSource(source, configProtocol, trustedProxyHeaders) {
159
+ if (configProtocol === "http" || configProtocol === "https") return configProtocol;
160
+ const headers = isRequestLike(source) ? source.headers : source;
161
+ if (trustedProxyHeaders) {
162
+ const forwardedProto = headers.get("x-forwarded-proto");
163
+ if (forwardedProto && validateProxyHeader(forwardedProto, "proto")) return forwardedProto;
164
+ }
165
+ if (isRequestLike(source)) try {
166
+ const url = new URL(source.url);
167
+ if (url.protocol === "http:" || url.protocol === "https:") return url.protocol.slice(0, -1);
168
+ } catch {}
169
+ const host = getHostFromSource(source, trustedProxyHeaders);
170
+ if (host && isLoopbackForDevScheme(host)) return "http";
171
+ return "https";
172
+ }
173
+ /**
174
+ * Matches a hostname against a host pattern.
175
+ * Supports wildcard patterns like `*.vercel.app` or `preview-*.myapp.com`.
176
+ *
177
+ * @param host The hostname to test (e.g., "myapp.com", "preview-123.vercel.app")
178
+ * @param pattern The host pattern (e.g., "myapp.com", "*.vercel.app")
179
+ * @returns {boolean} true if the host matches the pattern, false otherwise.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * matchesHostPattern("myapp.com", "myapp.com") // true
184
+ * matchesHostPattern("preview-123.vercel.app", "*.vercel.app") // true
185
+ * matchesHostPattern("preview-123.myapp.com", "preview-*.myapp.com") // true
186
+ * matchesHostPattern("evil.com", "myapp.com") // false
187
+ * ```
188
+ */
189
+ const matchesHostPattern = (host, pattern) => {
190
+ if (!host || !pattern) return false;
191
+ const normalizedHost = host.replace(/^https?:\/\//, "").split("/")[0].toLowerCase();
192
+ const normalizedPattern = pattern.replace(/^https?:\/\//, "").split("/")[0].toLowerCase();
193
+ if (normalizedPattern.includes("*") || normalizedPattern.includes("?")) return wildcardMatch(normalizedPattern)(normalizedHost);
194
+ return normalizedHost.toLowerCase() === normalizedPattern.toLowerCase();
195
+ };
196
+ /**
197
+ * Resolves the base URL from a dynamic config based on the incoming request.
198
+ * Validates the derived host against the allowedHosts allowlist.
199
+ *
200
+ * @param config The dynamic base URL config
201
+ * @param request The incoming request
202
+ * @param basePath The base path to append
203
+ * @returns The resolved base URL with path
204
+ * @throws BetterAuthError if host is not in allowedHosts and no fallback is set
205
+ */
206
+ function resolveDynamicBaseURL(config, source, basePath, trustedProxyHeaders) {
207
+ const host = getHostFromSource(source, trustedProxyHeaders);
208
+ if (!host) {
209
+ if (config.fallback) return withPath(config.fallback, basePath);
210
+ throw new BetterAuthError("Could not determine host from request headers. Please provide a fallback URL in your baseURL config.");
211
+ }
212
+ if (config.allowedHosts.some((pattern) => matchesHostPattern(host, pattern))) return withPath(`${getProtocolFromSource(source, config.protocol, trustedProxyHeaders)}://${host}`, basePath);
213
+ if (config.fallback) return withPath(config.fallback, basePath);
214
+ throw new BetterAuthError(`Host "${host}" is not in the allowed hosts list. Allowed hosts: ${config.allowedHosts.join(", ")}. Add this host to your allowedHosts config or provide a fallback URL.`);
215
+ }
216
+ /**
217
+ * Resolves the base URL from any config type (static string or dynamic object).
218
+ * This is the main entry point for base URL resolution.
219
+ *
220
+ * @param config The base URL config (string or object)
221
+ * @param basePath The base path to append
222
+ * @param request Optional request for dynamic resolution
223
+ * @param loadEnv Whether to load from environment variables
224
+ * @param trustedProxyHeaders Whether to trust proxy headers (for legacy behavior)
225
+ * @returns The resolved base URL with path
226
+ */
227
+ function resolveBaseURL(config, basePath, source, loadEnv, trustedProxyHeaders) {
228
+ if (isDynamicBaseURLConfig(config)) {
229
+ if (source) return resolveDynamicBaseURL(config, source, basePath, trustedProxyHeaders);
230
+ if (config.fallback) return withPath(config.fallback, basePath);
231
+ return getBaseURL(void 0, basePath, void 0, loadEnv, trustedProxyHeaders);
232
+ }
233
+ const request = isRequestLike(source) ? source : void 0;
234
+ if (typeof config === "string") return getBaseURL(config, basePath, request, loadEnv, trustedProxyHeaders);
235
+ return getBaseURL(void 0, basePath, request, loadEnv, trustedProxyHeaders);
236
+ }
237
+ //#endregion
238
+ export { getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL, trimTrailingSlashes };
@@ -0,0 +1,44 @@
1
+ import { APIError } from "@better-auth/core/error";
2
+ //#region src/utils/validate-user-info.ts
3
+ function assertValidUserInfoSource(source) {
4
+ if (!source?.method) throw new APIError("FORBIDDEN", {
5
+ code: "validation_source_missing",
6
+ message: "User validation source is required"
7
+ });
8
+ if (source.method === "oauth" && !source.oauth?.providerId) throw new APIError("FORBIDDEN", {
9
+ code: "validation_source_missing",
10
+ message: "OAuth user validation source requires oauth.providerId"
11
+ });
12
+ if ((source.method === "sso-oidc" || source.method === "sso-saml") && !source.sso?.providerId) throw new APIError("FORBIDDEN", {
13
+ code: "validation_source_missing",
14
+ message: "SSO user validation source requires sso.providerId"
15
+ });
16
+ }
17
+ /**
18
+ * Invoke the application's `user.validateUserInfo` gate and throw a `403`
19
+ * {@link APIError} if it rejects.
20
+ *
21
+ * Fails closed: if the hook throws, provisioning is rejected rather than
22
+ * silently allowed.
23
+ */
24
+ async function assertValidUserInfo(ctx, data) {
25
+ const validate = ctx.context.options.user?.validateUserInfo;
26
+ if (!validate) return;
27
+ assertValidUserInfoSource(data.source);
28
+ let result;
29
+ try {
30
+ result = await validate(data, ctx);
31
+ } catch (error) {
32
+ ctx.context.logger.error("validateUserInfo callback threw", error);
33
+ throw new APIError("FORBIDDEN", {
34
+ code: "validation_failed",
35
+ message: "User validation failed"
36
+ });
37
+ }
38
+ if (result?.error) throw new APIError("FORBIDDEN", {
39
+ code: result.error,
40
+ message: result.errorDescription || result.error
41
+ });
42
+ }
43
+ //#endregion
44
+ export { assertValidUserInfo, assertValidUserInfoSource };