better-auth 1.6.1 → 1.6.3

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 (57) hide show
  1. package/dist/api/index.d.mts +0 -2
  2. package/dist/api/routes/account.mjs +1 -1
  3. package/dist/api/routes/callback.mjs +2 -2
  4. package/dist/api/routes/email-verification.mjs +1 -1
  5. package/dist/api/routes/password.mjs +1 -1
  6. package/dist/api/routes/session.d.mts +0 -1
  7. package/dist/api/routes/session.mjs +3 -4
  8. package/dist/api/routes/sign-in.mjs +1 -1
  9. package/dist/api/to-auth-endpoints.mjs +27 -3
  10. package/dist/auth/base.mjs +5 -24
  11. package/dist/client/plugins/index.d.mts +2 -2
  12. package/dist/client/query.mjs +4 -4
  13. package/dist/context/create-context.mjs +2 -2
  14. package/dist/context/helpers.mjs +61 -3
  15. package/dist/cookies/index.mjs +3 -3
  16. package/dist/crypto/index.mjs +2 -2
  17. package/dist/db/index.mjs +1 -1
  18. package/dist/db/internal-adapter.mjs +1 -1
  19. package/dist/index.d.mts +2 -2
  20. package/dist/index.mjs +2 -2
  21. package/dist/integrations/next-js.mjs +21 -12
  22. package/dist/oauth2/state.d.mts +1 -0
  23. package/dist/package.mjs +1 -1
  24. package/dist/plugins/admin/admin.d.mts +1 -3
  25. package/dist/plugins/admin/routes.mjs +2 -8
  26. package/dist/plugins/device-authorization/routes.mjs +1 -1
  27. package/dist/plugins/email-otp/routes.mjs +1 -1
  28. package/dist/plugins/index.d.mts +2 -2
  29. package/dist/plugins/jwt/utils.mjs +1 -1
  30. package/dist/plugins/mcp/index.mjs +20 -8
  31. package/dist/plugins/oauth-proxy/index.mjs +5 -1
  32. package/dist/plugins/oidc-provider/index.mjs +2 -2
  33. package/dist/plugins/organization/organization.d.mts +1 -3
  34. package/dist/plugins/organization/organization.mjs +1 -7
  35. package/dist/plugins/organization/routes/crud-invites.mjs +1 -1
  36. package/dist/plugins/organization/routes/crud-org.mjs +1 -1
  37. package/dist/plugins/organization/routes/crud-team.mjs +1 -1
  38. package/dist/plugins/phone-number/routes.mjs +1 -1
  39. package/dist/plugins/two-factor/backup-codes/index.d.mts +2 -1
  40. package/dist/plugins/two-factor/backup-codes/index.mjs +12 -17
  41. package/dist/plugins/two-factor/client.d.mts +12 -2
  42. package/dist/plugins/two-factor/client.mjs +1 -1
  43. package/dist/plugins/two-factor/index.d.mts +9 -2
  44. package/dist/plugins/two-factor/index.mjs +35 -3
  45. package/dist/plugins/two-factor/otp/index.mjs +1 -1
  46. package/dist/plugins/two-factor/schema.d.mts +6 -0
  47. package/dist/plugins/two-factor/schema.mjs +6 -0
  48. package/dist/plugins/two-factor/totp/index.mjs +19 -10
  49. package/dist/plugins/two-factor/types.d.mts +1 -1
  50. package/dist/state.d.mts +6 -0
  51. package/dist/state.mjs +18 -2
  52. package/dist/test-utils/test-instance.d.mts +0 -6
  53. package/dist/test-utils/test-instance.mjs +7 -1
  54. package/dist/utils/index.d.mts +1 -1
  55. package/dist/utils/url.d.mts +22 -15
  56. package/dist/utils/url.mjs +54 -28
  57. package/package.json +9 -9
@@ -249,7 +249,6 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
249
249
  "application/json": {
250
250
  schema: {
251
251
  type: "object";
252
- nullable: boolean;
253
252
  properties: {
254
253
  session: {
255
254
  $ref: string;
@@ -2239,7 +2238,6 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2239
2238
  "application/json": {
2240
2239
  schema: {
2241
2240
  type: "object";
2242
- nullable: boolean;
2243
2241
  properties: {
2244
2242
  session: {
2245
2243
  $ref: 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";
@@ -1,5 +1,5 @@
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
5
  import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
@@ -104,7 +104,7 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
104
104
  return redirectOnError("unable_to_link_account");
105
105
  }
106
106
  if (userInfo.email?.toLowerCase() !== link.email.toLowerCase() && c.context.options.account?.accountLinking?.allowDifferentEmails !== true) return redirectOnError("email_doesn't_match");
107
- const existingAccount = await c.context.internalAdapter.findAccount(String(userInfo.id));
107
+ const existingAccount = await c.context.internalAdapter.findAccountByProviderId(String(userInfo.id), provider.id);
108
108
  if (existingAccount) {
109
109
  if (existingAccount.userId.toString() !== link.userId.toString()) return redirectOnError("account_already_linked_to_different_user");
110
110
  const updateData = Object.fromEntries(Object.entries({
@@ -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";
@@ -82,7 +82,7 @@ const requestPasswordReset = createAuthEndpoint("/request-password-reset", {
82
82
  });
83
83
  const requestPasswordResetCallback = createAuthEndpoint("/reset-password/:token", {
84
84
  method: "GET",
85
- operationId: "forgetPasswordCallback",
85
+ operationId: "resetPasswordCallback",
86
86
  query: z.object({ callbackURL: z.string().meta({ description: "The URL to redirect the user to reset their password" }) }),
87
87
  use: [originCheck((ctx) => ctx.query.callbackURL)],
88
88
  metadata: { openapi: {
@@ -25,7 +25,6 @@ declare const getSession: <Option extends BetterAuthOptions>() => better_call0.S
25
25
  "application/json": {
26
26
  schema: {
27
27
  type: "object";
28
- nullable: boolean;
29
28
  properties: {
30
29
  session: {
31
30
  $ref: string;
@@ -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";
@@ -24,8 +24,7 @@ const getSession = () => createAuthEndpoint("/get-session", {
24
24
  responses: { "200": {
25
25
  description: "Success",
26
26
  content: { "application/json": { schema: {
27
- type: "object",
28
- nullable: true,
27
+ type: ["object", "null"],
29
28
  properties: {
30
29
  session: { $ref: "#/components/schemas/Session" },
31
30
  user: { $ref: "#/components/schemas/User" }
@@ -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
  },
@@ -20,7 +20,7 @@ import { MULTI_SESSION_ERROR_CODES } from "../../plugins/multi-session/error-cod
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";
@@ -52,4 +52,4 @@ import { phoneNumberClient } from "../../plugins/phone-number/client.mjs";
52
52
  import { siweClient } from "../../plugins/siwe/client.mjs";
53
53
  import { usernameClient } from "../../plugins/username/client.mjs";
54
54
  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 };
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, 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 };
@@ -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 };
@@ -24,20 +24,29 @@ const nextCookies = () => {
24
24
  matcher(ctx) {
25
25
  return ctx.path === "/get-session";
26
26
  },
27
- handler: createAuthMiddleware(async () => {
28
- let cookieStore;
27
+ handler: createAuthMiddleware(async (ctx) => {
28
+ if ("_flag" in ctx && ctx._flag === "router") return;
29
+ let headersStore;
29
30
  try {
30
- const { cookies } = await import("next/headers.js");
31
- cookieStore = await cookies();
31
+ const { headers } = await import("next/headers.js");
32
+ headersStore = await headers();
32
33
  } catch {
33
34
  return;
34
35
  }
35
- try {
36
- cookieStore.set("__better-auth-cookie-store", "1", { maxAge: 0 });
37
- cookieStore.delete("__better-auth-cookie-store");
38
- } catch {
39
- await setShouldSkipSessionRefresh(true);
40
- }
36
+ /**
37
+ * Detect RSC via headers, NOT by probing cookies().set().
38
+ * In Next.js, cookies().set() unconditionally triggers router
39
+ * cache invalidation -- even if the value is unchanged.
40
+ *
41
+ * RSC sends `RSC: 1` without `next-action`. Only in that
42
+ * context cookies cannot be written -- skip session refresh
43
+ * to avoid DB/cookie mismatch.
44
+ *
45
+ * @see https://github.com/vercel/next.js/blob/8c5af211d580/packages/next/src/server/web/spec-extension/adapters/request-cookies.ts#L112-L157
46
+ */
47
+ const isRSC = headersStore.get("RSC") === "1";
48
+ const isServerAction = !!headersStore.get("next-action");
49
+ if (isRSC && !isServerAction) await setShouldSkipSessionRefresh(true);
41
50
  })
42
51
  }],
43
52
  after: [{
@@ -51,12 +60,12 @@ const nextCookies = () => {
51
60
  const setCookies = returned?.get("set-cookie");
52
61
  if (!setCookies) return;
53
62
  const parsed = parseSetCookieHeader(setCookies);
54
- const { cookies } = await import("next/headers.js");
55
63
  let cookieHelper;
56
64
  try {
65
+ const { cookies } = await import("next/headers.js");
57
66
  cookieHelper = await cookies();
58
67
  } catch (error) {
59
- if (error instanceof Error && error.message.startsWith("`cookies` was called outside a request scope.")) return;
68
+ if (error instanceof Error && (error.message.startsWith("`cookies` was called outside a request scope.") || error.message.includes("Cannot find module"))) return;
60
69
  throw error;
61
70
  }
62
71
  parsed.forEach((value, key) => {
@@ -15,6 +15,7 @@ declare function parseState(c: GenericEndpointContext): Promise<{
15
15
  expiresAt: number;
16
16
  errorURL?: string | undefined;
17
17
  newUserURL?: string | undefined;
18
+ oauthState?: string | undefined;
18
19
  link?: {
19
20
  email: string;
20
21
  userId: string;
package/dist/package.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "1.6.1";
2
+ var version = "1.6.3";
3
3
  //#endregion
4
4
  export { version };
@@ -775,11 +775,9 @@ declare const admin: <O extends AdminOptions>(options?: O | undefined) => {
775
775
  body: zod.ZodIntersection<zod.ZodObject<{
776
776
  userId: zod.ZodOptional<zod.ZodCoercedString<unknown>>;
777
777
  role: zod.ZodOptional<zod.ZodString>;
778
- }, zod_v4_core0.$strip>, zod.ZodUnion<readonly [zod.ZodObject<{
778
+ }, zod_v4_core0.$strip>, zod.ZodXor<readonly [zod.ZodObject<{
779
779
  permission: zod.ZodRecord<zod.ZodString, zod.ZodArray<zod.ZodString>>;
780
- permissions: zod.ZodUndefined;
781
780
  }, zod_v4_core0.$strip>, zod.ZodObject<{
782
- permission: zod.ZodUndefined;
783
781
  permissions: zod.ZodRecord<zod.ZodString, zod.ZodArray<zod.ZodString>>;
784
782
  }, zod_v4_core0.$strip>]>>;
785
783
  metadata: {
@@ -1,5 +1,5 @@
1
- import { getDate } from "../../utils/date.mjs";
2
1
  import { parseSessionOutput, parseUserOutput } from "../../db/schema.mjs";
2
+ import { getDate } from "../../utils/date.mjs";
3
3
  import { deleteSessionCookie, expireCookie, setSessionCookie } from "../../cookies/index.mjs";
4
4
  import { getSessionFromCtx } from "../../api/routes/session.mjs";
5
5
  import { ADMIN_ERROR_CODES } from "./error-codes.mjs";
@@ -766,13 +766,7 @@ const setUserPassword = (opts) => createAuthEndpoint("/admin/set-user-password",
766
766
  const userHasPermissionBodySchema = z.object({
767
767
  userId: z.coerce.string().optional().meta({ description: `The user id. Eg: "user-id"` }),
768
768
  role: z.string().optional().meta({ description: `The role to check permission for. Eg: "admin"` })
769
- }).and(z.union([z.object({
770
- permission: z.record(z.string(), z.array(z.string())),
771
- permissions: z.undefined()
772
- }), z.object({
773
- permission: z.undefined(),
774
- permissions: z.record(z.string(), z.array(z.string()))
775
- })]));
769
+ }).and(z.xor([z.object({ permission: z.record(z.string(), z.array(z.string())) }), z.object({ permissions: z.record(z.string(), z.array(z.string())) })]));
776
770
  /**
777
771
  * ### Endpoint
778
772
  *
@@ -1,5 +1,5 @@
1
- import { generateRandomString } from "../../crypto/random.mjs";
2
1
  import { ms } from "../../utils/time.mjs";
2
+ import { generateRandomString } from "../../crypto/random.mjs";
3
3
  import { getSessionFromCtx } from "../../api/routes/session.mjs";
4
4
  import { DEVICE_AUTHORIZATION_ERROR_CODES } from "./error-codes.mjs";
5
5
  import { APIError } from "@better-auth/core/error";
@@ -1,5 +1,5 @@
1
- import { getDate } from "../../utils/date.mjs";
2
1
  import { parseUserInput, parseUserOutput } from "../../db/schema.mjs";
2
+ import { getDate } from "../../utils/date.mjs";
3
3
  import { generateRandomString } from "../../crypto/random.mjs";
4
4
  import { symmetricDecrypt } from "../../crypto/index.mjs";
5
5
  import { setCookieCache, setSessionCookie } from "../../cookies/index.mjs";
@@ -51,7 +51,7 @@ import { phoneNumber } from "./phone-number/index.mjs";
51
51
  import { SIWEPluginOptions, siwe } from "./siwe/index.mjs";
52
52
  import { LoginResult, TestCookie, TestHelpers, TestUtilsOptions } from "./test-utils/types.mjs";
53
53
  import { testUtils } from "./test-utils/index.mjs";
54
- import { BackupCodeOptions, backupCode2fa, generateBackupCodes, getBackupCodes, verifyBackupCode } from "./two-factor/backup-codes/index.mjs";
54
+ import { BackupCodeOptions, backupCode2fa, encodeBackupCodes, generateBackupCodes, getBackupCodes, verifyBackupCode } from "./two-factor/backup-codes/index.mjs";
55
55
  import { OTPOptions, otp2fa } from "./two-factor/otp/index.mjs";
56
56
  import { TOTPOptions, totp2fa } from "./two-factor/totp/index.mjs";
57
57
  import { TwoFactorOptions, TwoFactorProvider, TwoFactorTable, UserWithTwoFactor } from "./two-factor/types.mjs";
@@ -62,4 +62,4 @@ import { USERNAME_ERROR_CODES } from "./username/error-codes.mjs";
62
62
  import { UsernameOptions, username } from "./username/index.mjs";
63
63
  import { hasPermission } from "./organization/has-permission.mjs";
64
64
  import { DefaultOrganizationPlugin, DynamicAccessControlEndpoints, OrganizationCreator, OrganizationEndpoints, OrganizationPlugin, TeamEndpoints, organization, parseRoles } from "./organization/organization.mjs";
65
- export { AccessControl, AdminOptions, AnonymousOptions, AnonymousSession, ArrayElement, Auth0Options, AuthorizationQuery, AuthorizeResponse, BackupCodeOptions, BaseCaptchaOptions, BaseOAuthProviderOptions, BearerOptions, CaptchaFoxOptions, CaptchaOptions, Client, CloudflareTurnstileOptions, CodeVerificationValue, CustomSessionPluginOptions, DefaultOrganizationPlugin, DeviceAuthorizationOptions, DynamicAccessControlEndpoints, MULTI_SESSION_ERROR_CODES as ERROR_CODES, EmailOTPOptions, FieldSchema, GenericOAuthConfig, GenericOAuthOptions, GoogleRecaptchaOptions, GumroadOptions, HCaptchaOptions, HIDE_METADATA, HaveIBeenPwnedOptions, HubSpotOptions, InferAdminRolesFromOption, InferInvitation, InferMember, InferOptionSchema, InferOrganization, InferOrganizationRolesFromOption, InferOrganizationZodRolesFromOption, InferPluginContext, InferPluginErrorCodes, InferPluginIDs, InferTeam, Invitation, InvitationInput, InvitationStatus, JWKOptions, JWSAlgorithms, Jwk, JwtOptions, KeycloakOptions, LastLoginMethodOptions, LineOptions, LoginResult, MagicLinkOptions, Member, MemberInput, MicrosoftEntraIdOptions, MultiSessionConfig, OAuthAccessToken, OAuthProxyOptions, OIDCMetadata, OIDCOptions, OTPOptions, OktaOptions, OneTapOptions, OneTimeTokenOptions, OpenAPIModelSchema, OpenAPIOptions, Organization, OrganizationCreator, OrganizationEndpoints, OrganizationInput, OrganizationOptions, OrganizationPlugin, OrganizationRole, OrganizationSchema, Path, PatreonOptions, PhoneNumberOptions, Provider, Role, SIWEPluginOptions, SessionWithImpersonatedBy, SlackOptions, Statements, SubArray, Subset, TOTPOptions, TWO_FACTOR_ERROR_CODES, Team, TeamEndpoints, TeamInput, TeamMember, TeamMemberInput, TestCookie, TestHelpers, TestUtilsOptions, TimeString, TokenBody, TwoFactorOptions, TwoFactorProvider, TwoFactorTable, USERNAME_ERROR_CODES, UserWithAnonymous, UserWithPhoneNumber, UserWithRole, UserWithTwoFactor, UsernameOptions, admin, anonymous, auth0, backupCode2fa, bearer, captcha, createAccessControl, createJwk, customSession, defaultRolesSchema, deviceAuthorization, deviceAuthorizationOptionsSchema, emailOTP, generateBackupCodes, generateExportedKeyPair, generator, genericOAuth, getBackupCodes, getClient, getJwtToken, getMCPProtectedResourceMetadata, getMCPProviderMetadata, getMetadata, getOrgAdapter, gumroad, hasPermission, haveIBeenPwned, hubspot, invitationSchema, invitationStatus, jwt, keycloak, lastLoginMethod, line, magicLink, mcp, memberSchema, microsoftEntraId, ms, multiSession, oAuthDiscoveryMetadata, oAuthProtectedResourceMetadata, oAuthProxy, oidcProvider, okta, oneTap, oneTimeToken, openAPI, organization, organizationRoleSchema, organizationSchema, otp2fa, parseRoles, patreon, phoneNumber, role, roleSchema, sec, signJWT, siwe, slack, teamMemberSchema, teamSchema, testUtils, toExpJWT, totp2fa, twoFactor, twoFactorClient, username, verifyBackupCode, verifyJWT, withMcpAuth };
65
+ export { AccessControl, AdminOptions, AnonymousOptions, AnonymousSession, ArrayElement, Auth0Options, AuthorizationQuery, AuthorizeResponse, BackupCodeOptions, BaseCaptchaOptions, BaseOAuthProviderOptions, BearerOptions, CaptchaFoxOptions, CaptchaOptions, Client, CloudflareTurnstileOptions, CodeVerificationValue, CustomSessionPluginOptions, DefaultOrganizationPlugin, DeviceAuthorizationOptions, DynamicAccessControlEndpoints, MULTI_SESSION_ERROR_CODES as ERROR_CODES, EmailOTPOptions, FieldSchema, GenericOAuthConfig, GenericOAuthOptions, GoogleRecaptchaOptions, GumroadOptions, HCaptchaOptions, HIDE_METADATA, HaveIBeenPwnedOptions, HubSpotOptions, InferAdminRolesFromOption, InferInvitation, InferMember, InferOptionSchema, InferOrganization, InferOrganizationRolesFromOption, InferOrganizationZodRolesFromOption, InferPluginContext, InferPluginErrorCodes, InferPluginIDs, InferTeam, Invitation, InvitationInput, InvitationStatus, JWKOptions, JWSAlgorithms, Jwk, JwtOptions, KeycloakOptions, LastLoginMethodOptions, LineOptions, LoginResult, MagicLinkOptions, Member, MemberInput, MicrosoftEntraIdOptions, MultiSessionConfig, OAuthAccessToken, OAuthProxyOptions, OIDCMetadata, OIDCOptions, OTPOptions, OktaOptions, OneTapOptions, OneTimeTokenOptions, OpenAPIModelSchema, OpenAPIOptions, Organization, OrganizationCreator, OrganizationEndpoints, OrganizationInput, OrganizationOptions, OrganizationPlugin, OrganizationRole, OrganizationSchema, Path, PatreonOptions, PhoneNumberOptions, Provider, Role, SIWEPluginOptions, SessionWithImpersonatedBy, SlackOptions, Statements, SubArray, Subset, TOTPOptions, TWO_FACTOR_ERROR_CODES, Team, TeamEndpoints, TeamInput, TeamMember, TeamMemberInput, TestCookie, TestHelpers, TestUtilsOptions, TimeString, TokenBody, TwoFactorOptions, TwoFactorProvider, TwoFactorTable, USERNAME_ERROR_CODES, UserWithAnonymous, UserWithPhoneNumber, UserWithRole, UserWithTwoFactor, UsernameOptions, admin, anonymous, auth0, backupCode2fa, bearer, captcha, createAccessControl, createJwk, customSession, defaultRolesSchema, deviceAuthorization, deviceAuthorizationOptionsSchema, emailOTP, encodeBackupCodes, generateBackupCodes, generateExportedKeyPair, generator, genericOAuth, getBackupCodes, getClient, getJwtToken, getMCPProtectedResourceMetadata, getMCPProviderMetadata, getMetadata, getOrgAdapter, gumroad, hasPermission, haveIBeenPwned, hubspot, invitationSchema, invitationStatus, jwt, keycloak, lastLoginMethod, line, magicLink, mcp, memberSchema, microsoftEntraId, ms, multiSession, oAuthDiscoveryMetadata, oAuthProtectedResourceMetadata, oAuthProxy, oidcProvider, okta, oneTap, oneTimeToken, openAPI, organization, organizationRoleSchema, organizationSchema, otp2fa, parseRoles, patreon, phoneNumber, role, roleSchema, sec, signJWT, siwe, slack, teamMemberSchema, teamSchema, testUtils, toExpJWT, totp2fa, twoFactor, twoFactorClient, username, verifyBackupCode, verifyJWT, withMcpAuth };
@@ -1,5 +1,5 @@
1
- import { symmetricEncrypt } from "../../crypto/index.mjs";
2
1
  import { sec } from "../../utils/time.mjs";
2
+ import { symmetricEncrypt } from "../../crypto/index.mjs";
3
3
  import { getJwksAdapter } from "./adapter.mjs";
4
4
  import { exportJWK, generateKeyPair } from "jose";
5
5
  //#region src/plugins/jwt/utils.ts