better-auth 1.7.0-beta.1 → 1.7.0-beta.10

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 (280) hide show
  1. package/README.md +14 -15
  2. package/dist/api/dispatch.d.mts +34 -0
  3. package/dist/api/dispatch.mjs +272 -0
  4. package/dist/api/index.d.mts +24 -55
  5. package/dist/api/index.mjs +9 -9
  6. package/dist/api/middlewares/origin-check.mjs +6 -1
  7. package/dist/api/rate-limiter/index.mjs +215 -98
  8. package/dist/api/routes/account.d.mts +4 -24
  9. package/dist/api/routes/account.mjs +169 -116
  10. package/dist/api/routes/callback.mjs +88 -29
  11. package/dist/api/routes/email-verification.d.mts +1 -0
  12. package/dist/api/routes/email-verification.mjs +24 -10
  13. package/dist/api/routes/error.mjs +1 -1
  14. package/dist/api/routes/index.d.mts +1 -1
  15. package/dist/api/routes/password.mjs +4 -5
  16. package/dist/api/routes/session.d.mts +41 -3
  17. package/dist/api/routes/session.mjs +127 -98
  18. package/dist/api/routes/sign-in.d.mts +3 -1
  19. package/dist/api/routes/sign-in.mjs +43 -29
  20. package/dist/api/routes/sign-up.d.mts +1 -0
  21. package/dist/api/routes/sign-up.mjs +46 -38
  22. package/dist/api/routes/update-session.mjs +9 -4
  23. package/dist/api/routes/update-user.mjs +18 -20
  24. package/dist/api/state/oauth.d.mts +38 -2
  25. package/dist/api/state/oauth.mjs +35 -2
  26. package/dist/api/to-auth-endpoints.mjs +14 -213
  27. package/dist/auth/base.mjs +34 -27
  28. package/dist/auth/trusted-origins.mjs +60 -1
  29. package/dist/client/config.d.mts +88 -0
  30. package/dist/client/config.mjs +9 -2
  31. package/dist/client/equality.d.mts +19 -0
  32. package/dist/client/equality.mjs +42 -0
  33. package/dist/client/fetch-plugins.mjs +2 -1
  34. package/dist/client/index.d.mts +6 -5
  35. package/dist/client/index.mjs +2 -1
  36. package/dist/client/lynx/index.d.mts +21 -104
  37. package/dist/client/lynx/index.mjs +2 -1
  38. package/dist/client/parser.mjs +0 -1
  39. package/dist/client/path-to-object.d.mts +5 -2
  40. package/dist/client/plugins/index.d.mts +7 -19
  41. package/dist/client/plugins/index.mjs +4 -5
  42. package/dist/client/proxy.mjs +2 -1
  43. package/dist/client/query.d.mts +4 -3
  44. package/dist/client/query.mjs +27 -17
  45. package/dist/client/react/index.d.mts +21 -104
  46. package/dist/client/react/index.mjs +2 -1
  47. package/dist/client/session-atom.d.mts +11 -0
  48. package/dist/client/session-atom.mjs +141 -5
  49. package/dist/client/session-refresh.d.mts +3 -18
  50. package/dist/client/session-refresh.mjs +38 -49
  51. package/dist/client/solid/index.d.mts +20 -98
  52. package/dist/client/solid/index.mjs +3 -2
  53. package/dist/client/svelte/index.d.mts +21 -104
  54. package/dist/client/svelte/index.mjs +2 -1
  55. package/dist/client/types.d.mts +27 -16
  56. package/dist/client/vanilla.d.mts +20 -104
  57. package/dist/client/vanilla.mjs +2 -1
  58. package/dist/client/vue/index.d.mts +40 -134
  59. package/dist/client/vue/index.mjs +2 -1
  60. package/dist/context/create-context.mjs +30 -16
  61. package/dist/context/helpers.mjs +9 -6
  62. package/dist/context/store-capabilities.mjs +12 -0
  63. package/dist/cookies/cookie-utils.d.mts +45 -1
  64. package/dist/cookies/cookie-utils.mjs +110 -14
  65. package/dist/cookies/index.d.mts +9 -3
  66. package/dist/cookies/index.mjs +93 -30
  67. package/dist/cookies/session-store.d.mts +0 -17
  68. package/dist/cookies/session-store.mjs +44 -72
  69. package/dist/db/get-migration.mjs +5 -4
  70. package/dist/db/get-schema.d.mts +1 -0
  71. package/dist/db/get-schema.mjs +3 -1
  72. package/dist/db/index.d.mts +3 -2
  73. package/dist/db/index.mjs +6 -2
  74. package/dist/db/internal-adapter.mjs +250 -34
  75. package/dist/db/revoke-unproven-account-access.d.mts +21 -0
  76. package/dist/db/revoke-unproven-account-access.mjs +58 -0
  77. package/dist/db/schema.d.mts +15 -1
  78. package/dist/db/schema.mjs +38 -1
  79. package/dist/db/to-zod.d.mts +2 -2
  80. package/dist/db/to-zod.mjs +1 -1
  81. package/dist/db/with-hooks.d.mts +1 -0
  82. package/dist/db/with-hooks.mjs +58 -1
  83. package/dist/index.d.mts +4 -4
  84. package/dist/index.mjs +3 -3
  85. package/dist/integrations/cookie-plugin-guard.mjs +18 -0
  86. package/dist/integrations/next-js.mjs +8 -10
  87. package/dist/integrations/svelte-kit.mjs +11 -10
  88. package/dist/integrations/tanstack-start-solid.mjs +8 -10
  89. package/dist/integrations/tanstack-start.mjs +8 -10
  90. package/dist/oauth2/errors.mjs +48 -0
  91. package/dist/oauth2/index.d.mts +4 -4
  92. package/dist/oauth2/index.mjs +4 -4
  93. package/dist/oauth2/link-account.d.mts +30 -2
  94. package/dist/oauth2/link-account.mjs +129 -33
  95. package/dist/oauth2/state.d.mts +33 -5
  96. package/dist/oauth2/state.mjs +30 -10
  97. package/dist/oauth2/utils.d.mts +6 -2
  98. package/dist/oauth2/utils.mjs +5 -1
  99. package/dist/package.mjs +1 -1
  100. package/dist/plugins/access/access.d.mts +3 -15
  101. package/dist/plugins/access/access.mjs +52 -17
  102. package/dist/plugins/access/index.d.mts +2 -2
  103. package/dist/plugins/access/types.d.mts +11 -4
  104. package/dist/plugins/admin/access/statement.d.mts +34 -98
  105. package/dist/plugins/admin/access/statement.mjs +2 -0
  106. package/dist/plugins/admin/admin.d.mts +6 -3
  107. package/dist/plugins/admin/admin.mjs +0 -4
  108. package/dist/plugins/admin/client.d.mts +12 -5
  109. package/dist/plugins/admin/client.mjs +5 -0
  110. package/dist/plugins/admin/error-codes.d.mts +2 -0
  111. package/dist/plugins/admin/error-codes.mjs +3 -1
  112. package/dist/plugins/admin/routes.mjs +84 -12
  113. package/dist/plugins/admin/schema.d.mts +1 -0
  114. package/dist/plugins/admin/schema.mjs +2 -1
  115. package/dist/plugins/anonymous/client.d.mts +1 -0
  116. package/dist/plugins/anonymous/error-codes.d.mts +1 -0
  117. package/dist/plugins/anonymous/error-codes.mjs +1 -0
  118. package/dist/plugins/anonymous/index.d.mts +5 -0
  119. package/dist/plugins/anonymous/index.mjs +97 -40
  120. package/dist/plugins/bearer/index.mjs +5 -12
  121. package/dist/plugins/captcha/constants.mjs +8 -1
  122. package/dist/plugins/captcha/index.mjs +22 -5
  123. package/dist/plugins/captcha/types.d.mts +25 -0
  124. package/dist/plugins/captcha/verify-handlers/captchafox.mjs +2 -0
  125. package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +7 -2
  126. package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +7 -2
  127. package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +2 -0
  128. package/dist/plugins/custom-session/index.d.mts +6 -5
  129. package/dist/plugins/custom-session/index.mjs +3 -15
  130. package/dist/plugins/device-authorization/error-codes.mjs +1 -0
  131. package/dist/plugins/device-authorization/index.d.mts +13 -9
  132. package/dist/plugins/device-authorization/index.mjs +1 -1
  133. package/dist/plugins/device-authorization/routes.mjs +154 -100
  134. package/dist/plugins/email-otp/index.mjs +1 -1
  135. package/dist/plugins/email-otp/otp-token.mjs +1 -1
  136. package/dist/plugins/email-otp/routes.mjs +39 -63
  137. package/dist/plugins/generic-oauth/error-codes.mjs +0 -1
  138. package/dist/plugins/generic-oauth/index.d.mts +4 -6
  139. package/dist/plugins/generic-oauth/index.mjs +72 -34
  140. package/dist/plugins/generic-oauth/providers/auth0.mjs +1 -0
  141. package/dist/plugins/generic-oauth/providers/gumroad.mjs +1 -0
  142. package/dist/plugins/generic-oauth/providers/hubspot.mjs +1 -0
  143. package/dist/plugins/generic-oauth/providers/keycloak.mjs +1 -0
  144. package/dist/plugins/generic-oauth/providers/line.mjs +1 -0
  145. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +1 -0
  146. package/dist/plugins/generic-oauth/providers/okta.mjs +1 -0
  147. package/dist/plugins/generic-oauth/providers/patreon.mjs +1 -0
  148. package/dist/plugins/generic-oauth/providers/slack.mjs +1 -0
  149. package/dist/plugins/generic-oauth/types.d.mts +85 -11
  150. package/dist/plugins/haveibeenpwned/index.d.mts +1 -1
  151. package/dist/plugins/haveibeenpwned/index.mjs +5 -1
  152. package/dist/plugins/index.d.mts +8 -7
  153. package/dist/plugins/index.mjs +6 -5
  154. package/dist/plugins/jwt/adapter.mjs +21 -2
  155. package/dist/plugins/jwt/cookie-cache.mjs +117 -0
  156. package/dist/plugins/jwt/index.d.mts +8 -0
  157. package/dist/plugins/jwt/index.mjs +6 -6
  158. package/dist/plugins/jwt/schema.d.mts +8 -0
  159. package/dist/plugins/jwt/schema.mjs +8 -0
  160. package/dist/plugins/jwt/sign.d.mts +62 -2
  161. package/dist/plugins/jwt/sign.mjs +53 -6
  162. package/dist/plugins/jwt/types.d.mts +45 -1
  163. package/dist/plugins/jwt/utils.d.mts +1 -1
  164. package/dist/plugins/jwt/utils.mjs +6 -3
  165. package/dist/plugins/last-login-method/client.d.mts +10 -0
  166. package/dist/plugins/last-login-method/client.mjs +6 -3
  167. package/dist/plugins/magic-link/index.d.mts +8 -1
  168. package/dist/plugins/magic-link/index.mjs +24 -24
  169. package/dist/plugins/multi-session/index.mjs +9 -7
  170. package/dist/plugins/oauth-popup/client.d.mts +82 -0
  171. package/dist/plugins/oauth-popup/client.mjs +203 -0
  172. package/dist/plugins/oauth-popup/constants.d.mts +11 -0
  173. package/dist/plugins/oauth-popup/constants.mjs +11 -0
  174. package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
  175. package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
  176. package/dist/plugins/oauth-popup/index.d.mts +67 -0
  177. package/dist/plugins/oauth-popup/index.mjs +232 -0
  178. package/dist/plugins/oauth-popup/types.d.mts +30 -0
  179. package/dist/plugins/oauth-proxy/index.mjs +67 -39
  180. package/dist/plugins/oauth-proxy/utils.mjs +19 -12
  181. package/dist/plugins/one-tap/client.mjs +21 -8
  182. package/dist/plugins/one-tap/index.d.mts +1 -2
  183. package/dist/plugins/one-tap/index.mjs +52 -51
  184. package/dist/plugins/one-time-token/index.mjs +1 -3
  185. package/dist/plugins/open-api/generator.d.mts +71 -59
  186. package/dist/plugins/open-api/generator.mjs +247 -89
  187. package/dist/plugins/open-api/index.d.mts +2 -2
  188. package/dist/plugins/organization/access/statement.d.mts +68 -201
  189. package/dist/plugins/organization/adapter.d.mts +34 -8
  190. package/dist/plugins/organization/adapter.mjs +274 -90
  191. package/dist/plugins/organization/client.d.mts +7 -5
  192. package/dist/plugins/organization/client.mjs +1 -1
  193. package/dist/plugins/organization/error-codes.d.mts +2 -0
  194. package/dist/plugins/organization/error-codes.mjs +3 -1
  195. package/dist/plugins/organization/organization.d.mts +6 -6
  196. package/dist/plugins/organization/organization.mjs +18 -0
  197. package/dist/plugins/organization/routes/crud-access-control.d.mts +3 -3
  198. package/dist/plugins/organization/routes/crud-access-control.mjs +1 -1
  199. package/dist/plugins/organization/routes/crud-invites.d.mts +8 -1
  200. package/dist/plugins/organization/routes/crud-invites.mjs +88 -32
  201. package/dist/plugins/organization/routes/crud-members.mjs +59 -6
  202. package/dist/plugins/organization/routes/crud-org.d.mts +4 -4
  203. package/dist/plugins/organization/routes/crud-org.mjs +2 -2
  204. package/dist/plugins/organization/routes/crud-team.d.mts +9 -8
  205. package/dist/plugins/organization/routes/crud-team.mjs +99 -8
  206. package/dist/plugins/organization/schema.d.mts +17 -1
  207. package/dist/plugins/organization/types.d.mts +24 -7
  208. package/dist/plugins/phone-number/index.d.mts +42 -0
  209. package/dist/plugins/phone-number/index.mjs +11 -2
  210. package/dist/plugins/phone-number/routes.mjs +87 -46
  211. package/dist/plugins/siwe/client.d.mts +4 -0
  212. package/dist/plugins/siwe/client.mjs +5 -1
  213. package/dist/plugins/siwe/index.d.mts +13 -2
  214. package/dist/plugins/siwe/index.mjs +236 -165
  215. package/dist/plugins/siwe/parse-message.mjs +60 -0
  216. package/dist/plugins/test-utils/db-helpers.mjs +1 -1
  217. package/dist/plugins/test-utils/index.d.mts +11 -2
  218. package/dist/plugins/test-utils/index.mjs +11 -2
  219. package/dist/plugins/two-factor/backup-codes/index.d.mts +4 -3
  220. package/dist/plugins/two-factor/backup-codes/index.mjs +26 -11
  221. package/dist/plugins/two-factor/client.d.mts +1 -0
  222. package/dist/plugins/two-factor/client.mjs +2 -1
  223. package/dist/plugins/two-factor/error-code.d.mts +1 -0
  224. package/dist/plugins/two-factor/error-code.mjs +1 -0
  225. package/dist/plugins/two-factor/index.d.mts +14 -0
  226. package/dist/plugins/two-factor/index.mjs +20 -6
  227. package/dist/plugins/two-factor/otp/index.mjs +26 -13
  228. package/dist/plugins/two-factor/schema.d.mts +13 -0
  229. package/dist/plugins/two-factor/schema.mjs +13 -0
  230. package/dist/plugins/two-factor/totp/index.mjs +24 -10
  231. package/dist/plugins/two-factor/types.d.mts +25 -0
  232. package/dist/plugins/two-factor/verify-two-factor.mjs +129 -5
  233. package/dist/plugins/username/client.d.mts +1 -0
  234. package/dist/plugins/username/error-codes.d.mts +1 -0
  235. package/dist/plugins/username/error-codes.mjs +2 -1
  236. package/dist/plugins/username/index.d.mts +43 -2
  237. package/dist/plugins/username/index.mjs +130 -49
  238. package/dist/state.d.mts +15 -2
  239. package/dist/state.mjs +23 -6
  240. package/dist/test-utils/headers.mjs +2 -7
  241. package/dist/test-utils/http-test-instance.d.mts +404 -0
  242. package/dist/test-utils/http-test-instance.mjs +95 -0
  243. package/dist/test-utils/index.d.mts +2 -1
  244. package/dist/test-utils/index.mjs +2 -1
  245. package/dist/test-utils/test-instance.d.mts +3 -12179
  246. package/dist/test-utils/test-instance.mjs +11 -2
  247. package/dist/types/auth.d.mts +4 -0
  248. package/dist/types/index.d.mts +2 -2
  249. package/dist/utils/index.d.mts +2 -2
  250. package/dist/utils/is-api-error.d.mts +1 -5
  251. package/dist/utils/is-api-error.mjs +1 -7
  252. package/dist/utils/url.d.mts +2 -1
  253. package/dist/utils/url.mjs +25 -8
  254. package/dist/utils/validate-user-info.mjs +44 -0
  255. package/package.json +33 -58
  256. package/dist/oauth2/error-codes.d.mts +0 -20
  257. package/dist/oauth2/error-codes.mjs +0 -20
  258. package/dist/plugins/generic-oauth/client.d.mts +0 -32
  259. package/dist/plugins/generic-oauth/client.mjs +0 -19
  260. package/dist/plugins/generic-oauth/error-codes.d.mts +0 -10
  261. package/dist/plugins/mcp/authorize.mjs +0 -128
  262. package/dist/plugins/mcp/client/adapters.d.mts +0 -56
  263. package/dist/plugins/mcp/client/adapters.mjs +0 -117
  264. package/dist/plugins/mcp/client/index.d.mts +0 -44
  265. package/dist/plugins/mcp/client/index.mjs +0 -152
  266. package/dist/plugins/mcp/index.d.mts +0 -457
  267. package/dist/plugins/mcp/index.mjs +0 -730
  268. package/dist/plugins/oidc-provider/authorize.mjs +0 -198
  269. package/dist/plugins/oidc-provider/client.d.mts +0 -16
  270. package/dist/plugins/oidc-provider/client.mjs +0 -15
  271. package/dist/plugins/oidc-provider/error.mjs +0 -24
  272. package/dist/plugins/oidc-provider/index.d.mts +0 -705
  273. package/dist/plugins/oidc-provider/index.mjs +0 -1095
  274. package/dist/plugins/oidc-provider/schema.d.mts +0 -159
  275. package/dist/plugins/oidc-provider/schema.mjs +0 -129
  276. package/dist/plugins/oidc-provider/types.d.mts +0 -517
  277. package/dist/plugins/oidc-provider/utils/prompt.mjs +0 -16
  278. package/dist/plugins/oidc-provider/utils.mjs +0 -12
  279. package/dist/utils/get-request-ip.d.mts +0 -6
  280. package/dist/utils/get-request-ip.mjs +0 -20
package/README.md CHANGED
@@ -1,32 +1,31 @@
1
- <p align="center">
1
+ <div align="center">
2
2
  <picture>
3
- <source media="(prefers-color-scheme: dark)" srcset="https://github.com/better-auth/better-auth/blob/main/banner-dark.png?raw=true" />
4
- <source media="(prefers-color-scheme: light)" srcset="https://github.com/better-auth/better-auth/blob/main/banner.png?raw=true" />
5
- <img alt="Better Auth Logo" src="https://github.com/better-auth/better-auth/blob/main/banner.png?raw=true" />
3
+ <source srcset="https://github.com/better-auth/better-auth/blob/main/banner-dark.png?raw=true" media="(prefers-color-scheme: dark)"/>
4
+ <source srcset="https://github.com/better-auth/better-auth/blob/main/banner-light.png?raw=true" media="(prefers-color-scheme: light)"/>
5
+ <img src="https://github.com/better-auth/better-auth/blob/main/banner-light.png?raw=true" alt="Better Auth Logo"/>
6
6
  </picture>
7
7
 
8
- <h1 align="center">
9
- Better Auth
10
- </h1>
8
+ [![npm](https://img.shields.io/npm/dm/better-auth?style=flat&colorA=000000&colorB=000000)](https://npm.chart.dev/better-auth?primary=neutral&gray=neutral&theme=dark)
9
+ [![npm version](https://img.shields.io/npm/v/better-auth.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/better-auth)
10
+ [![GitHub stars](https://img.shields.io/github/stars/better-auth/better-auth?style=flat&colorA=000000&colorB=000000)](https://github.com/better-auth/better-auth/stargazers)
11
11
 
12
- <p align="center">
13
- The most comprehensive authentication framework for TypeScript
14
- <br />
15
- <a href="https://better-auth.com"><strong>Learn more »</strong></a>
16
- <br />
17
- <br />
12
+ <p>
18
13
  <a href="https://discord.gg/better-auth">Discord</a>
19
14
  ·
20
15
  <a href="https://better-auth.com">Website</a>
21
16
  ·
22
17
  <a href="https://github.com/better-auth/better-auth/issues">Issues</a>
23
18
  </p>
24
- </p>
19
+ </div>
20
+
21
+ ## Better Auth
22
+
23
+ Better Auth is a framework-agnostic authentication (and authorization) framework for TypeScript. It provides a comprehensive set of features out of the box and includes a plugin ecosystem that simplifies adding advanced functionalities with minimal code in a short amount of time. Whether you need 2FA, multi-tenant support, or other complex features, it lets you focus on building your actual application instead of reinventing the wheel.
25
24
 
26
25
  ## Getting Started
27
26
 
28
27
  ```bash
29
- pnpm install better-auth
28
+ npm i better-auth
30
29
  ```
31
30
 
32
31
  Read the [Installation Guide](https://better-auth.com/docs/installation) to
@@ -0,0 +1,34 @@
1
+ import { AuthContext } from "@better-auth/core";
2
+ import { Endpoint, EndpointContext, InputContext } from "better-call";
3
+
4
+ //#region src/api/dispatch.d.ts
5
+ /**
6
+ * Input accepted by {@link dispatchAuthEndpoint}. `context` must already be a
7
+ * resolved `AuthContext`; the caller owns `baseURL` resolution. A fresh
8
+ * dispatch carries no `session` (the shared context has none), while a resumed
9
+ * dispatch carries the in-flight request's `session` through.
10
+ */
11
+ type DispatchContext = Partial<InputContext<string, any> & EndpointContext<string, any>> & {
12
+ context: AuthContext & {
13
+ returned?: unknown | undefined;
14
+ responseHeaders?: Headers | undefined;
15
+ };
16
+ operationId?: string | undefined;
17
+ };
18
+ /**
19
+ * Run a single endpoint through the configured `hooks.before` / `hooks.after`
20
+ * pipeline, normalizing the response, headers, and `APIError`s the same way a
21
+ * router or `auth.api.*` dispatch does.
22
+ *
23
+ * This is the canonical hook runner. The HTTP router and `auth.api.*` reach it
24
+ * through {@link toAuthEndpoints}. Plugins call it directly when they need to
25
+ * re-enter the pipeline on purpose, such as resuming `/oauth2/authorize` after
26
+ * a fresh sign-in. Calling an endpoint as a plain function deliberately skips
27
+ * hooks; `dispatchAuthEndpoint` is the supported way to opt back in.
28
+ *
29
+ * @param endpoint The endpoint to dispatch.
30
+ * @param input Input context whose `context` is an already-resolved `AuthContext`.
31
+ */
32
+ declare function dispatchAuthEndpoint(endpoint: Endpoint, input: DispatchContext): Promise<unknown>;
33
+ //#endregion
34
+ export { DispatchContext, dispatchAuthEndpoint };
@@ -0,0 +1,272 @@
1
+ import { isAPIError } from "../utils/is-api-error.mjs";
2
+ import { isRequestLike } from "../utils/url.mjs";
3
+ import { runWithEndpointContext } from "@better-auth/core/context";
4
+ import { shouldPublishLog } from "@better-auth/core/env";
5
+ import { APIError } from "@better-auth/core/error";
6
+ import { createDefu } from "defu";
7
+ import { ATTR_CONTEXT, ATTR_HOOK_TYPE, ATTR_HTTP_ROUTE, ATTR_OPERATION_ID, withSpan } from "@better-auth/core/instrumentation";
8
+ import { kAPIErrorHeaderSymbol, toResponse } from "better-call";
9
+ //#region src/api/dispatch.ts
10
+ const defuReplaceArrays = createDefu((obj, key, value) => {
11
+ if (Array.isArray(obj[key]) && Array.isArray(value)) {
12
+ obj[key] = value;
13
+ return true;
14
+ }
15
+ });
16
+ const hooksSourceWeakMap = /* @__PURE__ */ new WeakMap();
17
+ /**
18
+ * Resolves the operation id used for spans, preferring an explicit
19
+ * `operationId`, then the OpenAPI one, then the caller's `fallback` (the
20
+ * `auth.api.*` map key), and finally the route path.
21
+ */
22
+ function getOperationId(endpoint, fallback) {
23
+ const opts = endpoint.options;
24
+ return opts?.operationId ?? opts?.metadata?.openapi?.operationId ?? fallback ?? endpoint.path ?? "/:virtual";
25
+ }
26
+ /**
27
+ * Merge a set of response headers onto the dispatch's accumulator, appending
28
+ * `set-cookie` (multiple cookies are legal) and replacing everything else.
29
+ */
30
+ function mergeResponseHeaders(context, headers) {
31
+ if (!headers) return;
32
+ headers.forEach((value, key) => {
33
+ if (!context.responseHeaders) context.responseHeaders = new Headers({ [key]: value });
34
+ else if (key.toLowerCase() === "set-cookie") context.responseHeaders.append(key, value);
35
+ else context.responseHeaders.set(key, value);
36
+ });
37
+ }
38
+ /**
39
+ * Combine the two header sources an `APIError` can carry into one set:
40
+ * - `kAPIErrorHeaderSymbol`: `ctx.responseHeaders` accumulated via
41
+ * `c.setCookie` / `c.setHeader` before the throw.
42
+ * - `e.headers`: explicit headers on the error (e.g. `location` from
43
+ * `c.redirect`).
44
+ *
45
+ * `c.redirect()` reuses `ctx.responseHeaders` as `e.headers`, so when both
46
+ * point at the same object iterating each would duplicate every `set-cookie`;
47
+ * the identity check skips that copy. Explicit error headers override
48
+ * accumulated ones, while cookies from both accumulate.
49
+ */
50
+ function mergeAPIErrorHeaders(error) {
51
+ const ctxHeaders = error[kAPIErrorHeaderSymbol];
52
+ const errHeaders = error.headers && error.headers !== ctxHeaders ? new Headers(error.headers) : null;
53
+ if (!ctxHeaders && !errHeaders) return null;
54
+ const headers = new Headers();
55
+ ctxHeaders?.forEach((value, key) => {
56
+ headers.append(key, value);
57
+ });
58
+ errHeaders?.forEach((value, key) => {
59
+ if (key.toLowerCase() === "set-cookie") headers.append(key, value);
60
+ else headers.set(key, value);
61
+ });
62
+ return headers;
63
+ }
64
+ async function runBeforeHooks(context, hooks, endpoint, operationId) {
65
+ let modifiedContext = {};
66
+ for (const hook of hooks) {
67
+ let matched = false;
68
+ try {
69
+ matched = hook.matcher(context);
70
+ } catch (error) {
71
+ const hookSource = hooksSourceWeakMap.get(hook.handler) ?? "unknown";
72
+ context.context.logger.error(`An error occurred during ${hookSource} hook matcher execution:`, error);
73
+ throw new APIError("INTERNAL_SERVER_ERROR", { message: "An error occurred during hook matcher execution. Check the logs for more details." });
74
+ }
75
+ if (!matched) continue;
76
+ const hookSource = hooksSourceWeakMap.get(hook.handler) ?? "unknown";
77
+ const route = endpoint.path ?? "/:virtual";
78
+ const result = await withSpan(`hook before ${route} ${hookSource}`, {
79
+ [ATTR_HOOK_TYPE]: "before",
80
+ [ATTR_HTTP_ROUTE]: route,
81
+ [ATTR_CONTEXT]: hookSource,
82
+ [ATTR_OPERATION_ID]: operationId
83
+ }, () => hook.handler({
84
+ ...context,
85
+ returnHeaders: true
86
+ })).catch((e) => {
87
+ if (isAPIError(e) && shouldPublishLog(context.context.logger.level, "debug")) e.stack = e.errorStack;
88
+ throw e;
89
+ });
90
+ mergeResponseHeaders(context.context, result?.headers);
91
+ const hookReturn = result?.response;
92
+ if (hookReturn && typeof hookReturn === "object") {
93
+ if ("context" in hookReturn && typeof hookReturn.context === "object") {
94
+ const { headers, ...rest } = hookReturn.context;
95
+ if (headers instanceof Headers) if (modifiedContext.headers) headers.forEach((value, key) => {
96
+ modifiedContext.headers?.set(key, value);
97
+ });
98
+ else modifiedContext.headers = headers;
99
+ modifiedContext = defuReplaceArrays(rest, modifiedContext);
100
+ continue;
101
+ }
102
+ return hookReturn;
103
+ }
104
+ }
105
+ return { context: modifiedContext };
106
+ }
107
+ async function runAfterHooks(context, hooks, endpoint, operationId) {
108
+ for (const hook of hooks) {
109
+ if (!hook.matcher(context)) continue;
110
+ const hookSource = hooksSourceWeakMap.get(hook.handler) ?? "unknown";
111
+ const route = endpoint.path ?? "/:virtual";
112
+ const result = await withSpan(`hook after ${route} ${hookSource}`, {
113
+ [ATTR_HOOK_TYPE]: "after",
114
+ [ATTR_HTTP_ROUTE]: route,
115
+ [ATTR_CONTEXT]: hookSource,
116
+ [ATTR_OPERATION_ID]: operationId
117
+ }, () => hook.handler(context)).catch((e) => {
118
+ if (isAPIError(e)) {
119
+ if (shouldPublishLog(context.context.logger.level, "debug")) e.stack = e.errorStack;
120
+ return {
121
+ response: e,
122
+ headers: mergeAPIErrorHeaders(e)
123
+ };
124
+ }
125
+ throw e;
126
+ });
127
+ mergeResponseHeaders(context.context, result.headers);
128
+ if (result.response !== void 0) context.context.returned = result.response;
129
+ }
130
+ return {
131
+ response: context.context.returned,
132
+ headers: context.context.responseHeaders
133
+ };
134
+ }
135
+ function getHooks(authContext) {
136
+ const plugins = authContext.options.plugins || [];
137
+ const beforeHooks = [];
138
+ const afterHooks = [];
139
+ const beforeHookHandler = authContext.options.hooks?.before;
140
+ if (beforeHookHandler) {
141
+ hooksSourceWeakMap.set(beforeHookHandler, "user");
142
+ beforeHooks.push({
143
+ matcher: () => true,
144
+ handler: beforeHookHandler
145
+ });
146
+ }
147
+ const afterHookHandler = authContext.options.hooks?.after;
148
+ if (afterHookHandler) {
149
+ hooksSourceWeakMap.set(afterHookHandler, "user");
150
+ afterHooks.push({
151
+ matcher: () => true,
152
+ handler: afterHookHandler
153
+ });
154
+ }
155
+ const pluginBeforeHooks = plugins.flatMap((plugin) => (plugin.hooks?.before ?? []).map((h) => {
156
+ hooksSourceWeakMap.set(h.handler, `plugin:${plugin.id}`);
157
+ return h;
158
+ }));
159
+ const pluginAfterHooks = plugins.flatMap((plugin) => (plugin.hooks?.after ?? []).map((h) => {
160
+ hooksSourceWeakMap.set(h.handler, `plugin:${plugin.id}`);
161
+ return h;
162
+ }));
163
+ if (pluginBeforeHooks.length) beforeHooks.push(...pluginBeforeHooks);
164
+ if (pluginAfterHooks.length) afterHooks.push(...pluginAfterHooks);
165
+ return {
166
+ beforeHooks,
167
+ afterHooks
168
+ };
169
+ }
170
+ /**
171
+ * Run a single endpoint through the configured `hooks.before` / `hooks.after`
172
+ * pipeline, normalizing the response, headers, and `APIError`s the same way a
173
+ * router or `auth.api.*` dispatch does.
174
+ *
175
+ * This is the canonical hook runner. The HTTP router and `auth.api.*` reach it
176
+ * through {@link toAuthEndpoints}. Plugins call it directly when they need to
177
+ * re-enter the pipeline on purpose, such as resuming `/oauth2/authorize` after
178
+ * a fresh sign-in. Calling an endpoint as a plain function deliberately skips
179
+ * hooks; `dispatchAuthEndpoint` is the supported way to opt back in.
180
+ *
181
+ * @param endpoint The endpoint to dispatch.
182
+ * @param input Input context whose `context` is an already-resolved `AuthContext`.
183
+ */
184
+ async function dispatchAuthEndpoint(endpoint, input) {
185
+ const operationId = input.operationId ?? getOperationId(endpoint);
186
+ const route = endpoint.path ?? "/:virtual";
187
+ const endpointMethod = endpoint.options?.method;
188
+ const defaultMethod = Array.isArray(endpointMethod) ? endpointMethod[0] : endpointMethod;
189
+ const methodName = input.method ?? input.request?.method ?? defaultMethod ?? "?";
190
+ const shouldReturnResponse = input.asResponse ?? isRequestLike(input.request);
191
+ let internalContext = {
192
+ ...input,
193
+ context: {
194
+ ...input.context,
195
+ returned: void 0,
196
+ responseHeaders: void 0,
197
+ session: input.context.session ?? null
198
+ },
199
+ path: endpoint.path,
200
+ headers: input.headers ? new Headers(input.headers) : void 0
201
+ };
202
+ return withSpan(`${methodName} ${route}`, {
203
+ [ATTR_HTTP_ROUTE]: route,
204
+ [ATTR_OPERATION_ID]: operationId
205
+ }, async () => runWithEndpointContext(internalContext, async () => {
206
+ const { beforeHooks, afterHooks } = getHooks(internalContext.context);
207
+ const before = await runBeforeHooks(internalContext, beforeHooks, endpoint, operationId);
208
+ if ("context" in before && before.context && typeof before.context === "object") {
209
+ const { headers, ...rest } = before.context;
210
+ if (headers) {
211
+ if (!internalContext.headers) internalContext.headers = new Headers();
212
+ const requestHeaders = internalContext.headers;
213
+ headers.forEach((value, key) => {
214
+ requestHeaders.set(key, value);
215
+ });
216
+ }
217
+ internalContext = defuReplaceArrays(rest, internalContext);
218
+ } else if (before) {
219
+ const responseHeaders = internalContext.context.responseHeaders;
220
+ return shouldReturnResponse ? toResponse(before, { headers: responseHeaders }) : input.returnHeaders ? {
221
+ headers: responseHeaders,
222
+ response: before
223
+ } : before;
224
+ }
225
+ internalContext.asResponse = false;
226
+ internalContext.returnHeaders = true;
227
+ internalContext.returnStatus = true;
228
+ const result = await runWithEndpointContext(internalContext, () => withSpan(`handler ${route}`, {
229
+ [ATTR_HTTP_ROUTE]: route,
230
+ [ATTR_OPERATION_ID]: operationId
231
+ }, () => endpoint(internalContext))).catch((e) => {
232
+ if (isAPIError(e)) return {
233
+ response: e,
234
+ status: e.statusCode,
235
+ headers: mergeAPIErrorHeaders(e)
236
+ };
237
+ throw e;
238
+ });
239
+ if (result instanceof Response) return result;
240
+ internalContext.context.returned = result.response;
241
+ internalContext.context.responseHeaders = result.headers ?? void 0;
242
+ const after = await runAfterHooks(internalContext, afterHooks, endpoint, operationId);
243
+ if (after.response !== void 0) result.response = after.response;
244
+ result.headers = after.headers ?? result.headers;
245
+ if (isAPIError(result.response) && shouldPublishLog(internalContext.context.logger.level, "debug")) result.response.stack = result.response.errorStack;
246
+ if (isAPIError(result.response) && !shouldReturnResponse) {
247
+ if (result.headers) Object.defineProperty(result.response, kAPIErrorHeaderSymbol, {
248
+ enumerable: false,
249
+ configurable: true,
250
+ writable: false,
251
+ value: result.headers
252
+ });
253
+ throw result.response;
254
+ }
255
+ return shouldReturnResponse ? toResponse(result.response, {
256
+ headers: result.headers ?? void 0,
257
+ status: result.status
258
+ }) : input.returnHeaders ? input.returnStatus ? {
259
+ headers: result.headers,
260
+ response: result.response,
261
+ status: result.status
262
+ } : {
263
+ headers: result.headers,
264
+ response: result.response
265
+ } : input.returnStatus ? {
266
+ response: result.response,
267
+ status: result.status
268
+ } : result.response;
269
+ }));
270
+ }
271
+ //#endregion
272
+ export { dispatchAuthEndpoint, getOperationId };
@@ -1,7 +1,7 @@
1
1
  import { OverrideMerge, Prettify as Prettify$1, UnionToIntersection } from "../types/helper.mjs";
2
2
  import { AdditionalSessionFieldsInput, AdditionalUserFieldsInput } from "../types/models.mjs";
3
- import { getIp } from "../utils/get-request-ip.mjs";
4
3
  import { isAPIError } from "../utils/is-api-error.mjs";
4
+ import { DispatchContext, dispatchAuthEndpoint } from "./dispatch.mjs";
5
5
  import { requireOrgRole, requireResourceOwnership } from "./middlewares/authorization.mjs";
6
6
  import { formCsrfMiddleware, originCheck, originCheckMiddleware } from "./middlewares/origin-check.mjs";
7
7
  import { accountInfo, getAccessToken, linkSocialAccount, listUserAccounts, refreshToken, unlinkAccount } from "./routes/account.mjs";
@@ -10,21 +10,22 @@ import { createEmailVerificationToken, sendVerificationEmail, sendVerificationEm
10
10
  import { error } from "./routes/error.mjs";
11
11
  import { ok } from "./routes/ok.mjs";
12
12
  import { requestPasswordReset, requestPasswordResetCallback, resetPassword, verifyPassword } from "./routes/password.mjs";
13
- import { freshSessionMiddleware, getSession, getSessionFromCtx, listSessions, requestOnlySessionMiddleware, revokeOtherSessions, revokeSession, revokeSessions, sensitiveSessionMiddleware, sessionMiddleware } from "./routes/session.mjs";
13
+ import { freshSessionMiddleware, getAuthoritativeSessionFromCtx, getSession, getSessionFromCtx, isStateful, listSessions, requestOnlySessionMiddleware, revokeOtherSessions, revokeSession, revokeSessions, sensitiveSessionMiddleware, sessionMiddleware } from "./routes/session.mjs";
14
14
  import { signInEmail, signInSocial } from "./routes/sign-in.mjs";
15
15
  import { signOut } from "./routes/sign-out.mjs";
16
16
  import { signUpEmail } from "./routes/sign-up.mjs";
17
17
  import { updateSession } from "./routes/update-session.mjs";
18
18
  import { changeEmail, changePassword, deleteUser, deleteUserCallback, setPassword, updateUser } from "./routes/update-user.mjs";
19
- import { getOAuthState } from "./state/oauth.mjs";
19
+ import { addOAuthServerContext, getOAuthState } from "./state/oauth.mjs";
20
20
  import { getShouldSkipSessionRefresh, setShouldSkipSessionRefresh } from "./state/should-session-refresh.mjs";
21
21
  import { AuthContext, Awaitable, BetterAuthOptions, BetterAuthPlugin } from "@better-auth/core";
22
22
  import * as _better_auth_core_db0 from "@better-auth/core/db";
23
23
  import { InternalLogger } from "@better-auth/core/env";
24
24
  import { APIError } from "@better-auth/core/error";
25
25
  import * as _better_auth_core_oauth20 from "@better-auth/core/oauth2";
26
+ import { getIP } from "@better-auth/core/utils/ip";
26
27
  import * as better_call0 from "better-call";
27
- import { AuthEndpoint, AuthMiddleware, createAuthEndpoint, createAuthMiddleware, optionsMiddleware } from "@better-auth/core/api";
28
+ import { AuthEndpoint, AuthMiddleware, NO_STORE_HEADERS, createAuthEndpoint, createAuthMiddleware, optionsMiddleware } from "@better-auth/core/api";
28
29
  import * as zod from "zod";
29
30
  import * as zod_v4_core0 from "zod/v4/core";
30
31
 
@@ -110,6 +111,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
110
111
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
111
112
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
112
113
  loginHint: zod.ZodOptional<zod.ZodString>;
114
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
113
115
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
114
116
  }, zod_v4_core0.$strip>;
115
117
  metadata: {
@@ -137,6 +139,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
137
139
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
138
140
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
139
141
  loginHint: zod.ZodOptional<zod.ZodString>;
142
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
140
143
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
141
144
  }, zod_v4_core0.$strip>>;
142
145
  returned: {
@@ -178,7 +181,6 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
178
181
  };
179
182
  redirect: {
180
183
  type: string;
181
- enum: boolean[];
182
184
  };
183
185
  };
184
186
  required: string[];
@@ -330,6 +332,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
330
332
  callbackURL: zod.ZodOptional<zod.ZodString>;
331
333
  rememberMe: zod.ZodOptional<zod.ZodBoolean>;
332
334
  }, zod_v4_core0.$strip>, zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
335
+ cloneRequest: true;
333
336
  metadata: {
334
337
  allowedMediaTypes: string[];
335
338
  $Infer: {
@@ -496,6 +499,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
496
499
  method: "POST";
497
500
  operationId: string;
498
501
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>)[];
502
+ cloneRequest: true;
499
503
  body: zod.ZodObject<{
500
504
  email: zod.ZodString;
501
505
  password: zod.ZodString;
@@ -727,6 +731,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
727
731
  readonly sendVerificationEmail: better_call0.StrictEndpoint<"/send-verification-email", {
728
732
  method: "POST";
729
733
  operationId: string;
734
+ cloneRequest: true;
730
735
  body: zod.ZodObject<{
731
736
  email: zod.ZodEmail;
732
737
  callbackURL: zod.ZodOptional<zod.ZodString>;
@@ -1577,12 +1582,13 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
1577
1582
  nonce: zod.ZodOptional<zod.ZodString>;
1578
1583
  accessToken: zod.ZodOptional<zod.ZodString>;
1579
1584
  refreshToken: zod.ZodOptional<zod.ZodString>;
1580
- scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
1581
1585
  }, zod_v4_core0.$strip>>;
1582
1586
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
1583
1587
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
1584
1588
  errorCallbackURL: zod.ZodOptional<zod.ZodString>;
1585
1589
  disableRedirect: zod.ZodOptional<zod.ZodBoolean>;
1590
+ loginHint: zod.ZodOptional<zod.ZodString>;
1591
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
1586
1592
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
1587
1593
  }, zod_v4_core0.$strip>;
1588
1594
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
@@ -1931,29 +1937,6 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
1931
1937
  }>;
1932
1938
  readonly accountInfo: better_call0.StrictEndpoint<"/account-info", {
1933
1939
  method: "GET";
1934
- use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
1935
- session: {
1936
- session: Record<string, any> & {
1937
- id: string;
1938
- createdAt: Date;
1939
- updatedAt: Date;
1940
- userId: string;
1941
- expiresAt: Date;
1942
- token: string;
1943
- ipAddress?: string | null | undefined;
1944
- userAgent?: string | null | undefined;
1945
- };
1946
- user: Record<string, any> & {
1947
- id: string;
1948
- createdAt: Date;
1949
- updatedAt: Date;
1950
- email: string;
1951
- emailVerified: boolean;
1952
- name: string;
1953
- image?: string | null | undefined;
1954
- };
1955
- };
1956
- }>)[];
1957
1940
  metadata: {
1958
1941
  openapi: {
1959
1942
  description: string;
@@ -2003,6 +1986,8 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
2003
1986
  };
2004
1987
  query: zod.ZodOptional<zod.ZodObject<{
2005
1988
  accountId: zod.ZodOptional<zod.ZodString>;
1989
+ providerId: zod.ZodOptional<zod.ZodString>;
1990
+ userId: zod.ZodOptional<zod.ZodString>;
2006
1991
  }, zod_v4_core0.$strip>>;
2007
1992
  }, {
2008
1993
  user: _better_auth_core_oauth20.OAuth2UserInfo;
@@ -2101,6 +2086,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2101
2086
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
2102
2087
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
2103
2088
  loginHint: zod.ZodOptional<zod.ZodString>;
2089
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
2104
2090
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
2105
2091
  }, zod_v4_core0.$strip>;
2106
2092
  metadata: {
@@ -2128,6 +2114,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2128
2114
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
2129
2115
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
2130
2116
  loginHint: zod.ZodOptional<zod.ZodString>;
2117
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
2131
2118
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
2132
2119
  }, zod_v4_core0.$strip>>;
2133
2120
  returned: {
@@ -2169,7 +2156,6 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2169
2156
  };
2170
2157
  redirect: {
2171
2158
  type: string;
2172
- enum: boolean[];
2173
2159
  };
2174
2160
  };
2175
2161
  required: string[];
@@ -2321,6 +2307,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2321
2307
  callbackURL: zod.ZodOptional<zod.ZodString>;
2322
2308
  rememberMe: zod.ZodOptional<zod.ZodBoolean>;
2323
2309
  }, zod_v4_core0.$strip>, zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
2310
+ cloneRequest: true;
2324
2311
  metadata: {
2325
2312
  allowedMediaTypes: string[];
2326
2313
  $Infer: {
@@ -2487,6 +2474,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2487
2474
  method: "POST";
2488
2475
  operationId: string;
2489
2476
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>)[];
2477
+ cloneRequest: true;
2490
2478
  body: zod.ZodObject<{
2491
2479
  email: zod.ZodString;
2492
2480
  password: zod.ZodString;
@@ -2718,6 +2706,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2718
2706
  readonly sendVerificationEmail: better_call0.StrictEndpoint<"/send-verification-email", {
2719
2707
  method: "POST";
2720
2708
  operationId: string;
2709
+ cloneRequest: true;
2721
2710
  body: zod.ZodObject<{
2722
2711
  email: zod.ZodEmail;
2723
2712
  callbackURL: zod.ZodOptional<zod.ZodString>;
@@ -3568,12 +3557,13 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
3568
3557
  nonce: zod.ZodOptional<zod.ZodString>;
3569
3558
  accessToken: zod.ZodOptional<zod.ZodString>;
3570
3559
  refreshToken: zod.ZodOptional<zod.ZodString>;
3571
- scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
3572
3560
  }, zod_v4_core0.$strip>>;
3573
3561
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
3574
3562
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
3575
3563
  errorCallbackURL: zod.ZodOptional<zod.ZodString>;
3576
3564
  disableRedirect: zod.ZodOptional<zod.ZodBoolean>;
3565
+ loginHint: zod.ZodOptional<zod.ZodString>;
3566
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
3577
3567
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
3578
3568
  }, zod_v4_core0.$strip>;
3579
3569
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
@@ -3922,29 +3912,6 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
3922
3912
  }>;
3923
3913
  readonly accountInfo: better_call0.StrictEndpoint<"/account-info", {
3924
3914
  method: "GET";
3925
- use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
3926
- session: {
3927
- session: Record<string, any> & {
3928
- id: string;
3929
- createdAt: Date;
3930
- updatedAt: Date;
3931
- userId: string;
3932
- expiresAt: Date;
3933
- token: string;
3934
- ipAddress?: string | null | undefined;
3935
- userAgent?: string | null | undefined;
3936
- };
3937
- user: Record<string, any> & {
3938
- id: string;
3939
- createdAt: Date;
3940
- updatedAt: Date;
3941
- email: string;
3942
- emailVerified: boolean;
3943
- name: string;
3944
- image?: string | null | undefined;
3945
- };
3946
- };
3947
- }>)[];
3948
3915
  metadata: {
3949
3916
  openapi: {
3950
3917
  description: string;
@@ -3994,6 +3961,8 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
3994
3961
  };
3995
3962
  query: zod.ZodOptional<zod.ZodObject<{
3996
3963
  accountId: zod.ZodOptional<zod.ZodString>;
3964
+ providerId: zod.ZodOptional<zod.ZodString>;
3965
+ userId: zod.ZodOptional<zod.ZodString>;
3997
3966
  }, zod_v4_core0.$strip>>;
3998
3967
  }, {
3999
3968
  user: _better_auth_core_oauth20.OAuth2UserInfo;
@@ -4002,4 +3971,4 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
4002
3971
  } extends infer T_2 ? { [K in keyof T_2 as K extends keyof T_1 ? never : K]: T_2[K] } : never) & T_1> : never : never : never;
4003
3972
  };
4004
3973
  //#endregion
4005
- export { APIError, type AuthEndpoint, type AuthMiddleware, accountInfo, callbackOAuth, changeEmail, changePassword, checkEndpointConflicts, createAuthEndpoint, createAuthMiddleware, createEmailVerificationToken, deleteUser, deleteUserCallback, error, formCsrfMiddleware, freshSessionMiddleware, getAccessToken, getEndpoints, getIp, getOAuthState, getSession, getSessionFromCtx, getShouldSkipSessionRefresh, isAPIError, linkSocialAccount, listSessions, listUserAccounts, ok, optionsMiddleware, originCheck, originCheckMiddleware, refreshToken, requestOnlySessionMiddleware, requestPasswordReset, requestPasswordResetCallback, requireOrgRole, requireResourceOwnership, resetPassword, revokeOtherSessions, revokeSession, revokeSessions, router, sendVerificationEmail, sendVerificationEmailFn, sensitiveSessionMiddleware, sessionMiddleware, setPassword, setShouldSkipSessionRefresh, signInEmail, signInSocial, signOut, signUpEmail, unlinkAccount, updateSession, updateUser, verifyEmail, verifyPassword };
3974
+ export { APIError, type AuthEndpoint, type AuthMiddleware, type DispatchContext, NO_STORE_HEADERS, accountInfo, addOAuthServerContext, callbackOAuth, changeEmail, changePassword, checkEndpointConflicts, createAuthEndpoint, createAuthMiddleware, createEmailVerificationToken, deleteUser, deleteUserCallback, dispatchAuthEndpoint, error, formCsrfMiddleware, freshSessionMiddleware, getAccessToken, getAuthoritativeSessionFromCtx, getEndpoints, getIP, getOAuthState, getSession, getSessionFromCtx, getShouldSkipSessionRefresh, isAPIError, isStateful, linkSocialAccount, listSessions, listUserAccounts, ok, optionsMiddleware, originCheck, originCheckMiddleware, refreshToken, requestOnlySessionMiddleware, requestPasswordReset, requestPasswordResetCallback, requireOrgRole, requireResourceOwnership, resetPassword, revokeOtherSessions, revokeSession, revokeSessions, router, sendVerificationEmail, sendVerificationEmailFn, sensitiveSessionMiddleware, sessionMiddleware, setPassword, setShouldSkipSessionRefresh, signInEmail, signInSocial, signOut, signUpEmail, unlinkAccount, updateSession, updateUser, verifyEmail, verifyPassword };
@@ -1,11 +1,10 @@
1
1
  import { isAPIError } from "../utils/is-api-error.mjs";
2
2
  import { requireOrgRole, requireResourceOwnership } from "./middlewares/authorization.mjs";
3
3
  import { formCsrfMiddleware, originCheck, originCheckMiddleware } from "./middlewares/origin-check.mjs";
4
- import { getIp } from "../utils/get-request-ip.mjs";
5
- import { onRequestRateLimit, onResponseRateLimit } from "./rate-limiter/index.mjs";
6
- import { getOAuthState } from "./state/oauth.mjs";
4
+ import { onRequestRateLimit } from "./rate-limiter/index.mjs";
5
+ import { addOAuthServerContext, getOAuthState } from "./state/oauth.mjs";
7
6
  import { getShouldSkipSessionRefresh, setShouldSkipSessionRefresh } from "./state/should-session-refresh.mjs";
8
- import { freshSessionMiddleware, getSession, getSessionFromCtx, listSessions, requestOnlySessionMiddleware, revokeOtherSessions, revokeSession, revokeSessions, sensitiveSessionMiddleware, sessionMiddleware } from "./routes/session.mjs";
7
+ import { freshSessionMiddleware, getAuthoritativeSessionFromCtx, getSession, getSessionFromCtx, isStateful, listSessions, requestOnlySessionMiddleware, revokeOtherSessions, revokeSession, revokeSessions, sensitiveSessionMiddleware, sessionMiddleware } from "./routes/session.mjs";
9
8
  import { accountInfo, getAccessToken, linkSocialAccount, listUserAccounts, refreshToken, unlinkAccount } from "./routes/account.mjs";
10
9
  import { callbackOAuth } from "./routes/callback.mjs";
11
10
  import { createEmailVerificationToken, sendVerificationEmail, sendVerificationEmailFn, verifyEmail } from "./routes/email-verification.mjs";
@@ -17,13 +16,15 @@ import { signOut } from "./routes/sign-out.mjs";
17
16
  import { signUpEmail } from "./routes/sign-up.mjs";
18
17
  import { updateSession } from "./routes/update-session.mjs";
19
18
  import { changeEmail, changePassword, deleteUser, deleteUserCallback, setPassword, updateUser } from "./routes/update-user.mjs";
19
+ import { dispatchAuthEndpoint } from "./dispatch.mjs";
20
20
  import { toAuthEndpoints } from "./to-auth-endpoints.mjs";
21
21
  import { logger } from "@better-auth/core/env";
22
22
  import { APIError } from "@better-auth/core/error";
23
+ import { getIP } from "@better-auth/core/utils/ip";
23
24
  import { ATTR_CONTEXT, ATTR_HOOK_TYPE, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_HTTP_ROUTE, withSpan } from "@better-auth/core/instrumentation";
24
25
  import { normalizePathname } from "@better-auth/core/utils/url";
25
26
  import { createRouter } from "better-call";
26
- import { createAuthEndpoint, createAuthMiddleware, optionsMiddleware } from "@better-auth/core/api";
27
+ import { NO_STORE_HEADERS, createAuthEndpoint, createAuthMiddleware, optionsMiddleware } from "@better-auth/core/api";
27
28
  //#region src/api/index.ts
28
29
  function checkEndpointConflicts(options, logger) {
29
30
  const endpointRegistry = /* @__PURE__ */ new Map();
@@ -164,6 +165,8 @@ const router = (ctx, options) => {
164
165
  const normalizedPath = normalizePathname(req.url, basePath);
165
166
  if (disabledPaths.includes(normalizedPath)) return new Response("Not Found", { status: 404 });
166
167
  let currentRequest = req;
168
+ const rateLimitResponse = await onRequestRateLimit(currentRequest, ctx);
169
+ if (rateLimitResponse) return rateLimitResponse;
167
170
  for (const plugin of ctx.options.plugins || []) if (plugin.onRequest) {
168
171
  const response = await withSpan(`onRequest ${plugin.id}`, {
169
172
  [ATTR_HOOK_TYPE]: "onRequest",
@@ -172,12 +175,9 @@ const router = (ctx, options) => {
172
175
  if (response && "response" in response) return response.response;
173
176
  if (response && "request" in response) currentRequest = response.request;
174
177
  }
175
- const rateLimitResponse = await onRequestRateLimit(currentRequest, ctx);
176
- if (rateLimitResponse) return rateLimitResponse;
177
178
  return currentRequest;
178
179
  },
179
180
  async onResponse(res, req) {
180
- await onResponseRateLimit(req, ctx);
181
181
  for (const plugin of ctx.options.plugins || []) if (plugin.onResponse) {
182
182
  const response = await withSpan(`onResponse ${plugin.id}`, {
183
183
  [ATTR_HOOK_TYPE]: "onResponse",
@@ -213,4 +213,4 @@ const router = (ctx, options) => {
213
213
  });
214
214
  };
215
215
  //#endregion
216
- export { APIError, accountInfo, callbackOAuth, changeEmail, changePassword, checkEndpointConflicts, createAuthEndpoint, createAuthMiddleware, createEmailVerificationToken, deleteUser, deleteUserCallback, error, formCsrfMiddleware, freshSessionMiddleware, getAccessToken, getEndpoints, getIp, getOAuthState, getSession, getSessionFromCtx, getShouldSkipSessionRefresh, isAPIError, linkSocialAccount, listSessions, listUserAccounts, ok, optionsMiddleware, originCheck, originCheckMiddleware, refreshToken, requestOnlySessionMiddleware, requestPasswordReset, requestPasswordResetCallback, requireOrgRole, requireResourceOwnership, resetPassword, revokeOtherSessions, revokeSession, revokeSessions, router, sendVerificationEmail, sendVerificationEmailFn, sensitiveSessionMiddleware, sessionMiddleware, setPassword, setShouldSkipSessionRefresh, signInEmail, signInSocial, signOut, signUpEmail, unlinkAccount, updateSession, updateUser, verifyEmail, verifyPassword };
216
+ export { APIError, NO_STORE_HEADERS, accountInfo, addOAuthServerContext, callbackOAuth, changeEmail, changePassword, checkEndpointConflicts, createAuthEndpoint, createAuthMiddleware, createEmailVerificationToken, deleteUser, deleteUserCallback, dispatchAuthEndpoint, error, formCsrfMiddleware, freshSessionMiddleware, getAccessToken, getAuthoritativeSessionFromCtx, getEndpoints, getIP, getOAuthState, getSession, getSessionFromCtx, getShouldSkipSessionRefresh, isAPIError, isStateful, linkSocialAccount, listSessions, listUserAccounts, ok, optionsMiddleware, originCheck, originCheckMiddleware, refreshToken, requestOnlySessionMiddleware, requestPasswordReset, requestPasswordResetCallback, requireOrgRole, requireResourceOwnership, resetPassword, revokeOtherSessions, revokeSession, revokeSessions, router, sendVerificationEmail, sendVerificationEmailFn, sensitiveSessionMiddleware, sessionMiddleware, setPassword, setShouldSkipSessionRefresh, signInEmail, signInSocial, signOut, signUpEmail, unlinkAccount, updateSession, updateUser, verifyEmail, verifyPassword };