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

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 (74) hide show
  1. package/dist/api/index.d.mts +4 -0
  2. package/dist/api/routes/account.mjs +1 -1
  3. package/dist/api/routes/callback.d.mts +2 -0
  4. package/dist/api/routes/callback.mjs +23 -14
  5. package/dist/api/routes/email-verification.mjs +1 -1
  6. package/dist/api/routes/session.mjs +2 -2
  7. package/dist/api/routes/sign-in.mjs +1 -1
  8. package/dist/api/to-auth-endpoints.mjs +27 -3
  9. package/dist/auth/base.mjs +5 -24
  10. package/dist/client/path-to-object.d.mts +35 -1
  11. package/dist/client/plugins/index.d.mts +4 -3
  12. package/dist/client/plugins/index.mjs +2 -1
  13. package/dist/client/query.mjs +4 -4
  14. package/dist/context/create-context.mjs +2 -2
  15. package/dist/context/helpers.mjs +61 -3
  16. package/dist/cookies/index.mjs +3 -3
  17. package/dist/crypto/index.mjs +2 -2
  18. package/dist/db/index.mjs +1 -1
  19. package/dist/db/internal-adapter.mjs +1 -1
  20. package/dist/index.d.mts +2 -2
  21. package/dist/index.mjs +2 -2
  22. package/dist/oauth2/error-codes.d.mts +20 -0
  23. package/dist/oauth2/error-codes.mjs +20 -0
  24. package/dist/package.mjs +1 -1
  25. package/dist/plugins/admin/admin.mjs +1 -1
  26. package/dist/plugins/admin/routes.mjs +1 -1
  27. package/dist/plugins/anonymous/index.mjs +1 -1
  28. package/dist/plugins/device-authorization/routes.mjs +1 -1
  29. package/dist/plugins/email-otp/routes.mjs +1 -1
  30. package/dist/plugins/generic-oauth/client.d.mts +6 -6
  31. package/dist/plugins/generic-oauth/client.mjs +6 -0
  32. package/dist/plugins/generic-oauth/error-codes.d.mts +1 -6
  33. package/dist/plugins/generic-oauth/error-codes.mjs +2 -7
  34. package/dist/plugins/generic-oauth/index.d.mts +9 -156
  35. package/dist/plugins/generic-oauth/index.mjs +125 -74
  36. package/dist/plugins/generic-oauth/providers/auth0.d.mts +1 -1
  37. package/dist/plugins/generic-oauth/providers/gumroad.d.mts +1 -1
  38. package/dist/plugins/generic-oauth/providers/hubspot.d.mts +1 -1
  39. package/dist/plugins/generic-oauth/providers/keycloak.d.mts +1 -1
  40. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +1 -1
  41. package/dist/plugins/generic-oauth/providers/okta.d.mts +1 -1
  42. package/dist/plugins/generic-oauth/providers/patreon.d.mts +1 -1
  43. package/dist/plugins/generic-oauth/providers/slack.d.mts +1 -1
  44. package/dist/plugins/generic-oauth/types.d.mts +18 -25
  45. package/dist/plugins/index.d.mts +4 -4
  46. package/dist/plugins/index.mjs +2 -2
  47. package/dist/plugins/jwt/client.d.mts +1 -1
  48. package/dist/plugins/jwt/index.d.mts +3 -3
  49. package/dist/plugins/jwt/index.mjs +2 -2
  50. package/dist/plugins/jwt/sign.d.mts +15 -3
  51. package/dist/plugins/jwt/sign.mjs +31 -12
  52. package/dist/plugins/jwt/types.d.mts +13 -1
  53. package/dist/plugins/jwt/utils.mjs +1 -1
  54. package/dist/plugins/last-login-method/index.mjs +1 -1
  55. package/dist/plugins/mcp/index.mjs +20 -8
  56. package/dist/plugins/oauth-proxy/index.mjs +3 -3
  57. package/dist/plugins/oidc-provider/index.mjs +2 -2
  58. package/dist/plugins/organization/routes/crud-invites.mjs +1 -1
  59. package/dist/plugins/organization/routes/crud-org.mjs +1 -1
  60. package/dist/plugins/organization/routes/crud-team.mjs +1 -1
  61. package/dist/plugins/phone-number/routes.mjs +1 -1
  62. package/dist/plugins/two-factor/backup-codes/index.d.mts +2 -1
  63. package/dist/plugins/two-factor/backup-codes/index.mjs +12 -17
  64. package/dist/plugins/two-factor/client.d.mts +1 -1
  65. package/dist/plugins/two-factor/index.d.mts +2 -2
  66. package/dist/plugins/two-factor/index.mjs +16 -6
  67. package/dist/plugins/two-factor/types.d.mts +5 -0
  68. package/dist/test-utils/test-instance.d.mts +12 -0
  69. package/dist/test-utils/test-instance.mjs +7 -1
  70. package/dist/utils/index.d.mts +1 -1
  71. package/dist/utils/url.d.mts +22 -15
  72. package/dist/utils/url.mjs +54 -28
  73. package/package.json +9 -9
  74. package/dist/plugins/generic-oauth/routes.mjs +0 -411
@@ -216,6 +216,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
216
216
  error_description: zod.ZodOptional<zod.ZodString>;
217
217
  state: zod.ZodOptional<zod.ZodString>;
218
218
  user: zod.ZodOptional<zod.ZodString>;
219
+ iss: zod.ZodOptional<zod.ZodString>;
219
220
  }, zod_v4_core0.$strip>>;
220
221
  query: zod.ZodOptional<zod.ZodObject<{
221
222
  code: zod.ZodOptional<zod.ZodString>;
@@ -224,6 +225,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
224
225
  error_description: zod.ZodOptional<zod.ZodString>;
225
226
  state: zod.ZodOptional<zod.ZodString>;
226
227
  user: zod.ZodOptional<zod.ZodString>;
228
+ iss: zod.ZodOptional<zod.ZodString>;
227
229
  }, zod_v4_core0.$strip>>;
228
230
  metadata: {
229
231
  allowedMediaTypes: string[];
@@ -2205,6 +2207,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2205
2207
  error_description: zod.ZodOptional<zod.ZodString>;
2206
2208
  state: zod.ZodOptional<zod.ZodString>;
2207
2209
  user: zod.ZodOptional<zod.ZodString>;
2210
+ iss: zod.ZodOptional<zod.ZodString>;
2208
2211
  }, zod_v4_core0.$strip>>;
2209
2212
  query: zod.ZodOptional<zod.ZodObject<{
2210
2213
  code: zod.ZodOptional<zod.ZodString>;
@@ -2213,6 +2216,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2213
2216
  error_description: zod.ZodOptional<zod.ZodString>;
2214
2217
  state: zod.ZodOptional<zod.ZodString>;
2215
2218
  user: zod.ZodOptional<zod.ZodString>;
2219
+ iss: zod.ZodOptional<zod.ZodString>;
2216
2220
  }, zod_v4_core0.$strip>>;
2217
2221
  metadata: {
2218
2222
  allowedMediaTypes: string[];
@@ -1,6 +1,6 @@
1
1
  import { parseAccountOutput } from "../../db/schema.mjs";
2
- import { getAwaitableValue } from "../../context/helpers.mjs";
3
2
  import { getAccountCookie, setAccountCookie } from "../../cookies/session-store.mjs";
3
+ import { getAwaitableValue } from "../../context/helpers.mjs";
4
4
  import { generateState } from "../../oauth2/state.mjs";
5
5
  import { decryptOAuthToken, setTokenUtil } from "../../oauth2/utils.mjs";
6
6
  import { freshSessionMiddleware, getSessionFromCtx, sessionMiddleware } from "./session.mjs";
@@ -12,6 +12,7 @@ declare const callbackOAuth: better_call0.StrictEndpoint<"/callback/:id", {
12
12
  error_description: z.ZodOptional<z.ZodString>;
13
13
  state: z.ZodOptional<z.ZodString>;
14
14
  user: z.ZodOptional<z.ZodString>;
15
+ iss: z.ZodOptional<z.ZodString>;
15
16
  }, z.core.$strip>>;
16
17
  query: z.ZodOptional<z.ZodObject<{
17
18
  code: z.ZodOptional<z.ZodString>;
@@ -20,6 +21,7 @@ declare const callbackOAuth: better_call0.StrictEndpoint<"/callback/:id", {
20
21
  error_description: z.ZodOptional<z.ZodString>;
21
22
  state: z.ZodOptional<z.ZodString>;
22
23
  user: z.ZodOptional<z.ZodString>;
24
+ iss: z.ZodOptional<z.ZodString>;
23
25
  }, z.core.$strip>>;
24
26
  metadata: {
25
27
  allowedMediaTypes: string[];
@@ -1,7 +1,8 @@
1
- import { getAwaitableValue } from "../../context/helpers.mjs";
2
1
  import { setSessionCookie } from "../../cookies/index.mjs";
2
+ import { getAwaitableValue } from "../../context/helpers.mjs";
3
3
  import { parseState } from "../../oauth2/state.mjs";
4
4
  import { setTokenUtil } from "../../oauth2/utils.mjs";
5
+ import { OAUTH_CALLBACK_ERROR_CODES } from "../../oauth2/error-codes.mjs";
5
6
  import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
6
7
  import { HIDE_METADATA } from "../../utils/hide-metadata.mjs";
7
8
  import { safeJSONParse } from "@better-auth/core/utils/json";
@@ -14,7 +15,8 @@ const schema = z.object({
14
15
  device_id: z.string().optional(),
15
16
  error_description: z.string().optional(),
16
17
  state: z.string().optional(),
17
- user: z.string().optional()
18
+ user: z.string().optional(),
19
+ iss: z.string().optional()
18
20
  });
19
21
  const callbackOAuth = createAuthEndpoint("/callback/:id", {
20
22
  method: ["GET", "POST"],
@@ -48,7 +50,7 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
48
50
  c.context.logger.error("INVALID_CALLBACK_REQUEST", e);
49
51
  throw c.redirect(`${defaultErrorURL}?error=invalid_callback_request`);
50
52
  }
51
- const { code, error, state, error_description, device_id, user: userData } = queryOrBody;
53
+ const { code, error, state, error_description, device_id, user: userData, iss } = queryOrBody;
52
54
  if (!state) {
53
55
  c.context.logger.error("State not found", error);
54
56
  const url = `${defaultErrorURL}${defaultErrorURL.includes("?") ? "&" : "?"}state=state_not_found`;
@@ -65,12 +67,19 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
65
67
  if (error) redirectOnError(error, error_description);
66
68
  if (!code) {
67
69
  c.context.logger.error("Code not found");
68
- throw redirectOnError("no_code");
70
+ throw redirectOnError(OAUTH_CALLBACK_ERROR_CODES.NO_CODE);
69
71
  }
70
72
  const provider = await getAwaitableValue(c.context.socialProviders, { value: c.params.id });
71
73
  if (!provider) {
72
74
  c.context.logger.error("Oauth provider with id", c.params.id, "not found");
73
- throw redirectOnError("oauth_provider_not_found");
75
+ throw redirectOnError(OAUTH_CALLBACK_ERROR_CODES.PROVIDER_NOT_FOUND);
76
+ }
77
+ if (iss && provider.issuer && iss !== provider.issuer) {
78
+ c.context.logger.error("OAuth issuer mismatch", {
79
+ expected: provider.issuer,
80
+ received: iss
81
+ });
82
+ throw redirectOnError(OAUTH_CALLBACK_ERROR_CODES.ISSUER_MISMATCH);
74
83
  }
75
84
  let tokens;
76
85
  try {
@@ -82,9 +91,9 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
82
91
  });
83
92
  } catch (e) {
84
93
  c.context.logger.error("", e);
85
- throw redirectOnError("invalid_code");
94
+ throw redirectOnError(OAUTH_CALLBACK_ERROR_CODES.INVALID_CODE);
86
95
  }
87
- if (!tokens) throw redirectOnError("invalid_code");
96
+ if (!tokens) throw redirectOnError(OAUTH_CALLBACK_ERROR_CODES.INVALID_CODE);
88
97
  const parsedUserData = userData ? safeJSONParse(userData) : null;
89
98
  const userInfo = await provider.getUserInfo({
90
99
  ...tokens,
@@ -92,21 +101,21 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
92
101
  }).then((res) => res?.user);
93
102
  if (!userInfo) {
94
103
  c.context.logger.error("Unable to get user info");
95
- return redirectOnError("unable_to_get_user_info");
104
+ return redirectOnError(OAUTH_CALLBACK_ERROR_CODES.UNABLE_TO_GET_USER_INFO);
96
105
  }
97
106
  if (!callbackURL) {
98
107
  c.context.logger.error("No callback URL found");
99
- throw redirectOnError("no_callback_url");
108
+ throw redirectOnError(OAUTH_CALLBACK_ERROR_CODES.NO_CALLBACK_URL);
100
109
  }
101
110
  if (link) {
102
111
  if (!c.context.trustedProviders.includes(provider.id) && !userInfo.emailVerified || c.context.options.account?.accountLinking?.enabled === false) {
103
112
  c.context.logger.error("Unable to link account - untrusted provider");
104
- return redirectOnError("unable_to_link_account");
113
+ return redirectOnError(OAUTH_CALLBACK_ERROR_CODES.UNABLE_TO_LINK_ACCOUNT);
105
114
  }
106
- if (userInfo.email?.toLowerCase() !== link.email.toLowerCase() && c.context.options.account?.accountLinking?.allowDifferentEmails !== true) return redirectOnError("email_doesn't_match");
115
+ if (userInfo.email?.toLowerCase() !== link.email.toLowerCase() && c.context.options.account?.accountLinking?.allowDifferentEmails !== true) return redirectOnError(OAUTH_CALLBACK_ERROR_CODES.EMAIL_DOES_NOT_MATCH);
107
116
  const existingAccount = await c.context.internalAdapter.findAccountByProviderId(String(userInfo.id), provider.id);
108
117
  if (existingAccount) {
109
- if (existingAccount.userId.toString() !== link.userId.toString()) return redirectOnError("account_already_linked_to_different_user");
118
+ if (existingAccount.userId.toString() !== link.userId.toString()) return redirectOnError(OAUTH_CALLBACK_ERROR_CODES.ACCOUNT_ALREADY_LINKED_TO_DIFFERENT_USER);
110
119
  const updateData = Object.fromEntries(Object.entries({
111
120
  accessToken: await setTokenUtil(tokens.accessToken, c.context),
112
121
  refreshToken: await setTokenUtil(tokens.refreshToken, c.context),
@@ -124,7 +133,7 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
124
133
  accessToken: await setTokenUtil(tokens.accessToken, c.context),
125
134
  refreshToken: await setTokenUtil(tokens.refreshToken, c.context),
126
135
  scope: tokens.scopes?.join(",")
127
- })) return redirectOnError("unable_to_link_account");
136
+ })) return redirectOnError(OAUTH_CALLBACK_ERROR_CODES.UNABLE_TO_LINK_ACCOUNT);
128
137
  let toRedirectTo;
129
138
  try {
130
139
  toRedirectTo = callbackURL.toString();
@@ -135,7 +144,7 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
135
144
  }
136
145
  if (!userInfo.email) {
137
146
  c.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings.");
138
- return redirectOnError("email_not_found");
147
+ return redirectOnError(OAUTH_CALLBACK_ERROR_CODES.EMAIL_NOT_FOUND);
139
148
  }
140
149
  const accountData = {
141
150
  providerId: provider.id,
@@ -1,6 +1,6 @@
1
1
  import { originCheck } from "../middlewares/origin-check.mjs";
2
- import { parseUserOutput } from "../../db/schema.mjs";
3
2
  import { signJWT } from "../../crypto/jwt.mjs";
3
+ import { parseUserOutput } from "../../db/schema.mjs";
4
4
  import { setSessionCookie } from "../../cookies/index.mjs";
5
5
  import { getSessionFromCtx } from "./session.mjs";
6
6
  import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
@@ -1,7 +1,7 @@
1
1
  import { isAPIError } from "../../utils/is-api-error.mjs";
2
- import { getDate } from "../../utils/date.mjs";
3
- import { parseSessionOutput, parseUserOutput } from "../../db/schema.mjs";
4
2
  import { symmetricDecodeJWT, verifyJWT } from "../../crypto/jwt.mjs";
3
+ import { parseSessionOutput, parseUserOutput } from "../../db/schema.mjs";
4
+ import { getDate } from "../../utils/date.mjs";
5
5
  import { getChunkedCookie, getSessionQuerySchema } from "../../cookies/session-store.mjs";
6
6
  import { deleteSessionCookie, expireCookie, setCookieCache, setSessionCookie } from "../../cookies/index.mjs";
7
7
  import { getShouldSkipSessionRefresh } from "../state/should-session-refresh.mjs";
@@ -1,7 +1,7 @@
1
1
  import { formCsrfMiddleware } from "../middlewares/origin-check.mjs";
2
2
  import { parseUserOutput } from "../../db/schema.mjs";
3
- import { getAwaitableValue } from "../../context/helpers.mjs";
4
3
  import { setSessionCookie } from "../../cookies/index.mjs";
4
+ import { getAwaitableValue } from "../../context/helpers.mjs";
5
5
  import { generateState } from "../../oauth2/state.mjs";
6
6
  import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
7
7
  import { createEmailVerificationToken } from "./email-verification.mjs";
@@ -1,7 +1,9 @@
1
1
  import { isAPIError } from "../utils/is-api-error.mjs";
2
+ import { isDynamicBaseURLConfig, isRequestLike } from "../utils/url.mjs";
3
+ import { pickSource, resolveDynamicTrustedProxyHeaders, resolveRequestContext } from "../context/helpers.mjs";
2
4
  import { hasRequestState, runWithEndpointContext, runWithRequestState } from "@better-auth/core/context";
3
5
  import { shouldPublishLog } from "@better-auth/core/env";
4
- import { APIError } from "@better-auth/core/error";
6
+ import { APIError, BetterAuthError } from "@better-auth/core/error";
5
7
  import { createDefu } from "defu";
6
8
  import { ATTR_CONTEXT, ATTR_HOOK_TYPE, ATTR_HTTP_ROUTE, ATTR_OPERATION_ID, withSpan } from "@better-auth/core/instrumentation";
7
9
  import { kAPIErrorHeaderSymbol, toResponse } from "better-call";
@@ -18,6 +20,27 @@ function getOperationId(endpoint, key) {
18
20
  const opts = endpoint.options;
19
21
  return opts.operationId ?? opts.metadata?.openapi?.operationId ?? key;
20
22
  }
23
+ /**
24
+ * Resolves the per-call `AuthContext` for endpoints with a dynamic `baseURL`.
25
+ *
26
+ * - `rawCtx.baseURL` already set: HTTP handler rehydrated upstream; return as-is.
27
+ * - Direct `auth.api` call with a source or a configured `fallback`: resolve here.
28
+ * - Neither: throw `APIError` with a helpful message. Leaving `baseURL = ""`
29
+ * would let plugins build `new URL("")` and crash cryptically downstream.
30
+ */
31
+ async function resolveDynamicContext(rawCtx, input) {
32
+ if (rawCtx.baseURL) return rawCtx;
33
+ const source = pickSource(input);
34
+ const config = rawCtx.options.baseURL;
35
+ const hasFallback = isDynamicBaseURLConfig(config) && Boolean(config.fallback);
36
+ if (source === void 0 && !hasFallback) throw new APIError("INTERNAL_SERVER_ERROR", { message: "Dynamic baseURL could not be resolved for this direct auth.api call. Pass `headers: request.headers` (or `request`) to the call, or add `fallback` to your baseURL config." });
37
+ try {
38
+ return await resolveRequestContext(rawCtx, source, resolveDynamicTrustedProxyHeaders(rawCtx.options));
39
+ } catch (err) {
40
+ if (err instanceof BetterAuthError) throw new APIError("INTERNAL_SERVER_ERROR", { message: err.message });
41
+ throw err;
42
+ }
43
+ }
21
44
  function toAuthEndpoints(endpoints, ctx) {
22
45
  const api = {};
23
46
  for (const [key, endpoint] of Object.entries(endpoints)) {
@@ -26,9 +49,10 @@ function toAuthEndpoints(endpoints, ctx) {
26
49
  const endpointMethod = endpoint?.options?.method;
27
50
  const defaultMethod = Array.isArray(endpointMethod) ? endpointMethod[0] : endpointMethod;
28
51
  const run = async () => {
29
- const authContext = await ctx;
52
+ const rawContext = await ctx;
30
53
  const methodName = context?.method ?? context?.request?.method ?? defaultMethod ?? "?";
31
54
  const route = endpoint.path ?? "/:virtual";
55
+ const authContext = isDynamicBaseURLConfig(rawContext.options.baseURL) ? await resolveDynamicContext(rawContext, context) : rawContext;
32
56
  let internalContext = {
33
57
  ...context,
34
58
  context: {
@@ -40,7 +64,7 @@ function toAuthEndpoints(endpoints, ctx) {
40
64
  path: endpoint.path,
41
65
  headers: context?.headers ? new Headers(context?.headers) : void 0
42
66
  };
43
- const hasRequest = context?.request instanceof Request;
67
+ const hasRequest = isRequestLike(context?.request);
44
68
  const shouldReturnResponse = context?.asResponse ?? hasRequest;
45
69
  return withSpan(`${methodName} ${route}`, {
46
70
  [ATTR_HTTP_ROUTE]: route,
@@ -1,6 +1,5 @@
1
- import { getBaseURL, getOrigin, isDynamicBaseURLConfig, resolveBaseURL } from "../utils/url.mjs";
2
- import { getTrustedOrigins, getTrustedProviders } from "../context/helpers.mjs";
3
- import { createCookieGetter, getCookies } from "../cookies/index.mjs";
1
+ import { getBaseURL, getOrigin, isDynamicBaseURLConfig } from "../utils/url.mjs";
2
+ import { getTrustedOrigins, getTrustedProviders, resolveDynamicTrustedProxyHeaders, resolveRequestContext } from "../context/helpers.mjs";
4
3
  import { getEndpoints, router } from "../api/index.mjs";
5
4
  import { runWithAdapter } from "@better-auth/core/context";
6
5
  import { BASE_ERROR_CODES, BetterAuthError } from "@better-auth/core/error";
@@ -13,26 +12,8 @@ const createBetterAuth = (options, initFn) => {
13
12
  const ctx = await authContext;
14
13
  const basePath = ctx.options.basePath || "/api/auth";
15
14
  let handlerCtx;
16
- if (isDynamicBaseURLConfig(options.baseURL)) {
17
- handlerCtx = Object.create(Object.getPrototypeOf(ctx), Object.getOwnPropertyDescriptors(ctx));
18
- const baseURL = resolveBaseURL(options.baseURL, basePath, request);
19
- if (baseURL) {
20
- handlerCtx.baseURL = baseURL;
21
- handlerCtx.options = {
22
- ...ctx.options,
23
- baseURL: getOrigin(baseURL) || void 0
24
- };
25
- } else throw new BetterAuthError("Could not resolve base URL from request. Check your allowedHosts config.");
26
- const trustedOriginOptions = {
27
- ...handlerCtx.options,
28
- baseURL: options.baseURL
29
- };
30
- handlerCtx.trustedOrigins = await getTrustedOrigins(trustedOriginOptions, request);
31
- if (options.advanced?.crossSubDomainCookies?.enabled) {
32
- handlerCtx.authCookies = getCookies(handlerCtx.options);
33
- handlerCtx.createAuthCookie = createCookieGetter(handlerCtx.options);
34
- }
35
- } else {
15
+ if (isDynamicBaseURLConfig(options.baseURL)) handlerCtx = await resolveRequestContext(ctx, request, resolveDynamicTrustedProxyHeaders(ctx.options));
16
+ else {
36
17
  handlerCtx = ctx;
37
18
  if (!ctx.options.baseURL) {
38
19
  const baseURL = getBaseURL(void 0, basePath, request, void 0, ctx.options.advanced?.trustedProxyHeaders);
@@ -42,8 +23,8 @@ const createBetterAuth = (options, initFn) => {
42
23
  } else throw new BetterAuthError("Could not get base URL from request. Please provide a valid base URL.");
43
24
  }
44
25
  handlerCtx.trustedOrigins = await getTrustedOrigins(ctx.options, request);
26
+ handlerCtx.trustedProviders = await getTrustedProviders(ctx.options, request);
45
27
  }
46
- handlerCtx.trustedProviders = await getTrustedProviders(handlerCtx.options, request);
47
28
  const { handler } = router(handlerCtx, options);
48
29
  return runWithAdapter(handlerCtx.adapter, () => handler(request));
49
30
  },
@@ -1,10 +1,41 @@
1
1
  import { HasRequiredKeys, IsAny, Prettify as Prettify$1, UnionToIntersection } from "../types/helper.mjs";
2
2
  import { InferAdditionalFromClient, InferSessionFromClient, InferUserFromClient } from "./types.mjs";
3
3
  import { BetterAuthClientOptions, ClientFetchOption } from "@better-auth/core";
4
+ import { SocialProviderList } from "@better-auth/core/social-providers";
4
5
  import { Endpoint, InputContext, StandardSchemaV1 } from "better-call";
5
6
  import { BetterFetchResponse } from "@better-fetch/fetch";
6
7
 
7
8
  //#region src/client/path-to-object.d.ts
9
+ /**
10
+ * Extract generic OAuth provider IDs from the client options.
11
+ * Supports both `$InferAuth` (server type bridge) and client plugins
12
+ * with `$InferServerPlugin`.
13
+ */
14
+ type InferGenericOAuthProviderIds<O extends BetterAuthClientOptions> = (O extends {
15
+ $InferAuth: {
16
+ options: {
17
+ plugins: Array<infer P>;
18
+ };
19
+ };
20
+ } ? P extends {
21
+ id: "generic-oauth";
22
+ options: {
23
+ config: Array<{
24
+ providerId: infer ID;
25
+ }>;
26
+ };
27
+ } ? ID & string : never : never) | (O extends {
28
+ plugins: Array<infer P>;
29
+ } ? P extends {
30
+ $InferServerPlugin: {
31
+ id: "generic-oauth";
32
+ options: {
33
+ config: Array<{
34
+ providerId: infer ID;
35
+ }>;
36
+ };
37
+ };
38
+ } ? ID & string : never : never);
8
39
  type KeepNullishFromOriginal<Original, Replaced> = Replaced | (undefined extends Original ? undefined : never) | (null extends Original ? null : never);
9
40
  type ReplaceTopLevelField<Data, Field extends "user" | "session", Replaced> = Data extends object ? Field extends keyof Data ? Omit<Data, Field> & { [K in Field]: KeepNullishFromOriginal<Data[K], Replaced> } : Data : Data;
10
41
  type ReplaceAuthUserAndSession<Data, ClientOpts extends BetterAuthClientOptions> = ReplaceTopLevelField<ReplaceTopLevelField<Data, "user", InferUserFromClient<ClientOpts>>, "session", InferSessionFromClient<ClientOpts>>;
@@ -51,7 +82,10 @@ type InferRoute<API, COpts extends BetterAuthClientOptions> = API extends Record
51
82
  scope: "http";
52
83
  } | {
53
84
  scope: "server";
54
- } ? {} : PathToObject<T["path"], T extends ((ctx: infer C) => infer R) ? C extends InputContext<any, any> ? <FetchOptions extends ClientFetchOption<Partial<C["body"]> & Record<string, any>, Partial<C["query"]> & Record<string, any>, C["params"]>>(...data: HasRequiredKeys<InferCtx<C, FetchOptions>> extends true ? [Prettify$1<T["path"] extends `/sign-up/email` ? InferSignUpEmailCtx<COpts, FetchOptions> : InferCtx<C, FetchOptions>>, FetchOptions?] : [Prettify$1<T["path"] extends `/update-user` ? InferUserUpdateCtx<COpts, FetchOptions> : InferCtx<C, FetchOptions>>?, FetchOptions?]) => Promise<BetterFetchResponse<T["options"]["metadata"] extends {
85
+ } ? {} : PathToObject<T["path"], T extends ((ctx: infer C) => infer R) ? C extends InputContext<any, any> ? <FetchOptions extends ClientFetchOption<Partial<C["body"]> & Record<string, any>, Partial<C["query"]> & Record<string, any>, C["params"]>>(...data: HasRequiredKeys<InferCtx<C, FetchOptions>> extends true ? [Prettify$1<T["path"] extends `/sign-up/email` ? InferSignUpEmailCtx<COpts, FetchOptions> : T["path"] extends `/sign-in/social` ? Omit<InferCtx<C, FetchOptions>, "provider"> & {
86
+ provider: SocialProviderList[number] | InferGenericOAuthProviderIds<COpts> | (string & {});
87
+ fetchOptions?: FetchOptions | undefined;
88
+ } : InferCtx<C, FetchOptions>>, FetchOptions?] : [Prettify$1<T["path"] extends `/update-user` ? InferUserUpdateCtx<COpts, FetchOptions> : InferCtx<C, FetchOptions>>?, FetchOptions?]) => Promise<BetterFetchResponse<T["options"]["metadata"] extends {
55
89
  CUSTOM_SESSION: boolean;
56
90
  } ? MergeCustomSessionWithInferred<NonNullable<Awaited<R>>, COpts> : T["path"] extends "/get-session" ? {
57
91
  user: InferUserFromClient<COpts>;
@@ -14,13 +14,13 @@ import { OktaOptions, okta } from "../../plugins/generic-oauth/providers/okta.mj
14
14
  import { PatreonOptions, patreon } from "../../plugins/generic-oauth/providers/patreon.mjs";
15
15
  import { SlackOptions, slack } from "../../plugins/generic-oauth/providers/slack.mjs";
16
16
  import { BaseOAuthProviderOptions } from "../../plugins/generic-oauth/index.mjs";
17
- import { JWKOptions, JWSAlgorithms, Jwk, JwtOptions } from "../../plugins/jwt/types.mjs";
17
+ import { JWKOptions, JWSAlgorithms, Jwk, JwtOptions, ResolvedSigningKey } from "../../plugins/jwt/types.mjs";
18
18
  import { AuthorizationQuery, Client, CodeVerificationValue, OAuthAccessToken, OIDCMetadata, OIDCOptions, TokenBody } from "../../plugins/oidc-provider/types.mjs";
19
19
  import { MULTI_SESSION_ERROR_CODES } from "../../plugins/multi-session/error-codes.mjs";
20
20
  import { MultiSessionConfig } from "../../plugins/multi-session/index.mjs";
21
21
  import { OneTimeTokenOptions } from "../../plugins/one-time-token/index.mjs";
22
22
  import { PhoneNumberOptions, UserWithPhoneNumber } from "../../plugins/phone-number/types.mjs";
23
- import { BackupCodeOptions, backupCode2fa, generateBackupCodes, getBackupCodes, verifyBackupCode } from "../../plugins/two-factor/backup-codes/index.mjs";
23
+ import { BackupCodeOptions, backupCode2fa, encodeBackupCodes, generateBackupCodes, getBackupCodes, verifyBackupCode } from "../../plugins/two-factor/backup-codes/index.mjs";
24
24
  import { OTPOptions, otp2fa } from "../../plugins/two-factor/otp/index.mjs";
25
25
  import { TOTPOptions, totp2fa } from "../../plugins/two-factor/totp/index.mjs";
26
26
  import { TwoFactorOptions, TwoFactorProvider, TwoFactorTable, UserWithTwoFactor } from "../../plugins/two-factor/types.mjs";
@@ -37,6 +37,7 @@ import { customSessionClient } from "../../plugins/custom-session/client.mjs";
37
37
  import { deviceAuthorizationClient } from "../../plugins/device-authorization/client.mjs";
38
38
  import { EMAIL_OTP_ERROR_CODES } from "../../plugins/email-otp/error-codes.mjs";
39
39
  import { emailOTPClient } from "../../plugins/email-otp/client.mjs";
40
+ import { OAUTH_CALLBACK_ERROR_CODES } from "../../oauth2/error-codes.mjs";
40
41
  import { GENERIC_OAUTH_ERROR_CODES } from "../../plugins/generic-oauth/error-codes.mjs";
41
42
  import { genericOAuthClient } from "../../plugins/generic-oauth/client.mjs";
42
43
  import { jwtClient } from "../../plugins/jwt/client.mjs";
@@ -52,4 +53,4 @@ import { phoneNumberClient } from "../../plugins/phone-number/client.mjs";
52
53
  import { siweClient } from "../../plugins/siwe/client.mjs";
53
54
  import { usernameClient } from "../../plugins/username/client.mjs";
54
55
  import { InferServerPlugin } from "./infer-plugin.mjs";
55
- export { ADMIN_ERROR_CODES, ANONYMOUS_ERROR_CODES, AdminOptions, AnonymousOptions, AnonymousSession, Auth0Options, AuthorizationQuery, BackupCodeOptions, BaseOAuthProviderOptions, Client, CodeVerificationValue, EMAIL_OTP_ERROR_CODES, ExtractPluginField, GENERIC_OAUTH_ERROR_CODES, GenericOAuthConfig, GenericOAuthOptions, GoogleOneTapActionOptions, GoogleOneTapOptions, GsiButtonConfiguration, GumroadOptions, HasRequiredKeys, HubSpotOptions, InferAdminRolesFromOption, InferInvitation, InferMember, InferOrganization, InferOrganizationRolesFromOption, InferOrganizationZodRolesFromOption, InferPluginFieldFromTuple, InferServerPlugin, InferTeam, Invitation, InvitationInput, InvitationStatus, IsAny, JWKOptions, JWSAlgorithms, Jwk, JwtOptions, KeycloakOptions, LastLoginMethodClientConfig, LineOptions, MULTI_SESSION_ERROR_CODES, Member, MemberInput, MicrosoftEntraIdOptions, MultiSessionConfig, OAuthAccessToken, OIDCMetadata, OIDCOptions, ORGANIZATION_ERROR_CODES, OTPOptions, OidcClientPlugin, OktaOptions, OneTimeTokenOptions, Organization, OrganizationInput, OrganizationRole, OrganizationSchema, OverrideMerge, PHONE_NUMBER_ERROR_CODES, PatreonOptions, PhoneNumberOptions, Prettify, PrettifyDeep, RequiredKeysOf, SessionWithImpersonatedBy, SlackOptions, StripEmptyObjects, TOTPOptions, TWO_FACTOR_ERROR_CODES, Team, TeamInput, TeamMember, TeamMemberInput, TokenBody, TwoFactorOptions, TwoFactorProvider, TwoFactorTable, USERNAME_ERROR_CODES, UnionToIntersection, UserWithAnonymous, UserWithPhoneNumber, UserWithRole, UserWithTwoFactor, adminClient, anonymousClient, auth0, backupCode2fa, clientSideHasPermission, customSessionClient, defaultRolesSchema, deviceAuthorizationClient, emailOTPClient, generateBackupCodes, genericOAuthClient, getBackupCodes, gumroad, hubspot, inferAdditionalFields, inferOrgAdditionalFields, invitationSchema, invitationStatus, jwtClient, keycloak, lastLoginMethodClient, line, magicLinkClient, memberSchema, microsoftEntraId, multiSessionClient, oidcClient, okta, oneTapClient, oneTimeTokenClient, organizationClient, organizationRoleSchema, organizationSchema, otp2fa, patreon, phoneNumberClient, roleSchema, schema, siweClient, slack, teamMemberSchema, teamSchema, totp2fa, twoFactorClient, usernameClient, verifyBackupCode };
56
+ export { ADMIN_ERROR_CODES, ANONYMOUS_ERROR_CODES, AdminOptions, AnonymousOptions, AnonymousSession, Auth0Options, AuthorizationQuery, BackupCodeOptions, BaseOAuthProviderOptions, Client, CodeVerificationValue, EMAIL_OTP_ERROR_CODES, ExtractPluginField, GENERIC_OAUTH_ERROR_CODES, GenericOAuthConfig, GenericOAuthOptions, GoogleOneTapActionOptions, GoogleOneTapOptions, GsiButtonConfiguration, GumroadOptions, HasRequiredKeys, HubSpotOptions, InferAdminRolesFromOption, InferInvitation, InferMember, InferOrganization, InferOrganizationRolesFromOption, InferOrganizationZodRolesFromOption, InferPluginFieldFromTuple, InferServerPlugin, InferTeam, Invitation, InvitationInput, InvitationStatus, IsAny, JWKOptions, JWSAlgorithms, Jwk, JwtOptions, KeycloakOptions, LastLoginMethodClientConfig, LineOptions, MULTI_SESSION_ERROR_CODES, Member, MemberInput, MicrosoftEntraIdOptions, MultiSessionConfig, OAUTH_CALLBACK_ERROR_CODES, OAuthAccessToken, OIDCMetadata, OIDCOptions, ORGANIZATION_ERROR_CODES, OTPOptions, OidcClientPlugin, OktaOptions, OneTimeTokenOptions, Organization, OrganizationInput, OrganizationRole, OrganizationSchema, OverrideMerge, PHONE_NUMBER_ERROR_CODES, PatreonOptions, PhoneNumberOptions, Prettify, PrettifyDeep, RequiredKeysOf, ResolvedSigningKey, SessionWithImpersonatedBy, SlackOptions, StripEmptyObjects, TOTPOptions, TWO_FACTOR_ERROR_CODES, Team, TeamInput, TeamMember, TeamMemberInput, TokenBody, TwoFactorOptions, TwoFactorProvider, TwoFactorTable, USERNAME_ERROR_CODES, UnionToIntersection, UserWithAnonymous, UserWithPhoneNumber, UserWithRole, UserWithTwoFactor, adminClient, anonymousClient, auth0, backupCode2fa, clientSideHasPermission, customSessionClient, defaultRolesSchema, deviceAuthorizationClient, emailOTPClient, encodeBackupCodes, generateBackupCodes, genericOAuthClient, getBackupCodes, gumroad, hubspot, inferAdditionalFields, inferOrgAdditionalFields, invitationSchema, invitationStatus, jwtClient, keycloak, lastLoginMethodClient, line, magicLinkClient, memberSchema, microsoftEntraId, multiSessionClient, oidcClient, okta, oneTapClient, oneTimeTokenClient, organizationClient, organizationRoleSchema, organizationSchema, otp2fa, patreon, phoneNumberClient, roleSchema, schema, siweClient, slack, teamMemberSchema, teamSchema, totp2fa, twoFactorClient, usernameClient, verifyBackupCode };
@@ -1,3 +1,4 @@
1
+ import { OAUTH_CALLBACK_ERROR_CODES } from "../../oauth2/error-codes.mjs";
1
2
  import { inferAdditionalFields } from "../../plugins/additional-fields/client.mjs";
2
3
  import { ADMIN_ERROR_CODES } from "../../plugins/admin/error-codes.mjs";
3
4
  import { adminClient } from "../../plugins/admin/client.mjs";
@@ -27,4 +28,4 @@ import { twoFactorClient } from "../../plugins/two-factor/client.mjs";
27
28
  import { USERNAME_ERROR_CODES } from "../../plugins/username/error-codes.mjs";
28
29
  import { usernameClient } from "../../plugins/username/client.mjs";
29
30
  import { InferServerPlugin } from "./infer-plugin.mjs";
30
- export { ADMIN_ERROR_CODES, ANONYMOUS_ERROR_CODES, EMAIL_OTP_ERROR_CODES, GENERIC_OAUTH_ERROR_CODES, InferServerPlugin, MULTI_SESSION_ERROR_CODES, ORGANIZATION_ERROR_CODES, PHONE_NUMBER_ERROR_CODES, TWO_FACTOR_ERROR_CODES, USERNAME_ERROR_CODES, adminClient, anonymousClient, clientSideHasPermission, customSessionClient, deviceAuthorizationClient, emailOTPClient, genericOAuthClient, inferAdditionalFields, inferOrgAdditionalFields, jwtClient, lastLoginMethodClient, magicLinkClient, multiSessionClient, oidcClient, oneTapClient, oneTimeTokenClient, organizationClient, phoneNumberClient, siweClient, twoFactorClient, usernameClient };
31
+ export { ADMIN_ERROR_CODES, ANONYMOUS_ERROR_CODES, EMAIL_OTP_ERROR_CODES, GENERIC_OAUTH_ERROR_CODES, InferServerPlugin, MULTI_SESSION_ERROR_CODES, OAUTH_CALLBACK_ERROR_CODES, ORGANIZATION_ERROR_CODES, PHONE_NUMBER_ERROR_CODES, TWO_FACTOR_ERROR_CODES, USERNAME_ERROR_CODES, adminClient, anonymousClient, clientSideHasPermission, customSessionClient, deviceAuthorizationClient, emailOTPClient, genericOAuthClient, inferAdditionalFields, inferOrgAdditionalFields, jwtClient, lastLoginMethodClient, magicLinkClient, multiSessionClient, oidcClient, oneTapClient, oneTimeTokenClient, organizationClient, phoneNumberClient, siweClient, twoFactorClient, usernameClient };
@@ -72,15 +72,15 @@ const useAuthQuery = (initializedAtom, path, $fetch, options) => {
72
72
  });
73
73
  };
74
74
  initializedAtom = Array.isArray(initializedAtom) ? initializedAtom : [initializedAtom];
75
- let isMounted = false;
75
+ let isInitialized = false;
76
76
  for (const initAtom of initializedAtom) initAtom.subscribe(async () => {
77
77
  if (isServer()) return;
78
- if (isMounted) await fn();
78
+ if (isInitialized) await fn();
79
79
  else onMount(value, () => {
80
80
  const timeoutId = setTimeout(async () => {
81
- if (!isMounted) {
81
+ if (!isInitialized) {
82
+ isInitialized = true;
82
83
  await fn();
83
- isMounted = true;
84
84
  }
85
85
  }, 0);
86
86
  return () => {
@@ -1,10 +1,10 @@
1
1
  import { getBaseURL, isDynamicBaseURLConfig } from "../utils/url.mjs";
2
2
  import { matchesOriginPattern } from "../auth/trusted-origins.mjs";
3
- import { createInternalAdapter } from "../db/internal-adapter.mjs";
4
3
  import { isPromise } from "../utils/is-promise.mjs";
5
- import { getInternalPlugins, getTrustedOrigins, getTrustedProviders, runPluginInit } from "./helpers.mjs";
6
4
  import { hashPassword, verifyPassword } from "../crypto/password.mjs";
7
5
  import { createCookieGetter, getCookies } from "../cookies/index.mjs";
6
+ import { createInternalAdapter } from "../db/internal-adapter.mjs";
7
+ import { getInternalPlugins, getTrustedOrigins, getTrustedProviders, runPluginInit } from "./helpers.mjs";
8
8
  import { checkPassword } from "../utils/password.mjs";
9
9
  import { checkEndpointConflicts } from "../api/index.mjs";
10
10
  import { DEFAULT_SECRET } from "../utils/constants.mjs";
@@ -1,7 +1,9 @@
1
- import { getBaseURL, isDynamicBaseURLConfig } from "../utils/url.mjs";
2
- import { createInternalAdapter } from "../db/internal-adapter.mjs";
1
+ import { getBaseURL, getOrigin, isDynamicBaseURLConfig, isRequestLike, resolveBaseURL } from "../utils/url.mjs";
3
2
  import { isPromise } from "../utils/is-promise.mjs";
3
+ import { createCookieGetter, getCookies } from "../cookies/index.mjs";
4
+ import { createInternalAdapter } from "../db/internal-adapter.mjs";
4
5
  import { env } from "@better-auth/core/env";
6
+ import { BetterAuthError } from "@better-auth/core/error";
5
7
  import { defu } from "defu";
6
8
  //#region src/context/helpers.ts
7
9
  async function runPluginInit(context) {
@@ -80,6 +82,62 @@ async function getTrustedOrigins(options, request) {
80
82
  if (envTrustedOrigins) trustedOrigins.push(...envTrustedOrigins.split(","));
81
83
  return trustedOrigins.filter((v) => Boolean(v));
82
84
  }
85
+ /**
86
+ * Picks a `Request`-like or `Headers` value from a direct `auth.api` call.
87
+ * Headers are only accepted when they carry a host: without one, host
88
+ * resolution would fall back to `null` and the caller should use `fallback`
89
+ * or pass a `Request` instead.
90
+ */
91
+ function pickSource(input) {
92
+ if (isRequestLike(input?.request)) return input.request;
93
+ if (!input?.headers) return void 0;
94
+ const headers = input.headers instanceof Headers ? input.headers : new Headers(input.headers);
95
+ if (!headers.has("host") && !headers.has("x-forwarded-host")) return;
96
+ return headers;
97
+ }
98
+ /**
99
+ * Returns the effective `trustedProxyHeaders` value for dynamic `baseURL`
100
+ * resolution. When the user hasn't set `advanced.trustedProxyHeaders`,
101
+ * proxy headers (`x-forwarded-host` / `x-forwarded-proto`) are trusted by
102
+ * default so deployments behind a reverse proxy work without extra config.
103
+ */
104
+ function resolveDynamicTrustedProxyHeaders(options) {
105
+ return options.advanced?.trustedProxyHeaders ?? true;
106
+ }
107
+ /**
108
+ * Per-request clone with `baseURL`, `trustedOrigins`, `trustedProviders`
109
+ * and cookies rehydrated for the resolved host. Throws `BetterAuthError`
110
+ * when the URL cannot be resolved; callers on the direct-API path convert
111
+ * this to `APIError`.
112
+ */
113
+ async function resolveRequestContext(ctx, source, trustedProxyHeaders) {
114
+ const dynamicBaseURLConfig = ctx.options.baseURL;
115
+ const baseURL = resolveBaseURL(dynamicBaseURLConfig, ctx.options.basePath || "/api/auth", source, void 0, trustedProxyHeaders);
116
+ if (!baseURL) throw new BetterAuthError("Could not resolve base URL from request. Check your allowedHosts config.");
117
+ const resolved = Object.create(Object.getPrototypeOf(ctx), Object.getOwnPropertyDescriptors(ctx));
118
+ resolved.baseURL = baseURL;
119
+ resolved.options = {
120
+ ...ctx.options,
121
+ baseURL: getOrigin(baseURL) || void 0
122
+ };
123
+ const trustedOriginOptions = {
124
+ ...resolved.options,
125
+ baseURL: dynamicBaseURLConfig
126
+ };
127
+ const needsRequest = typeof ctx.options.trustedOrigins === "function" || typeof ctx.options.account?.accountLinking?.trustedProviders === "function";
128
+ let callbackRequest;
129
+ if (needsRequest) if (isRequestLike(source)) callbackRequest = source;
130
+ else if (source) callbackRequest = new Request(baseURL, { headers: source });
131
+ else callbackRequest = void 0;
132
+ else callbackRequest = void 0;
133
+ resolved.trustedOrigins = await getTrustedOrigins(trustedOriginOptions, callbackRequest);
134
+ resolved.trustedProviders = await getTrustedProviders(resolved.options, callbackRequest);
135
+ if (ctx.options.advanced?.crossSubDomainCookies?.enabled) {
136
+ resolved.authCookies = getCookies(resolved.options);
137
+ resolved.createAuthCookie = createCookieGetter(resolved.options);
138
+ }
139
+ return resolved;
140
+ }
83
141
  async function getAwaitableValue(arr, item) {
84
142
  if (!arr) return void 0;
85
143
  for (const val of arr) {
@@ -94,4 +152,4 @@ async function getTrustedProviders(options, request) {
94
152
  return (await trustedProviders(request) ?? []).filter((v) => Boolean(v));
95
153
  }
96
154
  //#endregion
97
- export { getAwaitableValue, getInternalPlugins, getTrustedOrigins, getTrustedProviders, runPluginInit };
155
+ export { getAwaitableValue, getInternalPlugins, getTrustedOrigins, getTrustedProviders, pickSource, resolveDynamicTrustedProxyHeaders, resolveRequestContext, runPluginInit };
@@ -1,11 +1,11 @@
1
1
  import { isDynamicBaseURLConfig } from "../utils/url.mjs";
2
- import { getDate } from "../utils/date.mjs";
2
+ import { signJWT, symmetricDecodeJWT, symmetricEncodeJWT, verifyJWT } from "../crypto/jwt.mjs";
3
3
  import { parseUserOutput } from "../db/schema.mjs";
4
+ import { getDate } from "../utils/date.mjs";
4
5
  import { isPromise } from "../utils/is-promise.mjs";
5
- import { signJWT, symmetricDecodeJWT, symmetricEncodeJWT, verifyJWT } from "../crypto/jwt.mjs";
6
- import { createAccountStore, createSessionStore, getAccountCookie, getChunkedCookie, setAccountCookie } from "./session-store.mjs";
7
6
  import { sec } from "../utils/time.mjs";
8
7
  import { HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, parseSetCookieHeader, setCookieToHeader, splitSetCookieHeader, stripSecureCookiePrefix } from "./cookie-utils.mjs";
8
+ import { createAccountStore, createSessionStore, getAccountCookie, getChunkedCookie, setAccountCookie } from "./session-store.mjs";
9
9
  import { env, isProduction } from "@better-auth/core/env";
10
10
  import { BetterAuthError } from "@better-auth/core/error";
11
11
  import { safeJSONParse } from "@better-auth/core/utils/json";
@@ -1,9 +1,9 @@
1
- import { constantTimeEqual } from "./buffer.mjs";
2
1
  import { signJWT, symmetricDecodeJWT, symmetricEncodeJWT, verifyJWT } from "./jwt.mjs";
2
+ import { constantTimeEqual } from "./buffer.mjs";
3
3
  import { hashPassword, verifyPassword } from "./password.mjs";
4
4
  import { generateRandomString } from "./random.mjs";
5
- import { createHash } from "@better-auth/utils/hash";
6
5
  import { getWebcryptoSubtle } from "@better-auth/utils";
6
+ import { createHash } from "@better-auth/utils/hash";
7
7
  import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
8
8
  import { bytesToHex, hexToBytes, managedNonce, utf8ToBytes } from "@noble/ciphers/utils.js";
9
9
  //#region src/crypto/index.ts
package/dist/db/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { __exportAll, __reExport } from "../_virtual/_rolldown/runtime.mjs";
2
2
  import { getSchema } from "./get-schema.mjs";
3
- import { convertFromDB, convertToDB } from "./field-converter.mjs";
4
3
  import { getSessionDefaultFields, mergeSchema, parseAccountInput, parseAccountOutput, parseAdditionalUserInput, parseInputData, parseSessionInput, parseSessionOutput, parseUserInput, parseUserOutput } from "./schema.mjs";
4
+ import { convertFromDB, convertToDB } from "./field-converter.mjs";
5
5
  import { getWithHooks } from "./with-hooks.mjs";
6
6
  import { createInternalAdapter } from "./internal-adapter.mjs";
7
7
  import { toZodSchema } from "./to-zod.mjs";
@@ -1,6 +1,6 @@
1
1
  import { getIp } from "../utils/get-request-ip.mjs";
2
- import { getDate } from "../utils/date.mjs";
3
2
  import { getSessionDefaultFields, parseSessionOutput, parseUserOutput } from "./schema.mjs";
3
+ import { getDate } from "../utils/date.mjs";
4
4
  import { getStorageOption, processIdentifier } from "./verification-token-storage.mjs";
5
5
  import { getWithHooks } from "./with-hooks.mjs";
6
6
  import { getCurrentAdapter, getCurrentAuthContext, runWithTransaction } from "@better-auth/core/context";
package/dist/index.d.mts CHANGED
@@ -10,7 +10,7 @@ import { betterAuth } from "./auth/full.mjs";
10
10
  import { generateState, parseState } from "./oauth2/state.mjs";
11
11
  import { StateData, generateGenericState, parseGenericState } from "./state.mjs";
12
12
  import { HIDE_METADATA } from "./utils/hide-metadata.mjs";
13
- import { getBaseURL, getHost, getHostFromRequest, getOrigin, getProtocol, getProtocolFromRequest, isDynamicBaseURLConfig, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL } from "./utils/url.mjs";
13
+ import { getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL } from "./utils/url.mjs";
14
14
  import { APIError } from "./api/index.mjs";
15
15
  import { StandardSchemaV1 } from "@better-auth/core";
16
16
  import { getCurrentAdapter } from "@better-auth/core/context";
@@ -27,4 +27,4 @@ export * from "@better-auth/core/utils/json";
27
27
  export * from "@better-auth/core/social-providers";
28
28
  export * from "better-call";
29
29
  export * from "zod";
30
- export { APIError, Account, AdditionalSessionFieldsInput, AdditionalUserFieldsInput, Auth, BetterAuthAdvancedOptions, BetterAuthClientOptions, BetterAuthClientPlugin, BetterAuthCookies, BetterAuthOptions, BetterAuthPlugin, BetterAuthRateLimitOptions, ClientAtomListener, ClientStore, DBAdapter, DBAdapterInstance, DBAdapterSchemaCreation, DBTransactionAdapter, ExtractPluginField, FilteredAPI, HIDE_METADATA, HasRequiredKeys, InferAPI, InferActions, InferAdditionalFromClient, InferClientAPI, InferErrorCodes, InferOptionSchema, InferPluginContext, InferPluginErrorCodes, InferPluginFieldFromTuple, InferPluginIDs, InferPluginTypes, InferSessionAPI, InferSessionFromClient, InferUserFromClient, IsAny, IsSignal, type JSONWebKeySet, type JWTPayload, JoinConfig, JoinOption, OverrideMerge, Prettify, PrettifyDeep, RateLimit, RequiredKeysOf, Session, SessionQueryParams, type StandardSchemaV1, StateData, StoreIdentifierOption, StripEmptyObjects, type TelemetryEvent, UnionToIntersection, User, Verification, Where, betterAuth, createTelemetry, generateGenericState, generateState, getBaseURL, getCurrentAdapter, getHost, getHostFromRequest, getOrigin, getProtocol, getProtocolFromRequest, getTelemetryAuthConfig, isDynamicBaseURLConfig, matchesHostPattern, parseGenericState, parseState, resolveBaseURL, resolveDynamicBaseURL };
30
+ export { APIError, Account, AdditionalSessionFieldsInput, AdditionalUserFieldsInput, Auth, BetterAuthAdvancedOptions, BetterAuthClientOptions, BetterAuthClientPlugin, BetterAuthCookies, BetterAuthOptions, BetterAuthPlugin, BetterAuthRateLimitOptions, ClientAtomListener, ClientStore, DBAdapter, DBAdapterInstance, DBAdapterSchemaCreation, DBTransactionAdapter, ExtractPluginField, FilteredAPI, HIDE_METADATA, HasRequiredKeys, InferAPI, InferActions, InferAdditionalFromClient, InferClientAPI, InferErrorCodes, InferOptionSchema, InferPluginContext, InferPluginErrorCodes, InferPluginFieldFromTuple, InferPluginIDs, InferPluginTypes, InferSessionAPI, InferSessionFromClient, InferUserFromClient, IsAny, IsSignal, type JSONWebKeySet, type JWTPayload, JoinConfig, JoinOption, OverrideMerge, Prettify, PrettifyDeep, RateLimit, RequiredKeysOf, Session, SessionQueryParams, type StandardSchemaV1, StateData, StoreIdentifierOption, StripEmptyObjects, type TelemetryEvent, UnionToIntersection, User, Verification, Where, betterAuth, createTelemetry, generateGenericState, generateState, getBaseURL, getCurrentAdapter, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, getTelemetryAuthConfig, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, parseGenericState, parseState, resolveBaseURL, resolveDynamicBaseURL };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { getBaseURL, getHost, getHostFromRequest, getOrigin, getProtocol, getProtocolFromRequest, isDynamicBaseURLConfig, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL } from "./utils/url.mjs";
1
+ import { getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL } from "./utils/url.mjs";
2
2
  import { generateGenericState, parseGenericState } from "./state.mjs";
3
3
  import { generateState, parseState } from "./oauth2/state.mjs";
4
4
  import { HIDE_METADATA } from "./utils/hide-metadata.mjs";
@@ -14,4 +14,4 @@ export * from "@better-auth/core/oauth2";
14
14
  export * from "@better-auth/core/utils/error-codes";
15
15
  export * from "@better-auth/core/utils/id";
16
16
  export * from "@better-auth/core/utils/json";
17
- export { APIError, HIDE_METADATA, betterAuth, createTelemetry, generateGenericState, generateState, getBaseURL, getCurrentAdapter, getHost, getHostFromRequest, getOrigin, getProtocol, getProtocolFromRequest, getTelemetryAuthConfig, isDynamicBaseURLConfig, matchesHostPattern, parseGenericState, parseState, resolveBaseURL, resolveDynamicBaseURL };
17
+ export { APIError, HIDE_METADATA, betterAuth, createTelemetry, generateGenericState, generateState, getBaseURL, getCurrentAdapter, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, getTelemetryAuthConfig, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, parseGenericState, parseState, resolveBaseURL, resolveDynamicBaseURL };