@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,96 @@
1
+ import { Account, User } from "../types/models.mjs";
2
+ import { GenericEndpointContext, UserProvisioningSource } from "@better-auth/core";
3
+
4
+ //#region src/oauth2/link-account.d.ts
5
+ declare function handleOAuthUserInfo(c: GenericEndpointContext, opts: {
6
+ userInfo: Omit<User, "createdAt" | "updatedAt">;
7
+ account: Omit<Account, "id" | "userId" | "createdAt" | "updatedAt">;
8
+ callbackURL?: string | undefined;
9
+ disableSignUp?: boolean | undefined;
10
+ overrideUserInfo?: boolean | undefined;
11
+ isTrustedProvider?: boolean | undefined;
12
+ trustProviderByName?: boolean | undefined;
13
+ source?: UserProvisioningSource | undefined;
14
+ selectedUser?: {
15
+ userId: string;
16
+ profile: "preserve" | "update";
17
+ } | undefined;
18
+ deferNonDatabaseWrites?: boolean | undefined;
19
+ requireExactAccountBinding?: boolean | undefined;
20
+ }): Promise<{
21
+ error: string;
22
+ data: null;
23
+ isRegister: boolean;
24
+ accountCookie?: undefined;
25
+ } | {
26
+ error: string;
27
+ data: null;
28
+ isRegister?: undefined;
29
+ accountCookie?: undefined;
30
+ } | {
31
+ data: {
32
+ session: {
33
+ id: string;
34
+ createdAt: Date;
35
+ updatedAt: Date;
36
+ userId: string;
37
+ expiresAt: Date;
38
+ token: string;
39
+ ipAddress?: string | null | undefined;
40
+ userAgent?: string | null | undefined;
41
+ };
42
+ user: {
43
+ id: string;
44
+ createdAt: Date;
45
+ updatedAt: Date;
46
+ email: string;
47
+ emailVerified: boolean;
48
+ name: string;
49
+ image?: string | null | undefined;
50
+ };
51
+ };
52
+ error: null;
53
+ isRegister: boolean;
54
+ accountCookie: {
55
+ id: string;
56
+ createdAt: Date;
57
+ updatedAt: Date;
58
+ providerId: string;
59
+ accountId: string;
60
+ userId: string;
61
+ accessToken?: string | null | undefined;
62
+ refreshToken?: string | null | undefined;
63
+ idToken?: string | null | undefined;
64
+ accessTokenExpiresAt?: Date | null | undefined;
65
+ refreshTokenExpiresAt?: Date | null | undefined;
66
+ scope?: string | null | undefined;
67
+ password?: string | null | undefined;
68
+ } | null;
69
+ }>;
70
+ /**
71
+ * Provider profile a freshly linked account may copy onto the local user.
72
+ * `email` and `emailVerified` are identity anchors and are stripped before
73
+ * the remaining fields are written. Provider identity is resolved separately
74
+ * from the raw profile through the provider's account-key contract.
75
+ */
76
+ type LinkedProviderProfile = {
77
+ name?: string | undefined;
78
+ email?: string | null | undefined;
79
+ emailVerified?: boolean | undefined;
80
+ image?: string | null | undefined;
81
+ };
82
+ /**
83
+ * Apply the `account.accountLinking.updateUserInfoOnLink` policy: when enabled,
84
+ * copy the freshly linked provider's profile onto the local user, matching the
85
+ * field set persisted on sign-up. The local `email` and `emailVerified` are
86
+ * never changed, so a link can't rebind the account's identity, and
87
+ * `updateUser` drops `undefined` fields, so a provider that omits one leaves
88
+ * the existing column intact.
89
+ *
90
+ * Returns the updated user so a caller that issues a session can seed the
91
+ * cookie cache with the fresh row. Returns `undefined` when the policy is
92
+ * disabled or the update fails: a failed profile sync must not abort the link.
93
+ */
94
+ declare function applyUpdateUserInfoOnLink(c: GenericEndpointContext, userId: string, userInfo: LinkedProviderProfile): Promise<User | undefined>;
95
+ //#endregion
96
+ export { applyUpdateUserInfoOnLink, handleOAuthUserInfo };
@@ -0,0 +1,329 @@
1
+ import { isAPIError } from "../utils/is-api-error.mjs";
2
+ import { parseAdditionalUserInputFromProviderProfile } from "../db/schema.mjs";
3
+ import { setAccountCookie } from "../cookies/session-store.mjs";
4
+ import { assertValidUserInfo } from "../utils/validate-user-info.mjs";
5
+ import { OAUTH_CALLBACK_ERROR_CODES, redirectOnError } from "./errors.mjs";
6
+ import { setTokenUtil } from "./utils.mjs";
7
+ import { createEmailVerificationToken } from "../api/routes/email-verification.mjs";
8
+ import { queueAfterTransactionHook, runWithTransaction } from "@better-auth/core/context";
9
+ import { isDevelopment } from "@better-auth/core/env";
10
+ import { APIError } from "@better-auth/core/error";
11
+ //#region src/oauth2/link-account.ts
12
+ async function handleOAuthUserInfo(c, opts) {
13
+ const { userInfo, account, callbackURL, disableSignUp, overrideUserInfo } = opts;
14
+ const source = opts.source ?? {
15
+ method: "oauth",
16
+ oauth: { providerId: account.providerId }
17
+ };
18
+ const requireExactAccountBinding = !!opts.selectedUser || opts.requireExactAccountBinding === true;
19
+ let pendingAccountCookie = null;
20
+ const accountOwner = await c.context.internalAdapter.findAccountOwnerByKey({
21
+ providerId: account.providerId,
22
+ accountId: account.accountId
23
+ }).catch((e) => {
24
+ c.context.logger.error("Better auth was unable to query your database.\nError: ", e);
25
+ redirectOnError(c, c.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`, "internal_server_error");
26
+ });
27
+ if (accountOwner?.kind === "orphaned") {
28
+ c.context.logger.error("OAuth account references a missing user. Repair the account before retrying authentication.");
29
+ return {
30
+ error: "unable to link account",
31
+ data: null,
32
+ isRegister: false
33
+ };
34
+ }
35
+ const dbUser = await (async () => {
36
+ if (accountOwner?.kind === "owned") {
37
+ if (opts.selectedUser && accountOwner.user.id !== opts.selectedUser.userId) throw new APIError("CONFLICT", {
38
+ code: "account_ownership_conflict",
39
+ message: "Account is already linked to another user"
40
+ });
41
+ return {
42
+ user: accountOwner.user,
43
+ linkedAccount: accountOwner.account,
44
+ accounts: [accountOwner.account]
45
+ };
46
+ }
47
+ if (opts.selectedUser) {
48
+ const selectedUser = await c.context.internalAdapter.findUserById(opts.selectedUser.userId);
49
+ if (!selectedUser) throw new APIError("NOT_FOUND", {
50
+ code: "user_not_found",
51
+ message: "User not found"
52
+ });
53
+ return {
54
+ user: selectedUser,
55
+ linkedAccount: null,
56
+ accounts: []
57
+ };
58
+ }
59
+ const emailMatch = await c.context.internalAdapter.findUserByEmail(userInfo.email.toLowerCase(), { includeAccounts: true });
60
+ if (!emailMatch) return null;
61
+ return {
62
+ user: emailMatch.user,
63
+ linkedAccount: null,
64
+ accounts: emailMatch.accounts
65
+ };
66
+ })().catch((e) => {
67
+ if (isAPIError(e)) throw e;
68
+ c.context.logger.error("Better auth was unable to query your database.\nError: ", e);
69
+ redirectOnError(c, c.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`, "internal_server_error");
70
+ });
71
+ let user = dbUser?.user;
72
+ const isRegister = !user;
73
+ if (dbUser) {
74
+ const linkedAccount = dbUser.linkedAccount ?? dbUser.accounts.find((acc) => acc.providerId === account.providerId && acc.accountId === account.accountId);
75
+ if (!linkedAccount) {
76
+ const accountLinking = c.context.options.account?.accountLinking;
77
+ const isTrustedProvider = opts.isTrustedProvider || opts.trustProviderByName !== false && c.context.trustedProviders.includes(account.providerId);
78
+ const requireLocalEmailVerified = accountLinking?.requireLocalEmailVerified ?? true;
79
+ if (!opts.selectedUser && (!isTrustedProvider && !userInfo.emailVerified || requireLocalEmailVerified && !dbUser.user.emailVerified || accountLinking?.enabled === false || accountLinking?.disableImplicitLinking === true)) {
80
+ if (isDevelopment()) c.context.logger.warn(`User already exist but account isn't linked to ${account.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`);
81
+ return {
82
+ error: "account not linked",
83
+ data: null
84
+ };
85
+ }
86
+ try {
87
+ const { id: _accountId, ...providerUserInfo } = userInfo;
88
+ await assertValidUserInfo(c, {
89
+ user: {
90
+ ...providerUserInfo,
91
+ id: dbUser.user.id,
92
+ email: userInfo.email.toLowerCase()
93
+ },
94
+ source: {
95
+ ...source,
96
+ action: "link-account"
97
+ }
98
+ });
99
+ const createdAccount = await c.context.internalAdapter.linkAccount({
100
+ providerId: account.providerId,
101
+ accountId: account.accountId,
102
+ userId: dbUser.user.id,
103
+ accessToken: await setTokenUtil(account.accessToken, c.context),
104
+ refreshToken: await setTokenUtil(account.refreshToken, c.context),
105
+ idToken: account.idToken,
106
+ accessTokenExpiresAt: account.accessTokenExpiresAt,
107
+ refreshTokenExpiresAt: account.refreshTokenExpiresAt,
108
+ scope: account.scope
109
+ });
110
+ if (!createdAccount) return {
111
+ error: "unable to link account",
112
+ data: null
113
+ };
114
+ if (requireExactAccountBinding && (createdAccount.accountId !== account.accountId || createdAccount.providerId !== account.providerId || createdAccount.userId !== dbUser.user.id)) throw new APIError("CONFLICT", {
115
+ code: "account_hook_binding_conflict",
116
+ message: "Account hook changed the selected authentication binding"
117
+ });
118
+ if (c.context.options.account?.storeAccountCookie) if (opts.deferNonDatabaseWrites) pendingAccountCookie = createdAccount;
119
+ else await setAccountCookie(c, createdAccount);
120
+ } catch (e) {
121
+ if (isAPIError(e)) throw e;
122
+ c.context.logger.error("Unable to link account", e);
123
+ return {
124
+ error: "unable to link account",
125
+ data: null
126
+ };
127
+ }
128
+ if (!opts.selectedUser && userInfo.emailVerified && !dbUser.user.emailVerified && userInfo.email.toLowerCase() === dbUser.user.email) await c.context.internalAdapter.updateUser(dbUser.user.id, { emailVerified: true });
129
+ if (!opts.selectedUser) user = await applyUpdateUserInfoOnLink(c, dbUser.user.id, userInfo) ?? user;
130
+ } else {
131
+ const { id: _accountId, ...providerUserInfo } = userInfo;
132
+ await assertValidUserInfo(c, {
133
+ user: {
134
+ ...providerUserInfo,
135
+ id: dbUser.user.id,
136
+ email: userInfo.email.toLowerCase()
137
+ },
138
+ source: {
139
+ ...source,
140
+ action: "sign-in"
141
+ }
142
+ });
143
+ /**
144
+ * `scope` intentionally omitted. Updated only via linkSocial.
145
+ *
146
+ * @see {@link Account.scope}
147
+ */
148
+ const freshTokens = c.context.options.account?.updateAccountOnSignIn !== false ? Object.fromEntries(Object.entries({
149
+ providerId: account.providerId,
150
+ idToken: account.idToken,
151
+ accessToken: await setTokenUtil(account.accessToken, c.context),
152
+ refreshToken: await setTokenUtil(account.refreshToken, c.context),
153
+ accessTokenExpiresAt: account.accessTokenExpiresAt,
154
+ refreshTokenExpiresAt: account.refreshTokenExpiresAt
155
+ }).filter(([_, value]) => value !== void 0)) : {};
156
+ if (c.context.options.account?.storeAccountCookie) {
157
+ const accountCookie = {
158
+ ...linkedAccount,
159
+ ...freshTokens
160
+ };
161
+ if (opts.deferNonDatabaseWrites) pendingAccountCookie = accountCookie;
162
+ else await setAccountCookie(c, accountCookie);
163
+ }
164
+ if (Object.keys(freshTokens).length > 0) {
165
+ const updatedAccount = await c.context.internalAdapter.updateAccount(linkedAccount.id, freshTokens);
166
+ if (!updatedAccount) return {
167
+ error: "unable to update account",
168
+ data: null
169
+ };
170
+ if (requireExactAccountBinding && (updatedAccount.accountId !== account.accountId || updatedAccount.providerId !== account.providerId || updatedAccount.userId !== dbUser.user.id)) throw new APIError("CONFLICT", {
171
+ code: "account_hook_binding_conflict",
172
+ message: "Account hook changed the selected authentication binding"
173
+ });
174
+ if (opts.deferNonDatabaseWrites && pendingAccountCookie) pendingAccountCookie = updatedAccount;
175
+ }
176
+ if (!opts.selectedUser && userInfo.emailVerified && !dbUser.user.emailVerified && userInfo.email.toLowerCase() === dbUser.user.email) await c.context.internalAdapter.updateUser(dbUser.user.id, { emailVerified: true });
177
+ }
178
+ if (opts.selectedUser ? opts.selectedUser.profile === "update" : overrideUserInfo) {
179
+ const { id: _id, email: _email, emailVerified: _emailVerified, name, image, ...providerProfile } = userInfo;
180
+ const additionalUserFields = parseAdditionalUserInputFromProviderProfile(c.context.options, providerProfile, "update");
181
+ const updatedUser = await c.context.internalAdapter.updateUser(dbUser.user.id, {
182
+ name,
183
+ image,
184
+ ...additionalUserFields,
185
+ email: userInfo.email.toLowerCase(),
186
+ emailVerified: userInfo.email.toLowerCase() === dbUser.user.email ? dbUser.user.emailVerified || userInfo.emailVerified : userInfo.emailVerified
187
+ });
188
+ if (updatedUser == null) c.context.logger.warn("Could not update user info during OAuth sign in; preserving existing user for session.");
189
+ if (opts.selectedUser && updatedUser && updatedUser.id !== opts.selectedUser.userId) throw new APIError("CONFLICT", {
190
+ code: "user_hook_selection_conflict",
191
+ message: "User hook changed the selected user"
192
+ });
193
+ user = updatedUser ?? user;
194
+ }
195
+ } else {
196
+ if (disableSignUp) return {
197
+ error: "signup disabled",
198
+ data: null,
199
+ isRegister: false
200
+ };
201
+ try {
202
+ const { id: _id, email: _email, emailVerified: _emailVerified, name, image, ...providerProfile } = userInfo;
203
+ const additionalUserFields = parseAdditionalUserInputFromProviderProfile(c.context.options, providerProfile, "create");
204
+ const accountData = {
205
+ accessToken: await setTokenUtil(account.accessToken, c.context),
206
+ refreshToken: await setTokenUtil(account.refreshToken, c.context),
207
+ idToken: account.idToken,
208
+ accessTokenExpiresAt: account.accessTokenExpiresAt,
209
+ refreshTokenExpiresAt: account.refreshTokenExpiresAt,
210
+ scope: account.scope,
211
+ providerId: account.providerId,
212
+ accountId: account.accountId
213
+ };
214
+ const { createdUser, createdAccount } = await runWithTransaction(c.context.adapter, async () => {
215
+ const createdUser = await c.context.internalAdapter.createUser({
216
+ name,
217
+ image,
218
+ ...additionalUserFields,
219
+ email: userInfo.email.toLowerCase(),
220
+ emailVerified: userInfo.emailVerified
221
+ }, source);
222
+ return {
223
+ createdUser,
224
+ createdAccount: await c.context.internalAdapter.createAccount({
225
+ ...accountData,
226
+ userId: createdUser.id
227
+ })
228
+ };
229
+ });
230
+ if (requireExactAccountBinding && (createdAccount.accountId !== account.accountId || createdAccount.providerId !== account.providerId || createdAccount.userId !== createdUser.id)) throw new APIError("CONFLICT", {
231
+ code: "account_hook_binding_conflict",
232
+ message: "Account hook changed the selected authentication binding"
233
+ });
234
+ user = createdUser;
235
+ if (c.context.options.account?.storeAccountCookie) if (opts.deferNonDatabaseWrites) pendingAccountCookie = createdAccount;
236
+ else await setAccountCookie(c, createdAccount);
237
+ } catch (e) {
238
+ if (isAPIError(e)) throw e;
239
+ c.context.logger.error("Unable to create OAuth user", e);
240
+ return {
241
+ error: "unable to create user",
242
+ data: null,
243
+ isRegister: false
244
+ };
245
+ }
246
+ }
247
+ if (!user) return {
248
+ error: "unable to create user",
249
+ data: null,
250
+ isRegister: false
251
+ };
252
+ const requireEmailVerification = c.context.socialProviders.find((p) => p.id === account.providerId)?.options?.requireEmailVerification;
253
+ if (isRegister && !user.emailVerified && (c.context.options.emailVerification?.sendOnSignUp ?? requireEmailVerification)) await dispatchVerificationEmail(c, user, callbackURL, opts.deferNonDatabaseWrites);
254
+ if (requireEmailVerification && !user.emailVerified) {
255
+ if (!isRegister && c.context.options.emailVerification?.sendOnSignIn) await dispatchVerificationEmail(c, user, callbackURL, opts.deferNonDatabaseWrites);
256
+ return {
257
+ error: OAUTH_CALLBACK_ERROR_CODES.EMAIL_NOT_VERIFIED,
258
+ data: null,
259
+ isRegister
260
+ };
261
+ }
262
+ const session = await c.context.internalAdapter.createSession(user.id, void 0, void 0, void 0, { deferSecondaryStorageWrites: opts.deferNonDatabaseWrites === true });
263
+ if (!session) return {
264
+ error: "unable to create session",
265
+ data: null,
266
+ isRegister: false
267
+ };
268
+ if (requireExactAccountBinding && session.userId !== (opts.selectedUser?.userId ?? user.id)) throw new APIError("CONFLICT", {
269
+ code: "session_hook_user_conflict",
270
+ message: "Session hook changed the selected user"
271
+ });
272
+ return {
273
+ data: {
274
+ session,
275
+ user
276
+ },
277
+ error: null,
278
+ isRegister,
279
+ accountCookie: pendingAccountCookie
280
+ };
281
+ }
282
+ async function dispatchVerificationEmail(c, user, callbackURL, deferUntilAfterTransaction) {
283
+ const sendVerificationEmail = c.context.options.emailVerification?.sendVerificationEmail;
284
+ if (!sendVerificationEmail) return;
285
+ const send = async () => {
286
+ try {
287
+ const token = await createEmailVerificationToken(c.context.secret, user.email, void 0, c.context.options.emailVerification?.expiresIn);
288
+ const url = `${c.context.baseURL}/verify-email?token=${token}&callbackURL=${encodeURIComponent(callbackURL || "/")}`;
289
+ await c.context.runInBackgroundOrAwait(sendVerificationEmail({
290
+ user,
291
+ url,
292
+ token
293
+ }, c.request));
294
+ } catch (e) {
295
+ c.context.logger.error("Failed to send OAuth verification email", e);
296
+ }
297
+ };
298
+ if (deferUntilAfterTransaction) await queueAfterTransactionHook(send);
299
+ else await send();
300
+ }
301
+ /**
302
+ * Apply the `account.accountLinking.updateUserInfoOnLink` policy: when enabled,
303
+ * copy the freshly linked provider's profile onto the local user, matching the
304
+ * field set persisted on sign-up. The local `email` and `emailVerified` are
305
+ * never changed, so a link can't rebind the account's identity, and
306
+ * `updateUser` drops `undefined` fields, so a provider that omits one leaves
307
+ * the existing column intact.
308
+ *
309
+ * Returns the updated user so a caller that issues a session can seed the
310
+ * cookie cache with the fresh row. Returns `undefined` when the policy is
311
+ * disabled or the update fails: a failed profile sync must not abort the link.
312
+ */
313
+ async function applyUpdateUserInfoOnLink(c, userId, userInfo) {
314
+ if (c.context.options.account?.accountLinking?.updateUserInfoOnLink !== true) return;
315
+ try {
316
+ const { email: _email, emailVerified: _emailVerified, name, image, ...providerProfile } = userInfo;
317
+ const additionalUserFields = parseAdditionalUserInputFromProviderProfile(c.context.options, providerProfile, "update");
318
+ return await c.context.internalAdapter.updateUser(userId, {
319
+ name,
320
+ image,
321
+ ...additionalUserFields
322
+ });
323
+ } catch (e) {
324
+ c.context.logger.warn("Could not update user info on account link", e);
325
+ return;
326
+ }
327
+ }
328
+ //#endregion
329
+ export { applyUpdateUserInfoOnLink, handleOAuthUserInfo };
@@ -0,0 +1,54 @@
1
+ import { GenericEndpointContext } from "@better-auth/core";
2
+
3
+ //#region src/oauth2/state.d.ts
4
+ /**
5
+ * Mint the OIDC `nonce` for the redirect flow, or `undefined` when the provider
6
+ * does not require ID-token nonce binding. Every redirect entrypoint (social
7
+ * sign-in, account linking, IDP-initiated bounce, and the OAuth popup) mints
8
+ * through this helper, so the value sent on the authorization URL and the value
9
+ * persisted in state are produced one way and cannot drift apart.
10
+ */
11
+ declare function generateIdTokenNonce(provider: {
12
+ requiresIdTokenNonce?: boolean | undefined;
13
+ }): string | undefined;
14
+ /**
15
+ * Inputs for {@link generateState}. Grouped into one object so call sites read
16
+ * by name instead of by position.
17
+ */
18
+ interface GenerateStateOptions {
19
+ /** Link target when this flow links a provider identity to an existing user. */
20
+ link?: {
21
+ email: string;
22
+ userId: string;
23
+ } | undefined;
24
+ /** Extra data to round-trip through state; `false` writes none. */
25
+ additionalData?: Record<string, any> | false | undefined;
26
+ /** The `state` nonce already used to build the authorization URL. Minted when omitted. */
27
+ state?: string | undefined;
28
+ /** The PKCE `codeVerifier` already used to build the authorization URL. Minted when omitted. */
29
+ codeVerifier?: string | undefined;
30
+ /** The OIDC nonce already sent as the authorization URL `nonce` parameter. */
31
+ idTokenNonce?: string | undefined;
32
+ }
33
+ declare function generateState(c: GenericEndpointContext, options?: GenerateStateOptions): Promise<{
34
+ state: string;
35
+ codeVerifier: string;
36
+ }>;
37
+ declare function parseState(c: GenericEndpointContext): Promise<{
38
+ [x: string]: unknown;
39
+ callbackURL: string;
40
+ codeVerifier: string;
41
+ expiresAt: number;
42
+ errorURL?: string | undefined;
43
+ newUserURL?: string | undefined;
44
+ oauthState?: string | undefined;
45
+ link?: {
46
+ email: string;
47
+ userId: string;
48
+ } | undefined;
49
+ requestSignUp?: boolean | undefined;
50
+ idTokenNonce?: string | undefined;
51
+ serverContext?: Record<string, unknown> | undefined;
52
+ }>;
53
+ //#endregion
54
+ export { GenerateStateOptions, generateIdTokenNonce, generateState, parseState };
@@ -0,0 +1,67 @@
1
+ import { generateRandomString } from "../crypto/random.mjs";
2
+ import { redirectOnError } from "./errors.mjs";
3
+ import { getOAuthServerContext, setOAuthState } from "../api/state/oauth.mjs";
4
+ import { StateError, generateGenericState, parseGenericState } from "../state.mjs";
5
+ import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
6
+ //#region src/oauth2/state.ts
7
+ /**
8
+ * Mint the OIDC `nonce` for the redirect flow, or `undefined` when the provider
9
+ * does not require ID-token nonce binding. Every redirect entrypoint (social
10
+ * sign-in, account linking, IDP-initiated bounce, and the OAuth popup) mints
11
+ * through this helper, so the value sent on the authorization URL and the value
12
+ * persisted in state are produced one way and cannot drift apart.
13
+ */
14
+ function generateIdTokenNonce(provider) {
15
+ return provider.requiresIdTokenNonce ? generateRandomString(32) : void 0;
16
+ }
17
+ async function generateState(c, options) {
18
+ const callbackURL = c.body?.callbackURL || c.context.options.baseURL;
19
+ if (!callbackURL) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.CALLBACK_URL_REQUIRED);
20
+ const codeVerifier = options?.codeVerifier ?? generateRandomString(128);
21
+ const pendingServerContext = await getOAuthServerContext();
22
+ const serverContext = pendingServerContext && Object.keys(pendingServerContext).length ? pendingServerContext : void 0;
23
+ const stateData = {
24
+ ...options?.additionalData ? options.additionalData : {},
25
+ callbackURL,
26
+ codeVerifier,
27
+ errorURL: c.body?.errorCallbackURL,
28
+ newUserURL: c.body?.newUserCallbackURL,
29
+ link: options?.link,
30
+ serverContext,
31
+ expiresAt: Date.now() + 600 * 1e3,
32
+ requestSignUp: c.body?.requestSignUp,
33
+ idTokenNonce: options?.idTokenNonce
34
+ };
35
+ await setOAuthState(stateData);
36
+ try {
37
+ return generateGenericState(c, stateData);
38
+ } catch (error) {
39
+ c.context.logger.error("Failed to create verification", error);
40
+ throw new APIError("INTERNAL_SERVER_ERROR", {
41
+ message: "Unable to create verification",
42
+ cause: error
43
+ });
44
+ }
45
+ }
46
+ async function parseState(c) {
47
+ const state = c.query.state || c.body?.state;
48
+ const errorURL = c.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;
49
+ let parsedData;
50
+ try {
51
+ parsedData = await parseGenericState(c, state);
52
+ } catch (error) {
53
+ c.context.logger.error("Failed to parse state", error);
54
+ let code = "internal_server_error";
55
+ let redirectErrorURL = errorURL;
56
+ if (error instanceof StateError) {
57
+ code = error.code === "state_security_mismatch" ? "state_mismatch" : error.code;
58
+ redirectErrorURL = error.errorURL || errorURL;
59
+ }
60
+ redirectOnError(c, redirectErrorURL, code);
61
+ }
62
+ if (!parsedData.errorURL) parsedData.errorURL = errorURL;
63
+ if (parsedData) await setOAuthState(parsedData);
64
+ return parsedData;
65
+ }
66
+ //#endregion
67
+ export { generateIdTokenNonce, generateState, parseState };
@@ -0,0 +1,11 @@
1
+ import { AuthContext, LiteralString } from "@better-auth/core";
2
+
3
+ //#region src/oauth2/utils.d.ts
4
+ declare function decryptOAuthToken(token: string, ctx: AuthContext): string | Promise<string>;
5
+ declare function setTokenUtil(token: string | null | undefined, ctx: AuthContext): string | Promise<string> | null | undefined;
6
+ declare function getOAuthCallbackPath(provider: {
7
+ id: LiteralString;
8
+ callbackPath?: string | undefined;
9
+ }): string;
10
+ //#endregion
11
+ export { decryptOAuthToken, getOAuthCallbackPath, setTokenUtil };
@@ -0,0 +1,33 @@
1
+ import { symmetricDecrypt, symmetricEncrypt } from "../crypto/index.mjs";
2
+ //#region src/oauth2/utils.ts
3
+ /**
4
+ * Check if a string looks like encrypted data
5
+ */
6
+ function isLikelyEncrypted(token) {
7
+ if (token.startsWith("$ba$")) return true;
8
+ return token.length % 2 === 0 && /^[0-9a-f]+$/i.test(token);
9
+ }
10
+ function decryptOAuthToken(token, ctx) {
11
+ if (!token) return token;
12
+ if (ctx.options.account?.encryptOAuthTokens) {
13
+ if (!isLikelyEncrypted(token)) return token;
14
+ return symmetricDecrypt({
15
+ key: ctx.secretConfig,
16
+ data: token
17
+ });
18
+ }
19
+ return token;
20
+ }
21
+ function setTokenUtil(token, ctx) {
22
+ if (ctx.options.account?.encryptOAuthTokens && token) return symmetricEncrypt({
23
+ key: ctx.secretConfig,
24
+ data: token
25
+ });
26
+ return token;
27
+ }
28
+ function getOAuthCallbackPath(provider) {
29
+ if (!provider.callbackPath) return `/callback/${provider.id}`;
30
+ return provider.callbackPath.startsWith("/") ? provider.callbackPath : `/${provider.callbackPath}`;
31
+ }
32
+ //#endregion
33
+ export { decryptOAuthToken, getOAuthCallbackPath, setTokenUtil };
@@ -0,0 +1,4 @@
1
+ //#region package.json
2
+ var version = "1.7.5";
3
+ //#endregion
4
+ export { version };
@@ -0,0 +1,17 @@
1
+ import { ExactRoleStatements, Role, RoleInput, Statements } from "./types.mjs";
2
+
3
+ //#region src/plugins/access/access.d.ts
4
+ type AuthorizeResponse = {
5
+ success: false;
6
+ error: string;
7
+ } | {
8
+ success: true;
9
+ error?: never | undefined;
10
+ };
11
+ declare function role<const TRoleStatements extends Statements, TAuthorizeStatements extends Statements = TRoleStatements>(statements: TRoleStatements): Role<ExactRoleStatements<TRoleStatements>, TAuthorizeStatements>;
12
+ declare function createAccessControl<const TStatements extends Statements>(s: TStatements): {
13
+ newRole<const TRoleStatements extends Statements>(statements: RoleInput<TStatements, TRoleStatements>): Role<ExactRoleStatements<TRoleStatements>, TStatements>;
14
+ statements: TStatements;
15
+ };
16
+ //#endregion
17
+ export { AuthorizeResponse, createAccessControl, role };