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.
- package/README.md +14 -15
- package/dist/api/dispatch.d.mts +34 -0
- package/dist/api/dispatch.mjs +272 -0
- package/dist/api/index.d.mts +24 -55
- package/dist/api/index.mjs +9 -9
- package/dist/api/middlewares/origin-check.mjs +6 -1
- package/dist/api/rate-limiter/index.mjs +215 -98
- package/dist/api/routes/account.d.mts +4 -24
- package/dist/api/routes/account.mjs +169 -116
- package/dist/api/routes/callback.mjs +88 -29
- package/dist/api/routes/email-verification.d.mts +1 -0
- package/dist/api/routes/email-verification.mjs +24 -10
- package/dist/api/routes/error.mjs +1 -1
- package/dist/api/routes/index.d.mts +1 -1
- package/dist/api/routes/password.mjs +4 -5
- package/dist/api/routes/session.d.mts +41 -3
- package/dist/api/routes/session.mjs +127 -98
- package/dist/api/routes/sign-in.d.mts +3 -1
- package/dist/api/routes/sign-in.mjs +43 -29
- package/dist/api/routes/sign-up.d.mts +1 -0
- package/dist/api/routes/sign-up.mjs +46 -38
- package/dist/api/routes/update-session.mjs +9 -4
- package/dist/api/routes/update-user.mjs +18 -20
- package/dist/api/state/oauth.d.mts +38 -2
- package/dist/api/state/oauth.mjs +35 -2
- package/dist/api/to-auth-endpoints.mjs +14 -213
- package/dist/auth/base.mjs +34 -27
- package/dist/auth/trusted-origins.mjs +60 -1
- package/dist/client/config.d.mts +88 -0
- package/dist/client/config.mjs +9 -2
- package/dist/client/equality.d.mts +19 -0
- package/dist/client/equality.mjs +42 -0
- package/dist/client/fetch-plugins.mjs +2 -1
- package/dist/client/index.d.mts +6 -5
- package/dist/client/index.mjs +2 -1
- package/dist/client/lynx/index.d.mts +21 -104
- package/dist/client/lynx/index.mjs +2 -1
- package/dist/client/parser.mjs +0 -1
- package/dist/client/path-to-object.d.mts +5 -2
- package/dist/client/plugins/index.d.mts +7 -19
- package/dist/client/plugins/index.mjs +4 -5
- package/dist/client/proxy.mjs +2 -1
- package/dist/client/query.d.mts +4 -3
- package/dist/client/query.mjs +27 -17
- package/dist/client/react/index.d.mts +21 -104
- package/dist/client/react/index.mjs +2 -1
- package/dist/client/session-atom.d.mts +11 -0
- package/dist/client/session-atom.mjs +141 -5
- package/dist/client/session-refresh.d.mts +3 -18
- package/dist/client/session-refresh.mjs +38 -49
- package/dist/client/solid/index.d.mts +20 -98
- package/dist/client/solid/index.mjs +3 -2
- package/dist/client/svelte/index.d.mts +21 -104
- package/dist/client/svelte/index.mjs +2 -1
- package/dist/client/types.d.mts +27 -16
- package/dist/client/vanilla.d.mts +20 -104
- package/dist/client/vanilla.mjs +2 -1
- package/dist/client/vue/index.d.mts +40 -134
- package/dist/client/vue/index.mjs +2 -1
- package/dist/context/create-context.mjs +30 -16
- package/dist/context/helpers.mjs +9 -6
- package/dist/context/store-capabilities.mjs +12 -0
- package/dist/cookies/cookie-utils.d.mts +45 -1
- package/dist/cookies/cookie-utils.mjs +110 -14
- package/dist/cookies/index.d.mts +9 -3
- package/dist/cookies/index.mjs +93 -30
- package/dist/cookies/session-store.d.mts +0 -17
- package/dist/cookies/session-store.mjs +44 -72
- package/dist/db/get-migration.mjs +5 -4
- package/dist/db/get-schema.d.mts +1 -0
- package/dist/db/get-schema.mjs +3 -1
- package/dist/db/index.d.mts +3 -2
- package/dist/db/index.mjs +6 -2
- package/dist/db/internal-adapter.mjs +250 -34
- package/dist/db/revoke-unproven-account-access.d.mts +21 -0
- package/dist/db/revoke-unproven-account-access.mjs +58 -0
- package/dist/db/schema.d.mts +15 -1
- package/dist/db/schema.mjs +38 -1
- package/dist/db/to-zod.d.mts +2 -2
- package/dist/db/to-zod.mjs +1 -1
- package/dist/db/with-hooks.d.mts +1 -0
- package/dist/db/with-hooks.mjs +58 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +3 -3
- package/dist/integrations/cookie-plugin-guard.mjs +18 -0
- package/dist/integrations/next-js.mjs +8 -10
- package/dist/integrations/svelte-kit.mjs +11 -10
- package/dist/integrations/tanstack-start-solid.mjs +8 -10
- package/dist/integrations/tanstack-start.mjs +8 -10
- package/dist/oauth2/errors.mjs +48 -0
- package/dist/oauth2/index.d.mts +4 -4
- package/dist/oauth2/index.mjs +4 -4
- package/dist/oauth2/link-account.d.mts +30 -2
- package/dist/oauth2/link-account.mjs +129 -33
- package/dist/oauth2/state.d.mts +33 -5
- package/dist/oauth2/state.mjs +30 -10
- package/dist/oauth2/utils.d.mts +6 -2
- package/dist/oauth2/utils.mjs +5 -1
- package/dist/package.mjs +1 -1
- package/dist/plugins/access/access.d.mts +3 -15
- package/dist/plugins/access/access.mjs +52 -17
- package/dist/plugins/access/index.d.mts +2 -2
- package/dist/plugins/access/types.d.mts +11 -4
- package/dist/plugins/admin/access/statement.d.mts +34 -98
- package/dist/plugins/admin/access/statement.mjs +2 -0
- package/dist/plugins/admin/admin.d.mts +6 -3
- package/dist/plugins/admin/admin.mjs +0 -4
- package/dist/plugins/admin/client.d.mts +12 -5
- package/dist/plugins/admin/client.mjs +5 -0
- package/dist/plugins/admin/error-codes.d.mts +2 -0
- package/dist/plugins/admin/error-codes.mjs +3 -1
- package/dist/plugins/admin/routes.mjs +84 -12
- package/dist/plugins/admin/schema.d.mts +1 -0
- package/dist/plugins/admin/schema.mjs +2 -1
- package/dist/plugins/anonymous/client.d.mts +1 -0
- package/dist/plugins/anonymous/error-codes.d.mts +1 -0
- package/dist/plugins/anonymous/error-codes.mjs +1 -0
- package/dist/plugins/anonymous/index.d.mts +5 -0
- package/dist/plugins/anonymous/index.mjs +97 -40
- package/dist/plugins/bearer/index.mjs +5 -12
- package/dist/plugins/captcha/constants.mjs +8 -1
- package/dist/plugins/captcha/index.mjs +22 -5
- package/dist/plugins/captcha/types.d.mts +25 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs +2 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +7 -2
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +7 -2
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +2 -0
- package/dist/plugins/custom-session/index.d.mts +6 -5
- package/dist/plugins/custom-session/index.mjs +3 -15
- package/dist/plugins/device-authorization/error-codes.mjs +1 -0
- package/dist/plugins/device-authorization/index.d.mts +13 -9
- package/dist/plugins/device-authorization/index.mjs +1 -1
- package/dist/plugins/device-authorization/routes.mjs +154 -100
- package/dist/plugins/email-otp/index.mjs +1 -1
- package/dist/plugins/email-otp/otp-token.mjs +1 -1
- package/dist/plugins/email-otp/routes.mjs +39 -63
- package/dist/plugins/generic-oauth/error-codes.mjs +0 -1
- package/dist/plugins/generic-oauth/index.d.mts +4 -6
- package/dist/plugins/generic-oauth/index.mjs +72 -34
- package/dist/plugins/generic-oauth/providers/auth0.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/line.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs +1 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs +1 -0
- package/dist/plugins/generic-oauth/types.d.mts +85 -11
- package/dist/plugins/haveibeenpwned/index.d.mts +1 -1
- package/dist/plugins/haveibeenpwned/index.mjs +5 -1
- package/dist/plugins/index.d.mts +8 -7
- package/dist/plugins/index.mjs +6 -5
- package/dist/plugins/jwt/adapter.mjs +21 -2
- package/dist/plugins/jwt/cookie-cache.mjs +117 -0
- package/dist/plugins/jwt/index.d.mts +8 -0
- package/dist/plugins/jwt/index.mjs +6 -6
- package/dist/plugins/jwt/schema.d.mts +8 -0
- package/dist/plugins/jwt/schema.mjs +8 -0
- package/dist/plugins/jwt/sign.d.mts +62 -2
- package/dist/plugins/jwt/sign.mjs +53 -6
- package/dist/plugins/jwt/types.d.mts +45 -1
- package/dist/plugins/jwt/utils.d.mts +1 -1
- package/dist/plugins/jwt/utils.mjs +6 -3
- package/dist/plugins/last-login-method/client.d.mts +10 -0
- package/dist/plugins/last-login-method/client.mjs +6 -3
- package/dist/plugins/magic-link/index.d.mts +8 -1
- package/dist/plugins/magic-link/index.mjs +24 -24
- package/dist/plugins/multi-session/index.mjs +9 -7
- package/dist/plugins/oauth-popup/client.d.mts +82 -0
- package/dist/plugins/oauth-popup/client.mjs +203 -0
- package/dist/plugins/oauth-popup/constants.d.mts +11 -0
- package/dist/plugins/oauth-popup/constants.mjs +11 -0
- package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
- package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
- package/dist/plugins/oauth-popup/index.d.mts +67 -0
- package/dist/plugins/oauth-popup/index.mjs +232 -0
- package/dist/plugins/oauth-popup/types.d.mts +30 -0
- package/dist/plugins/oauth-proxy/index.mjs +67 -39
- package/dist/plugins/oauth-proxy/utils.mjs +19 -12
- package/dist/plugins/one-tap/client.mjs +21 -8
- package/dist/plugins/one-tap/index.d.mts +1 -2
- package/dist/plugins/one-tap/index.mjs +52 -51
- package/dist/plugins/one-time-token/index.mjs +1 -3
- package/dist/plugins/open-api/generator.d.mts +71 -59
- package/dist/plugins/open-api/generator.mjs +247 -89
- package/dist/plugins/open-api/index.d.mts +2 -2
- package/dist/plugins/organization/access/statement.d.mts +68 -201
- package/dist/plugins/organization/adapter.d.mts +34 -8
- package/dist/plugins/organization/adapter.mjs +274 -90
- package/dist/plugins/organization/client.d.mts +7 -5
- package/dist/plugins/organization/client.mjs +1 -1
- package/dist/plugins/organization/error-codes.d.mts +2 -0
- package/dist/plugins/organization/error-codes.mjs +3 -1
- package/dist/plugins/organization/organization.d.mts +6 -6
- package/dist/plugins/organization/organization.mjs +18 -0
- package/dist/plugins/organization/routes/crud-access-control.d.mts +3 -3
- package/dist/plugins/organization/routes/crud-access-control.mjs +1 -1
- package/dist/plugins/organization/routes/crud-invites.d.mts +8 -1
- package/dist/plugins/organization/routes/crud-invites.mjs +88 -32
- package/dist/plugins/organization/routes/crud-members.mjs +59 -6
- package/dist/plugins/organization/routes/crud-org.d.mts +4 -4
- package/dist/plugins/organization/routes/crud-org.mjs +2 -2
- package/dist/plugins/organization/routes/crud-team.d.mts +9 -8
- package/dist/plugins/organization/routes/crud-team.mjs +99 -8
- package/dist/plugins/organization/schema.d.mts +17 -1
- package/dist/plugins/organization/types.d.mts +24 -7
- package/dist/plugins/phone-number/index.d.mts +42 -0
- package/dist/plugins/phone-number/index.mjs +11 -2
- package/dist/plugins/phone-number/routes.mjs +87 -46
- package/dist/plugins/siwe/client.d.mts +4 -0
- package/dist/plugins/siwe/client.mjs +5 -1
- package/dist/plugins/siwe/index.d.mts +13 -2
- package/dist/plugins/siwe/index.mjs +236 -165
- package/dist/plugins/siwe/parse-message.mjs +60 -0
- package/dist/plugins/test-utils/db-helpers.mjs +1 -1
- package/dist/plugins/test-utils/index.d.mts +11 -2
- package/dist/plugins/test-utils/index.mjs +11 -2
- package/dist/plugins/two-factor/backup-codes/index.d.mts +4 -3
- package/dist/plugins/two-factor/backup-codes/index.mjs +26 -11
- package/dist/plugins/two-factor/client.d.mts +1 -0
- package/dist/plugins/two-factor/client.mjs +2 -1
- package/dist/plugins/two-factor/error-code.d.mts +1 -0
- package/dist/plugins/two-factor/error-code.mjs +1 -0
- package/dist/plugins/two-factor/index.d.mts +14 -0
- package/dist/plugins/two-factor/index.mjs +20 -6
- package/dist/plugins/two-factor/otp/index.mjs +26 -13
- package/dist/plugins/two-factor/schema.d.mts +13 -0
- package/dist/plugins/two-factor/schema.mjs +13 -0
- package/dist/plugins/two-factor/totp/index.mjs +24 -10
- package/dist/plugins/two-factor/types.d.mts +25 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs +129 -5
- package/dist/plugins/username/client.d.mts +1 -0
- package/dist/plugins/username/error-codes.d.mts +1 -0
- package/dist/plugins/username/error-codes.mjs +2 -1
- package/dist/plugins/username/index.d.mts +43 -2
- package/dist/plugins/username/index.mjs +130 -49
- package/dist/state.d.mts +15 -2
- package/dist/state.mjs +23 -6
- package/dist/test-utils/headers.mjs +2 -7
- package/dist/test-utils/http-test-instance.d.mts +404 -0
- package/dist/test-utils/http-test-instance.mjs +95 -0
- package/dist/test-utils/index.d.mts +2 -1
- package/dist/test-utils/index.mjs +2 -1
- package/dist/test-utils/test-instance.d.mts +3 -12179
- package/dist/test-utils/test-instance.mjs +11 -2
- package/dist/types/auth.d.mts +4 -0
- package/dist/types/index.d.mts +2 -2
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/is-api-error.d.mts +1 -5
- package/dist/utils/is-api-error.mjs +1 -7
- package/dist/utils/url.d.mts +2 -1
- package/dist/utils/url.mjs +25 -8
- package/dist/utils/validate-user-info.mjs +44 -0
- package/package.json +33 -58
- package/dist/oauth2/error-codes.d.mts +0 -20
- package/dist/oauth2/error-codes.mjs +0 -20
- package/dist/plugins/generic-oauth/client.d.mts +0 -32
- package/dist/plugins/generic-oauth/client.mjs +0 -19
- package/dist/plugins/generic-oauth/error-codes.d.mts +0 -10
- package/dist/plugins/mcp/authorize.mjs +0 -128
- package/dist/plugins/mcp/client/adapters.d.mts +0 -56
- package/dist/plugins/mcp/client/adapters.mjs +0 -117
- package/dist/plugins/mcp/client/index.d.mts +0 -44
- package/dist/plugins/mcp/client/index.mjs +0 -152
- package/dist/plugins/mcp/index.d.mts +0 -457
- package/dist/plugins/mcp/index.mjs +0 -730
- package/dist/plugins/oidc-provider/authorize.mjs +0 -198
- package/dist/plugins/oidc-provider/client.d.mts +0 -16
- package/dist/plugins/oidc-provider/client.mjs +0 -15
- package/dist/plugins/oidc-provider/error.mjs +0 -24
- package/dist/plugins/oidc-provider/index.d.mts +0 -705
- package/dist/plugins/oidc-provider/index.mjs +0 -1095
- package/dist/plugins/oidc-provider/schema.d.mts +0 -159
- package/dist/plugins/oidc-provider/schema.mjs +0 -129
- package/dist/plugins/oidc-provider/types.d.mts +0 -517
- package/dist/plugins/oidc-provider/utils/prompt.mjs +0 -16
- package/dist/plugins/oidc-provider/utils.mjs +0 -12
- package/dist/utils/get-request-ip.d.mts +0 -6
- package/dist/utils/get-request-ip.mjs +0 -20
package/README.md
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
2
|
<picture>
|
|
3
|
-
<source
|
|
4
|
-
<source
|
|
5
|
-
<img
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
[](https://npm.chart.dev/better-auth?primary=neutral&gray=neutral&theme=dark)
|
|
9
|
+
[](https://www.npmjs.com/package/better-auth)
|
|
10
|
+
[](https://github.com/better-auth/better-auth/stargazers)
|
|
11
11
|
|
|
12
|
-
<p
|
|
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
|
-
</
|
|
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
|
-
|
|
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 };
|
package/dist/api/index.d.mts
CHANGED
|
@@ -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,
|
|
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 };
|
package/dist/api/index.mjs
CHANGED
|
@@ -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 {
|
|
5
|
-
import {
|
|
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,
|
|
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 };
|