@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,130 @@
1
+ import * as _$_better_auth_core0 from "@better-auth/core";
2
+ import { SecretConfig } from "@better-auth/core";
3
+ import * as _$better_call0 from "better-call";
4
+ import * as z from "zod";
5
+
6
+ //#region src/plugins/oauth-proxy/index.d.ts
7
+ declare module "@better-auth/core" {
8
+ interface BetterAuthPluginRegistry<AuthOptions, Options> {
9
+ "oauth-proxy": {
10
+ creator: typeof oAuthProxy;
11
+ };
12
+ }
13
+ }
14
+ interface OAuthProxyOptions {
15
+ /**
16
+ * The current URL of the application.
17
+ * The plugin will attempt to infer the current URL from your environment
18
+ * by checking the base URL from popular hosting providers,
19
+ * from the request URL if invoked by a client,
20
+ * or as a fallback, from the `baseURL` in your auth config.
21
+ * If the URL is not inferred correctly, you can provide a value here."
22
+ */
23
+ currentURL?: string | undefined;
24
+ /**
25
+ * If a request in a production url it won't be proxied.
26
+ *
27
+ * default to `BETTER_AUTH_URL`
28
+ */
29
+ productionURL?: string | undefined;
30
+ /**
31
+ * Maximum age in seconds for the encrypted payload.
32
+ * Payloads older than this will be rejected to prevent replay attacks.
33
+ *
34
+ * Keep this value short (e.g., 30-60 seconds) to minimize the window
35
+ * for potential replay attacks while still allowing normal OAuth flows.
36
+ *
37
+ * @default 60 (1 minute)
38
+ */
39
+ maxAge?: number | undefined;
40
+ /**
41
+ * A dedicated secret used to encrypt and decrypt data passed between
42
+ * servers during the OAuth proxy flow.
43
+ *
44
+ * When set, this secret is used **instead of** the global
45
+ * `BETTER_AUTH_SECRET` for all OAuth proxy encryption operations.
46
+ * This limits the blast radius if the secret is shared across
47
+ * environments (production, preview, development): a leaked proxy
48
+ * secret cannot be used to forge sessions or decrypt other data
49
+ * protected by the main secret.
50
+ *
51
+ * All environments participating in the OAuth proxy flow must share
52
+ * the same `secret` value.
53
+ */
54
+ secret?: string | SecretConfig | undefined;
55
+ }
56
+ declare const oAuthProxy: <O extends OAuthProxyOptions>(opts?: O) => {
57
+ id: "oauth-proxy";
58
+ version: string;
59
+ options: NoInfer<O>;
60
+ endpoints: {
61
+ /**
62
+ * @deprecated OAuth proxy callbacks now use `/callback/:id/oauth-proxy`.
63
+ * This endpoint will be removed in the next minor release.
64
+ */
65
+ oAuthProxy: _$better_call0.StrictEndpoint<"/oauth-proxy-callback", {
66
+ method: "GET";
67
+ operationId: string;
68
+ query: z.ZodObject<{
69
+ callbackURL: z.ZodString;
70
+ profile: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strip>;
72
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<void>>[];
73
+ metadata: {
74
+ openapi: {
75
+ operationId: string;
76
+ deprecated: boolean;
77
+ description: string;
78
+ parameters: ({
79
+ in: "query";
80
+ name: string;
81
+ required: true;
82
+ description: string;
83
+ } | {
84
+ in: "query";
85
+ name: string;
86
+ required: false;
87
+ description: string;
88
+ })[];
89
+ responses: {
90
+ 302: {
91
+ description: string;
92
+ headers: {
93
+ Location: {
94
+ description: string;
95
+ schema: {
96
+ type: string;
97
+ };
98
+ };
99
+ };
100
+ };
101
+ };
102
+ };
103
+ };
104
+ }, never>;
105
+ oAuthProxyCompletion: _$better_call0.StrictEndpoint<"/callback/:id/oauth-proxy", {
106
+ method: "GET";
107
+ operationId: string;
108
+ query: z.ZodObject<{
109
+ callbackURL: z.ZodString;
110
+ profile: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strip>;
112
+ use: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<void>>[];
113
+ metadata: {
114
+ scope: "http";
115
+ };
116
+ }, never>;
117
+ };
118
+ hooks: {
119
+ before: {
120
+ matcher(context: _$_better_auth_core0.HookEndpointContext): boolean;
121
+ handler: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<void>>;
122
+ }[];
123
+ after: {
124
+ matcher(context: _$_better_auth_core0.HookEndpointContext): boolean;
125
+ handler: _$better_call0.Middleware<_$better_call0.MiddlewareOptions, (inputContext: _$better_call0.MiddlewareInputContext<_$better_call0.MiddlewareOptions>) => Promise<void>>;
126
+ }[];
127
+ };
128
+ };
129
+ //#endregion
130
+ export { OAuthProxyOptions, oAuthProxy };
@@ -0,0 +1,407 @@
1
+ import { isAPIError } from "../../utils/is-api-error.mjs";
2
+ import { getOrigin } from "../../utils/url.mjs";
3
+ import { originCheck } from "../../api/middlewares/origin-check.mjs";
4
+ import { parseSetCookieHeader } from "../../cookies/cookie-utils.mjs";
5
+ import { symmetricDecrypt, symmetricEncrypt } from "../../crypto/index.mjs";
6
+ import { setSessionCookie } from "../../cookies/index.mjs";
7
+ import { resolveOAuthAccountKey, toOAuthProfileRecord } from "../../oauth2/account-key.mjs";
8
+ import { redirectOnError } from "../../oauth2/errors.mjs";
9
+ import { getOAuthCallbackPath } from "../../oauth2/utils.mjs";
10
+ import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
11
+ import { setOAuthState } from "../../api/state/oauth.mjs";
12
+ import { parseGenericState } from "../../state.mjs";
13
+ import { PACKAGE_VERSION } from "../../version.mjs";
14
+ import { parseJSON } from "../../client/parser.mjs";
15
+ import { checkSkipProxy, resolveCurrentURL, stripTrailingSlash } from "./utils.mjs";
16
+ import { accountSchema, userSchema } from "@better-auth/core/db";
17
+ import { safeJSONParse } from "@better-auth/core/utils/json";
18
+ import { defu } from "defu";
19
+ import { createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
20
+ import * as z from "zod";
21
+ //#region src/plugins/oauth-proxy/index.ts
22
+ /**
23
+ * Passthrough payload containing OAuth profile data.
24
+ * Used to transfer OAuth credentials from production to preview
25
+ * without creating user/session on production.
26
+ * @internal
27
+ */
28
+ const passthroughPayloadSchema = z.looseObject({
29
+ userInfo: z.looseObject(userSchema.omit({
30
+ createdAt: true,
31
+ updatedAt: true
32
+ }).shape),
33
+ account: z.looseObject(accountSchema.omit({
34
+ id: true,
35
+ userId: true,
36
+ createdAt: true,
37
+ updatedAt: true
38
+ }).shape),
39
+ profile: z.record(z.string(), z.unknown()).optional(),
40
+ state: z.string().min(1),
41
+ callbackURL: z.string().min(1),
42
+ newUserURL: z.string().optional(),
43
+ errorURL: z.string().optional(),
44
+ disableSignUp: z.boolean().optional(),
45
+ timestamp: z.number()
46
+ });
47
+ const restoreOAuthProxyState = async (ctx, state) => {
48
+ try {
49
+ const stateData = await parseGenericState(ctx, state, { skipStateCookieCheck: true });
50
+ await setOAuthState(stateData);
51
+ return stateData;
52
+ } catch (e) {
53
+ ctx.context.logger.warn("OAuth proxy state missing or invalid", e);
54
+ return null;
55
+ }
56
+ };
57
+ const oauthProxyQuerySchema = z.object({
58
+ callbackURL: z.string().meta({ description: "The URL to redirect to after the proxy" }),
59
+ profile: z.string().optional().meta({ description: "Encrypted OAuth profile data" })
60
+ });
61
+ const oauthCallbackQuerySchema = z.object({
62
+ code: z.string().optional(),
63
+ error: z.string().optional(),
64
+ user: z.string().optional()
65
+ });
66
+ const oAuthProxy = (opts) => {
67
+ const maxAge = opts?.maxAge ?? 60;
68
+ const getEncryptionKey = (ctx) => opts?.secret ?? ctx.context.secretConfig;
69
+ const oauthProxyCompletion = createAuthEndpoint("/callback/:id/oauth-proxy", {
70
+ method: "GET",
71
+ operationId: "oauthProxyCompletion",
72
+ query: oauthProxyQuerySchema,
73
+ use: [originCheck((ctx) => ctx.query.callbackURL)],
74
+ metadata: { scope: "http" }
75
+ }, async (ctx) => {
76
+ const baseURLStr = typeof ctx.context.options.baseURL === "string" ? ctx.context.options.baseURL : getOrigin(ctx.context.baseURL) || "";
77
+ const defaultErrorURL = ctx.context.options.onAPIError?.errorURL || `${stripTrailingSlash(baseURLStr)}/api/auth/error`;
78
+ const encryptedProfile = ctx.query.profile;
79
+ if (!encryptedProfile) {
80
+ ctx.context.logger.error("OAuth proxy callback missing profile data");
81
+ throw redirectOnError(ctx, defaultErrorURL, "missing_profile");
82
+ }
83
+ let decryptedPayload;
84
+ try {
85
+ decryptedPayload = await symmetricDecrypt({
86
+ key: getEncryptionKey(ctx),
87
+ data: encryptedProfile
88
+ });
89
+ } catch (e) {
90
+ ctx.context.logger.error("Failed to decrypt OAuth proxy profile", e);
91
+ throw redirectOnError(ctx, defaultErrorURL, "invalid_profile");
92
+ }
93
+ let payload;
94
+ try {
95
+ payload = passthroughPayloadSchema.parse(parseJSON(decryptedPayload));
96
+ } catch (e) {
97
+ ctx.context.logger.error("Failed to parse OAuth proxy payload", e);
98
+ throw redirectOnError(ctx, defaultErrorURL, "invalid_payload");
99
+ }
100
+ const errorURL = payload.errorURL || defaultErrorURL;
101
+ if (ctx.path?.startsWith("/callback/") && ctx.params.id !== payload.account.providerId) {
102
+ ctx.context.logger.warn("OAuth proxy callback provider mismatch");
103
+ throw redirectOnError(ctx, errorURL, "provider_mismatch");
104
+ }
105
+ const age = (Date.now() - payload.timestamp) / 1e3;
106
+ if (age > maxAge || age < -10) {
107
+ ctx.context.logger.error(`OAuth proxy payload expired or invalid (age: ${age}s, maxAge: ${maxAge}s)`);
108
+ throw redirectOnError(ctx, errorURL, "payload_expired");
109
+ }
110
+ if (!await restoreOAuthProxyState(ctx, payload.state)) throw redirectOnError(ctx, errorURL, "state_mismatch");
111
+ let result;
112
+ try {
113
+ result = await handleOAuthUserInfo(ctx, {
114
+ userInfo: payload.userInfo,
115
+ account: payload.account,
116
+ callbackURL: payload.callbackURL,
117
+ disableSignUp: payload.disableSignUp,
118
+ source: {
119
+ method: "oauth",
120
+ oauth: {
121
+ providerId: payload.account.providerId,
122
+ profile: payload.profile
123
+ }
124
+ }
125
+ });
126
+ } catch (e) {
127
+ if (isAPIError(e) && e.body?.code) throw redirectOnError(ctx, errorURL, e.body.code, e.body.message);
128
+ throw e;
129
+ }
130
+ if (result.error) {
131
+ ctx.context.logger.error("OAuth proxy callback error", result.error);
132
+ throw redirectOnError(ctx, errorURL, result.error.split(" ").join("_"));
133
+ }
134
+ if (!result.data) {
135
+ ctx.context.logger.error("OAuth proxy callback missing session data");
136
+ throw redirectOnError(ctx, errorURL, "user_creation_failed");
137
+ }
138
+ await setSessionCookie(ctx, result.data);
139
+ const finalURL = result.isRegister ? payload.newUserURL || payload.callbackURL : payload.callbackURL;
140
+ throw ctx.redirect(finalURL);
141
+ });
142
+ return {
143
+ id: "oauth-proxy",
144
+ version: PACKAGE_VERSION,
145
+ options: opts,
146
+ endpoints: {
147
+ /**
148
+ * @deprecated OAuth proxy callbacks now use `/callback/:id/oauth-proxy`.
149
+ * This endpoint will be removed in the next minor release.
150
+ */
151
+ oAuthProxy: createAuthEndpoint("/oauth-proxy-callback", {
152
+ method: "GET",
153
+ operationId: "oauthProxyCallback",
154
+ query: oauthProxyQuerySchema,
155
+ use: [originCheck((ctx) => ctx.query.callbackURL)],
156
+ metadata: { openapi: {
157
+ operationId: "oauthProxyCallback",
158
+ deprecated: true,
159
+ description: "OAuth Proxy Callback",
160
+ parameters: [{
161
+ in: "query",
162
+ name: "callbackURL",
163
+ required: true,
164
+ description: "The URL to redirect to after the proxy"
165
+ }, {
166
+ in: "query",
167
+ name: "profile",
168
+ required: false,
169
+ description: "Encrypted OAuth profile data"
170
+ }],
171
+ responses: { 302: {
172
+ description: "Redirect",
173
+ headers: { Location: {
174
+ description: "The URL to redirect to",
175
+ schema: { type: "string" }
176
+ } }
177
+ } }
178
+ } }
179
+ }, async (ctx) => oauthProxyCompletion({
180
+ ...ctx,
181
+ params: { id: "oauth-proxy" }
182
+ })),
183
+ oAuthProxyCompletion: oauthProxyCompletion
184
+ },
185
+ hooks: {
186
+ before: [{
187
+ matcher(context) {
188
+ return !!context.path?.startsWith("/sign-in/social");
189
+ },
190
+ handler: createAuthMiddleware(async (ctx) => {
191
+ if (checkSkipProxy(ctx, opts)) return;
192
+ const providerId = ctx.body?.provider;
193
+ if (!providerId) return;
194
+ const currentURL = resolveCurrentURL(ctx, opts);
195
+ const productionURL = opts?.productionURL;
196
+ const originalCallbackURL = ctx.body?.callbackURL || ctx.context.baseURL;
197
+ if (productionURL) {
198
+ const productionBaseURL = `${stripTrailingSlash(productionURL)}${ctx.context.options.basePath || "/api/auth"}`;
199
+ ctx.context.baseURL = productionBaseURL;
200
+ }
201
+ const newCallbackURL = `${stripTrailingSlash(currentURL.origin)}${ctx.context.options.basePath || "/api/auth"}/callback/${providerId}/oauth-proxy?callbackURL=${encodeURIComponent(originalCallbackURL)}`;
202
+ ctx.body.callbackURL = newCallbackURL;
203
+ })
204
+ }, {
205
+ matcher(context) {
206
+ return context.path === "/callback/:id";
207
+ },
208
+ handler: createAuthMiddleware(async (ctx) => {
209
+ const callbackParams = defu(ctx.query, ctx.body);
210
+ const state = callbackParams.state;
211
+ if (!state || typeof state !== "string") return;
212
+ let statePackage;
213
+ try {
214
+ statePackage = parseJSON(await symmetricDecrypt({
215
+ key: getEncryptionKey(ctx),
216
+ data: state
217
+ }));
218
+ } catch {
219
+ ctx.context.logger.debug("OAuth proxy: could not decrypt state package, falling back to regular callback");
220
+ return;
221
+ }
222
+ if (!statePackage.isOAuthProxy || !statePackage.state || !statePackage.stateCookie) {
223
+ ctx.context.logger.warn("Invalid OAuth proxy state package");
224
+ return;
225
+ }
226
+ const query = oauthCallbackQuerySchema.safeParse(callbackParams);
227
+ if (!query.success) {
228
+ ctx.context.logger.warn("Invalid OAuth callback query", query.error);
229
+ return;
230
+ }
231
+ const { code, error, user: userData } = query.data;
232
+ let stateData;
233
+ try {
234
+ stateData = parseJSON(await symmetricDecrypt({
235
+ key: getEncryptionKey(ctx),
236
+ data: statePackage.stateCookie
237
+ }));
238
+ } catch (e) {
239
+ ctx.context.logger.error("Failed to decrypt OAuth proxy state cookie:", e);
240
+ return;
241
+ }
242
+ const errorURL = stateData.errorURL || ctx.context.options.onAPIError?.errorURL || `${ctx.context.baseURL}/error`;
243
+ if (stateData.oauthState !== void 0 && stateData.oauthState !== statePackage.state) {
244
+ ctx.context.logger.error("OAuth proxy state binding mismatch");
245
+ throw redirectOnError(ctx, errorURL, "state_mismatch");
246
+ }
247
+ if (error) throw redirectOnError(ctx, errorURL, error);
248
+ if (!code) {
249
+ ctx.context.logger.warn("OAuth callback missing authorization code");
250
+ throw redirectOnError(ctx, errorURL, "no_code");
251
+ }
252
+ const providerId = ctx.params?.id;
253
+ const provider = ctx.context.socialProviders.find((p) => p.id === providerId);
254
+ if (!provider) {
255
+ ctx.context.logger.warn("OAuth provider not found", { providerId });
256
+ throw redirectOnError(ctx, errorURL, "oauth_provider_not_found");
257
+ }
258
+ let tokens;
259
+ try {
260
+ tokens = await provider.validateAuthorizationCode({
261
+ code,
262
+ codeVerifier: stateData.codeVerifier,
263
+ redirectURI: `${ctx.context.baseURL}${getOAuthCallbackPath(provider)}`
264
+ });
265
+ } catch (e) {
266
+ ctx.context.logger.error("Failed to validate authorization code", e);
267
+ throw redirectOnError(ctx, errorURL, "invalid_code");
268
+ }
269
+ if (!tokens) throw redirectOnError(ctx, errorURL, "invalid_code");
270
+ const parsedUserData = userData ? safeJSONParse(userData) : null;
271
+ const userInfoResult = await provider.getUserInfo({
272
+ ...tokens,
273
+ /**
274
+ * The user object from the provider
275
+ * This is only available for some providers like Apple
276
+ */
277
+ user: parsedUserData ?? void 0
278
+ });
279
+ const userInfo = userInfoResult?.user;
280
+ if (!userInfo) {
281
+ ctx.context.logger.error("Unable to get user info from provider");
282
+ throw redirectOnError(ctx, errorURL, "unable_to_get_user_info");
283
+ }
284
+ if (!userInfo.email) {
285
+ ctx.context.logger.error("Provider did not return email");
286
+ throw redirectOnError(ctx, errorURL, "email_not_found");
287
+ }
288
+ let accountKey;
289
+ try {
290
+ accountKey = await resolveOAuthAccountKey(provider, tokens, userInfoResult.data);
291
+ } catch (error) {
292
+ ctx.context.logger.error("Unable to derive provider account identity", {
293
+ providerId: provider.id,
294
+ error
295
+ });
296
+ throw redirectOnError(ctx, errorURL, "unable_to_get_user_info");
297
+ }
298
+ const providerProfile = toOAuthProfileRecord(userInfoResult.data);
299
+ const proxyCallbackURL = new URL(stateData.callbackURL);
300
+ const finalCallbackURL = proxyCallbackURL.searchParams.get("callbackURL") || stateData.callbackURL;
301
+ const payload = {
302
+ userInfo: {
303
+ id: accountKey.accountId,
304
+ email: userInfo.email,
305
+ name: userInfo.name || "",
306
+ image: userInfo.image,
307
+ emailVerified: userInfo.emailVerified
308
+ },
309
+ profile: providerProfile,
310
+ account: {
311
+ ...accountKey,
312
+ accessToken: tokens.accessToken,
313
+ refreshToken: tokens.refreshToken,
314
+ idToken: tokens.idToken,
315
+ accessTokenExpiresAt: tokens.accessTokenExpiresAt,
316
+ refreshTokenExpiresAt: tokens.refreshTokenExpiresAt,
317
+ scope: tokens.scopes?.join(",")
318
+ },
319
+ state: statePackage.state,
320
+ callbackURL: finalCallbackURL,
321
+ newUserURL: stateData.newUserURL,
322
+ errorURL: stateData.errorURL,
323
+ disableSignUp: provider.disableImplicitSignUp && !stateData.requestSignUp || provider.options?.disableSignUp,
324
+ timestamp: Date.now()
325
+ };
326
+ const encryptedPayload = await symmetricEncrypt({
327
+ key: getEncryptionKey(ctx),
328
+ data: JSON.stringify(payload)
329
+ });
330
+ proxyCallbackURL.searchParams.set("profile", encryptedPayload);
331
+ throw ctx.redirect(proxyCallbackURL.toString());
332
+ })
333
+ }],
334
+ after: [{
335
+ matcher(context) {
336
+ return !!context.path?.startsWith("/sign-in/social");
337
+ },
338
+ handler: createAuthMiddleware(async (ctx) => {
339
+ if (checkSkipProxy(ctx, opts)) return;
340
+ const signInResponse = ctx.context.returned;
341
+ if (!signInResponse || typeof signInResponse !== "object" || !("url" in signInResponse)) return;
342
+ const { url: providerURL } = signInResponse;
343
+ if (typeof providerURL !== "string") return;
344
+ const oauthURL = new URL(providerURL);
345
+ const originalState = oauthURL.searchParams.get("state");
346
+ if (!originalState) return;
347
+ try {
348
+ let plaintextState;
349
+ if (ctx.context.oauthConfig.storeStateStrategy === "cookie") {
350
+ const setCookieHeader = ctx.context.responseHeaders?.get("set-cookie");
351
+ if (setCookieHeader) {
352
+ const oauthStateCookie = ctx.context.createAuthCookie("oauth_state");
353
+ const encryptedCookieValue = parseSetCookieHeader(setCookieHeader).get(oauthStateCookie.name)?.value;
354
+ if (encryptedCookieValue) plaintextState = await symmetricDecrypt({
355
+ key: ctx.context.secretConfig,
356
+ data: encryptedCookieValue
357
+ });
358
+ }
359
+ } else plaintextState = (await ctx.context.internalAdapter.findVerificationValue(originalState))?.value;
360
+ if (!plaintextState) {
361
+ ctx.context.logger.warn("No OAuth state found for proxy");
362
+ return;
363
+ }
364
+ const statePackage = {
365
+ state: originalState,
366
+ stateCookie: await symmetricEncrypt({
367
+ key: getEncryptionKey(ctx),
368
+ data: plaintextState
369
+ }),
370
+ isOAuthProxy: true
371
+ };
372
+ const encryptedPackage = await symmetricEncrypt({
373
+ key: getEncryptionKey(ctx),
374
+ data: JSON.stringify(statePackage)
375
+ });
376
+ oauthURL.searchParams.set("state", encryptedPackage);
377
+ ctx.context.returned = {
378
+ ...signInResponse,
379
+ url: oauthURL.toString()
380
+ };
381
+ } catch (e) {
382
+ ctx.context.logger.error("Failed to prepare OAuth proxy state:", e);
383
+ }
384
+ })
385
+ }, {
386
+ matcher(context) {
387
+ return context.path === "/callback/:id";
388
+ },
389
+ handler: createAuthMiddleware(async (ctx) => {
390
+ const location = ctx.context.responseHeaders?.get("location");
391
+ if (!location?.includes("/oauth-proxy?callbackURL") && !location?.includes("/oauth-proxy-callback?callbackURL") || !location.startsWith("http")) return;
392
+ const productionOrigin = getOrigin(opts?.productionURL || (typeof ctx.context.options.baseURL === "string" ? ctx.context.options.baseURL : void 0) || ctx.context.baseURL);
393
+ const locationURL = new URL(location);
394
+ if (locationURL.origin === productionOrigin) {
395
+ const newLocation = locationURL.searchParams.get("callbackURL");
396
+ if (!newLocation) return;
397
+ ctx.setHeader("location", newLocation);
398
+ return;
399
+ }
400
+ ctx.context.logger.warn("OAuth proxy: cross-origin callback reached after hook unexpectedly");
401
+ })
402
+ }]
403
+ }
404
+ };
405
+ };
406
+ //#endregion
407
+ export { oAuthProxy };
@@ -0,0 +1,55 @@
1
+ import { getOrigin, trimTrailingSlashes } from "../../utils/url.mjs";
2
+ import { env } from "@better-auth/core/env";
3
+ //#region src/plugins/oauth-proxy/utils.ts
4
+ /**
5
+ * Strip trailing slashes from URL to prevent double slashes
6
+ */
7
+ function stripTrailingSlash(url) {
8
+ if (!url) return "";
9
+ return trimTrailingSlashes(url);
10
+ }
11
+ /**
12
+ * Get base URL from vendor-specific environment variables
13
+ */
14
+ function getVendorBaseURL() {
15
+ const vercel = env.VERCEL_URL ? `https://${env.VERCEL_URL}` : void 0;
16
+ const netlify = env.NETLIFY_URL;
17
+ const render = env.RENDER_URL;
18
+ const aws = env.AWS_LAMBDA_FUNCTION_NAME;
19
+ const google = env.GOOGLE_CLOUD_FUNCTION_NAME;
20
+ const azure = env.AZURE_FUNCTION_NAME;
21
+ return vercel || netlify || render || aws || google || azure;
22
+ }
23
+ /**
24
+ * Resolve the current URL from various sources.
25
+ *
26
+ * The request URL host can come from an untrusted source (`Host` / forwarded host),
27
+ * and this origin becomes the receiver for the encrypted OAuth profile replay.
28
+ * So a request-derived origin is only honored when it is an explicitly trusted
29
+ * origin; otherwise resolution falls back to the configured platform/base URL,
30
+ * never the raw request host. An explicit `opts.currentURL` and the vendor/base
31
+ * URLs are configured by the developer and trusted as-is.
32
+ */
33
+ function resolveCurrentURL(ctx, opts) {
34
+ if (opts?.currentURL) return new URL(opts.currentURL);
35
+ const requestURL = ctx.request?.url;
36
+ if (requestURL) {
37
+ const origin = getOrigin(requestURL);
38
+ if (origin && ctx.context.isTrustedOrigin(origin)) return new URL(requestURL);
39
+ }
40
+ const vendorBaseURL = getVendorBaseURL();
41
+ return new URL(vendorBaseURL && getOrigin(vendorBaseURL) ? vendorBaseURL : ctx.context.baseURL);
42
+ }
43
+ /**
44
+ * Check if the proxy should be skipped for this request
45
+ */
46
+ function checkSkipProxy(ctx, opts) {
47
+ if (ctx.request?.headers.get("x-skip-oauth-proxy")) return true;
48
+ const productionURL = opts?.productionURL || env.BETTER_AUTH_URL || ctx.context.baseURL;
49
+ if (!productionURL) return false;
50
+ const currentURL = opts?.currentURL || ctx.request?.url || getVendorBaseURL();
51
+ if (!currentURL) return false;
52
+ return getOrigin(productionURL) === getOrigin(currentURL);
53
+ }
54
+ //#endregion
55
+ export { checkSkipProxy, resolveCurrentURL, stripTrailingSlash };