@better-auth/infra 0.4.6 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { i as INFRA_USER_AGENT, n as INFRA_API_URL, o as PLUGIN_VERSION, r as INFRA_KV_URL } from "./constants-CApB_fKA.mjs";
2
- import { a as createAPI, n as hash$1, o as createKV, r as hmacSha256Hex } from "./crypto-CfK70MTZ.mjs";
1
+ import { i as INFRA_USER_AGENT, n as INFRA_API_URL, o as PLUGIN_VERSION, r as INFRA_KV_URL } from "./constants-C8_UJzzu.mjs";
2
+ import { a as createAPI, n as hash$1, o as createKV, r as hmacSha256Hex } from "./crypto-DRS7yhmR.mjs";
3
3
  import { EMAIL_TEMPLATES, createEmailSender, sendBulkEmails, sendEmail } from "./email.mjs";
4
4
  import { getCurrentAdapter, getCurrentAuthContext, getCurrentDBAdapterAsyncLocalStorage, runWithTransaction } from "@better-auth/core/context";
5
5
  import { APIError, generateId, getAuthTables, logger } from "better-auth";
@@ -21,14 +21,18 @@ function resolveConnectionOptions(options) {
21
21
  apiUrl: options?.apiUrl || INFRA_API_URL,
22
22
  kvUrl: options?.kvUrl || INFRA_KV_URL,
23
23
  apiKey: options?.apiKey || env.BETTER_AUTH_API_KEY || "",
24
- apiOptions: { timeout: options?.apiOptions?.timeout ?? options?.apiTimeout ?? 3e3 },
24
+ apiOptions: {
25
+ timeout: options?.apiOptions?.timeout ?? options?.apiTimeout ?? 3e3,
26
+ headers: options?.apiOptions?.headers
27
+ },
25
28
  kvOptions: {
26
29
  timeout: options?.kvOptions?.timeout ?? options?.kvTimeout ?? 1e3,
27
30
  retry: {
28
31
  attempts: options?.kvOptions?.retry?.attempts ?? 2,
29
32
  baseDelay: options?.kvOptions?.retry?.baseDelay ?? 400,
30
33
  maxDelay: options?.kvOptions?.retry?.maxDelay ?? 600
31
- }
34
+ },
35
+ headers: options?.kvOptions?.headers
32
36
  }
33
37
  };
34
38
  }
@@ -56,6 +60,21 @@ function resolveSentinelOptions(options) {
56
60
  };
57
61
  }
58
62
  //#endregion
63
+ //#region src/types.ts
64
+ /** Type-only cast — does not wrap or mutate ctx. */
65
+ function asInfraContext(ctx) {
66
+ return ctx;
67
+ }
68
+ /**
69
+ * better-auth createAuthMiddleware with InfraAuthContext on `ctx.context`.
70
+ * Pass-through at runtime — type-only (does not wrap the handler).
71
+ *
72
+ * Prefer this for dash/sentinel/identification hooks. Keep better-auth's
73
+ * createAuthMiddleware where middleware return values must extend AuthContext
74
+ * (e.g. JWT `payload` via `use: [...]`).
75
+ */
76
+ const createAuthMiddleware$1 = createAuthMiddleware;
77
+ //#endregion
59
78
  //#region ../utils/dist/ip.mjs
60
79
  /** Platform-set client IP headers (not accepted from clients on the open internet). */
61
80
  const DEFAULT_TRUSTED_IP_HEADERS = [
@@ -1102,7 +1121,7 @@ function shouldRunIdentification(ctx, getRoutes = IDENTIFICATION_GET_ROUTES) {
1102
1121
  * needs it; together they would append duplicate Set-Cookie headers).
1103
1122
  */
1104
1123
  function createIdentificationCookieAfterMiddleware() {
1105
- return createAuthMiddleware(async (ctx) => {
1124
+ return createAuthMiddleware$1(async (ctx) => {
1106
1125
  if (ctx.context.infraRidCookieSet) return;
1107
1126
  ctx.context.infraRidCookieSet = true;
1108
1127
  const headerRequestId = ctx.request?.headers.get("X-Request-Id");
@@ -1230,7 +1249,7 @@ function resolveUntrustedVisitorId(visitorId, ip, headerVisitorId) {
1230
1249
  */
1231
1250
  function createIdentificationMiddleware($kv, options) {
1232
1251
  const retry = options?.retry ?? DEFAULT_KV_RETRY;
1233
- return createAuthMiddleware(async (ctx) => {
1252
+ return createAuthMiddleware$1(async (ctx) => {
1234
1253
  const skipIdentification = options?.skipIdentification?.(ctx) ?? false;
1235
1254
  let headerVisitorId = null;
1236
1255
  let requestId = null;
@@ -1368,7 +1387,8 @@ function createSecurityClient(conn, $api, options, onSecurityEvent) {
1368
1387
  const resolvedApiUrl = conn.apiUrl || INFRA_API_URL;
1369
1388
  const emailSender = createEmailSender({
1370
1389
  apiUrl: resolvedApiUrl,
1371
- apiKey: conn.apiKey
1390
+ apiKey: conn.apiKey,
1391
+ apiOptions: { headers: conn.apiOptions.headers }
1372
1392
  });
1373
1393
  function logEvent(event) {
1374
1394
  const fullEvent = {
@@ -2475,7 +2495,8 @@ const sentinel = (options) => {
2475
2495
  const $kv = createKV({
2476
2496
  kvUrl: opts.kvUrl,
2477
2497
  apiKey: opts.apiKey,
2478
- timeout: opts.kvOptions.timeout
2498
+ timeout: opts.kvOptions.timeout,
2499
+ headers: opts.kvOptions.headers
2479
2500
  });
2480
2501
  const { tracker } = initTrackEvents($api);
2481
2502
  const { trackEvent } = tracker;
@@ -2576,14 +2597,15 @@ const sentinel = (options) => {
2576
2597
  customRules
2577
2598
  } },
2578
2599
  options: {
2579
- emailValidation: opts.security?.emailValidation,
2580
- emailNormalization: opts.security?.emailNormalization,
2600
+ ...opts.security?.emailValidation !== void 0 ? { emailValidation: opts.security.emailValidation } : {},
2601
+ ...opts.security?.emailNormalization !== void 0 ? { emailNormalization: opts.security.emailNormalization } : {},
2581
2602
  rateLimit: { customRules },
2582
2603
  databaseHooks: {
2583
2604
  user: {
2584
2605
  create: {
2585
- async before(user, ctx) {
2586
- if (!ctx) return;
2606
+ async before(user, _ctx) {
2607
+ if (!_ctx) return;
2608
+ const ctx = asInfraContext(_ctx);
2587
2609
  if (isDashRoute(ctx.path)) {
2588
2610
  if (user.email && typeof user.email === "string" && isEmailNormalizationEnabled(opts.security)) return { data: {
2589
2611
  ...user,
@@ -2617,8 +2639,9 @@ const sentinel = (options) => {
2617
2639
  email: normalizeEmail(user.email, ctx.context)
2618
2640
  } };
2619
2641
  },
2620
- async after(user, ctx) {
2621
- if (!ctx || isDashRoute(ctx.path)) return;
2642
+ async after(user, _ctx) {
2643
+ if (!_ctx || isDashRoute(_ctx.path)) return;
2644
+ const ctx = asInfraContext(_ctx);
2622
2645
  const visitorId = ctx.context.visitorId;
2623
2646
  const reservationId = ctx.context.freeTrialReservationId;
2624
2647
  if (visitorId && reservationId && opts.security?.freeTrialAbuse?.enabled) await ctx.context.runInBackgroundOrAwait(securityService.confirmFreeTrialSignup(visitorId, reservationId, user.id, ctx.context.requestId ?? null));
@@ -2633,8 +2656,9 @@ const sentinel = (options) => {
2633
2656
  } }
2634
2657
  },
2635
2658
  session: { create: {
2636
- async before(session, ctx) {
2637
- if (!ctx || isDashRoute(ctx.path)) return;
2659
+ async before(session, _ctx) {
2660
+ if (!_ctx || isDashRoute(_ctx.path)) return;
2661
+ const ctx = asInfraContext(_ctx);
2638
2662
  const visitorId = ctx.context.visitorId;
2639
2663
  const identification = ctx.context.identification;
2640
2664
  if (session.userId && identification?.location && visitorId) {
@@ -2666,8 +2690,9 @@ const sentinel = (options) => {
2666
2690
  }
2667
2691
  }
2668
2692
  },
2669
- async after(session, ctx) {
2670
- if (!ctx || !session.userId || isDashRoute(ctx.path)) return;
2693
+ async after(session, _ctx) {
2694
+ if (!_ctx || !session.userId || isDashRoute(_ctx.path)) return;
2695
+ const ctx = asInfraContext(_ctx);
2671
2696
  const visitorId = ctx.context.visitorId;
2672
2697
  const identification = ctx.context.identification;
2673
2698
  let user = null;
@@ -2699,7 +2724,7 @@ const sentinel = (options) => {
2699
2724
  ...phoneValidationHooks.before,
2700
2725
  {
2701
2726
  matcher: (ctx) => ctx.request?.method !== "GET" && !isDashRoute(ctx.path),
2702
- handler: createAuthMiddleware(async (ctx) => {
2727
+ handler: createAuthMiddleware$1(async (ctx) => {
2703
2728
  const visitorId = ctx.context.visitorId;
2704
2729
  const identification = ctx.context.identification;
2705
2730
  const ip = ctx.context.ip;
@@ -2759,7 +2784,7 @@ const sentinel = (options) => {
2759
2784
  },
2760
2785
  {
2761
2786
  matcher: (ctx) => !!opts.security?.staleUsers?.enabled && !isDashRoute(ctx.path),
2762
- handler: createAuthMiddleware(async (ctx) => {
2787
+ handler: createAuthMiddleware$1(async (ctx) => {
2763
2788
  if (ctx.context.returned instanceof Error) return;
2764
2789
  const created = ctx.context.newSession;
2765
2790
  const userId = created?.user?.id ?? created?.session?.userId;
@@ -2806,7 +2831,7 @@ const sentinel = (options) => {
2806
2831
  },
2807
2832
  {
2808
2833
  matcher: (ctx) => ctx.request?.method !== "GET" && !isDashRoute(ctx.path),
2809
- handler: createAuthMiddleware(async (ctx) => {
2834
+ handler: createAuthMiddleware$1(async (ctx) => {
2810
2835
  const untrustedVisitorId = ctx.context.untrustedVisitorId;
2811
2836
  const ip = ctx.context.ip;
2812
2837
  const body = ctx.body;
@@ -10525,11 +10550,12 @@ function createSMSSender(config) {
10525
10550
  if (!apiKey) logger.warn("[Dash] No API key provided for SMS sending. Set BETTER_AUTH_API_KEY environment variable or pass apiKey in config.");
10526
10551
  const $api = createFetch({
10527
10552
  baseURL: apiUrl,
10553
+ timeout: config?.apiOptions?.timeout ?? config?.apiTimeout ?? 3e3,
10528
10554
  headers: {
10555
+ ...config?.apiOptions?.headers,
10529
10556
  "user-agent": INFRA_USER_AGENT,
10530
10557
  Authorization: `Bearer ${apiKey}`
10531
- },
10532
- timeout: config?.apiOptions?.timeout ?? config?.apiTimeout ?? 3e3
10558
+ }
10533
10559
  });
10534
10560
  /**
10535
10561
  * Send an SMS with OTP code
@@ -10622,7 +10648,7 @@ function setPendingSessionTracking(ctx, pending) {
10622
10648
  }
10623
10649
  async function getRequestLocation() {
10624
10650
  try {
10625
- return (await getCurrentAuthContext()).context.location;
10651
+ return asInfraContext(await getCurrentAuthContext()).context.location;
10626
10652
  } catch {
10627
10653
  return;
10628
10654
  }
@@ -10638,7 +10664,8 @@ const dash = (options) => {
10638
10664
  const $kv = createKV({
10639
10665
  kvUrl: opts.kvUrl,
10640
10666
  apiKey: opts.apiKey,
10641
- timeout: opts.kvOptions.timeout
10667
+ timeout: opts.kvOptions.timeout,
10668
+ headers: opts.kvOptions.headers
10642
10669
  });
10643
10670
  const activityUpdateInterval = opts.activityTracking?.updateInterval ?? 3e5;
10644
10671
  const scheduleLastActiveUpdate = async (ctx, userId) => {
@@ -10970,7 +10997,8 @@ const dash = (options) => {
10970
10997
  const location = ctx.context.location;
10971
10998
  if (matchesAnyRoute(path, [routes.REQUEST_PASSWORD_RESET])) trackPasswordResetRequest(verification, trigger, ctx, location);
10972
10999
  } },
10973
- delete: { async after(verification, ctx) {
11000
+ delete: { async after(verification, _ctx) {
11001
+ const ctx = _ctx;
10974
11002
  if (!ctx) return;
10975
11003
  const path = ctx.path;
10976
11004
  const maybeUserId = ctx.context.session?.user.id ?? "unknown";
@@ -10994,7 +11022,7 @@ const dash = (options) => {
10994
11022
  after: [
10995
11023
  {
10996
11024
  matcher: (ctx) => !!getPendingSessionTracking(ctx),
10997
- handler: createAuthMiddleware(async (ctx) => {
11025
+ handler: createAuthMiddleware$1(async (ctx) => {
10998
11026
  const pending = getPendingSessionTracking(ctx);
10999
11027
  if (!pending) return;
11000
11028
  trackSessionLifecycle(pending.enrichedSession, pending.userId, ctx, pending.location, resolveUserFromContext(pending.userId, ctx), pending.trackSignIn, pending.impersonatedBy);
@@ -11009,8 +11037,7 @@ const dash = (options) => {
11009
11037
  routes.DASH_IMPERSONATE_USER
11010
11038
  ]);
11011
11039
  },
11012
- handler: createAuthMiddleware(async (_ctx) => {
11013
- const ctx = _ctx;
11040
+ handler: createAuthMiddleware$1(async (ctx) => {
11014
11041
  const maybeUserId = ctx.context.session?.user.id ?? "unknown";
11015
11042
  const trigger = getTriggerInfo(ctx, maybeUserId);
11016
11043
  if (matchesAnyRoute(ctx.path, [routes.SEND_VERIFICATION_EMAIL, routes.DASH_SEND_VERIFICATION_EMAIL]) && ctx.context.session && !(ctx.context.returned instanceof Error)) trackEmailVerificationSent(ctx.context.session.session, ctx.context.session.user, trigger, ctx.context.location);
@@ -11025,7 +11052,7 @@ const dash = (options) => {
11025
11052
  handler: createIdentificationCookieAfterMiddleware()
11026
11053
  },
11027
11054
  {
11028
- handler: createAuthMiddleware(async (ctx) => {
11055
+ handler: createAuthMiddleware$1(async (ctx) => {
11029
11056
  if (!opts.activityTracking?.enabled) return;
11030
11057
  if (activityUpdateInterval === 0) return;
11031
11058
  const session = ctx.context.session || ctx.context.newSession;
package/dist/native.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as DashGetAllAuditLogsInput, i as DashClientOptions, n as DashAuditLog, o as DashGetAuditLogsInput, r as DashAuditLogsResponse, s as dashClient, t as IdentifyClientOptions } from "./identify-client-options-Cim5Fztg.mjs";
1
+ import { a as DashGetAllAuditLogsInput, i as DashClientOptions, n as DashAuditLog, o as DashGetAuditLogsInput, r as DashAuditLogsResponse, s as dashClient, t as IdentifyClientOptions } from "./identify-client-options-DgKA4Eq8.mjs";
2
2
  import { BetterAuthClientPlugin } from "better-auth";
3
3
  //#region src/sentinel/native/client.d.ts
4
4
  interface SentinelNativeClientOptions {
package/dist/native.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { o as createKV, t as bytesToHex } from "./crypto-CfK70MTZ.mjs";
2
- import { a as resolveSentinelClientIdentifyUrl, c as identify, i as solvePoWChallenge, l as dashClient, n as decodePoWChallenge, o as resolveIdentifyClientRetry, r as encodePoWSolution, t as createPowRetryTimeout } from "./pow-retry-DkrUdqDd.mjs";
1
+ import { o as createKV, t as bytesToHex } from "./crypto-DRS7yhmR.mjs";
2
+ import { a as resolveSentinelClientIdentifyUrl, c as identify, i as solvePoWChallenge, l as dashClient, n as decodePoWChallenge, o as resolveIdentifyClientRetry, r as encodePoWSolution, t as createPowRetryTimeout } from "./pow-retry-Di0eUKbA.mjs";
3
3
  import { env } from "@better-auth/core/env";
4
4
  import { Dimensions, InteractionManager, PixelRatio, Platform } from "react-native";
5
5
  //#region src/sentinel/native/components.ts
@@ -1,4 +1,4 @@
1
- import { i as randomBytes, n as hash, t as bytesToHex } from "./crypto-CfK70MTZ.mjs";
1
+ import { i as randomBytes, n as hash, t as bytesToHex } from "./crypto-DRS7yhmR.mjs";
2
2
  //#region src/dash-client.ts
3
3
  function resolveDashUserId(input, options) {
4
4
  return input.userId || options?.resolveUserId?.({
@@ -1,7 +1,8 @@
1
- import { BetterAuthPlugin, GenericEndpointContext } from "better-auth";
1
+ import { GenericEndpointContext } from "better-auth";
2
+ import { createAuthMiddleware } from "better-auth/api";
2
3
  import { createFetch } from "@better-fetch/fetch";
3
4
  import { BetterAuthRateLimitRule } from "@better-auth/core";
4
- import { APIError as APIError$1, Endpoint, EndpointOptions } from "better-call";
5
+ import { APIError as APIError$2, Endpoint, EndpointOptions } from "better-call";
5
6
  //#region src/identification.d.ts
6
7
  interface IPLocation {
7
8
  lat: number;
@@ -170,28 +171,13 @@ declare const sentinel: (options?: SentinelOptions) => {
170
171
  init(ctx: import("better-auth").AuthContext): {
171
172
  context: {
172
173
  rateLimit: {
173
- customRules: {
174
- [key: string]: false | BetterAuthRateLimitRule | ((request: Request, currentRule: BetterAuthRateLimitRule) => import("@better-auth/core").Awaitable<false | BetterAuthRateLimitRule>);
175
- };
176
174
  enabled: boolean;
177
175
  window: number;
178
176
  max: number;
179
177
  storage: "memory" | "database" | "secondary-storage";
180
- modelName?: import("better-auth").LiteralString | "rateLimit" | undefined;
181
- fields?: Partial<Record<"key" | "count" | "lastRequest", string>> | undefined;
182
- customStorage?: import("better-auth").BetterAuthRateLimitStorage | undefined;
183
- };
178
+ } & Omit<import("better-auth").BetterAuthRateLimitOptions, "window" | "enabled" | "max" | "storage">;
184
179
  };
185
180
  options: {
186
- emailValidation: {
187
- enabled?: boolean;
188
- strictness?: "low" | "medium" | "high";
189
- action?: SecurityAction;
190
- domainAllowlist?: string[];
191
- } | undefined;
192
- emailNormalization: {
193
- enabled?: boolean;
194
- } | undefined;
195
181
  rateLimit: {
196
182
  customRules: {
197
183
  [key: string]: false | BetterAuthRateLimitRule | ((request: Request, currentRule: BetterAuthRateLimitRule) => import("@better-auth/core").Awaitable<false | BetterAuthRateLimitRule>);
@@ -208,7 +194,7 @@ declare const sentinel: (options?: SentinelOptions) => {
208
194
  emailVerified: boolean;
209
195
  name: string;
210
196
  image?: string | null | undefined;
211
- } & Record<string, unknown>, ctx: import("better-auth").GenericEndpointContext | null): Promise<{
197
+ } & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<{
212
198
  data: {
213
199
  email: string;
214
200
  id: string;
@@ -227,7 +213,7 @@ declare const sentinel: (options?: SentinelOptions) => {
227
213
  emailVerified: boolean;
228
214
  name: string;
229
215
  image?: string | null | undefined;
230
- } & Record<string, unknown>, ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
216
+ } & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
231
217
  };
232
218
  update: {
233
219
  before(user: Partial<{
@@ -262,7 +248,7 @@ declare const sentinel: (options?: SentinelOptions) => {
262
248
  token: string;
263
249
  ipAddress?: string | null | undefined;
264
250
  userAgent?: string | null | undefined;
265
- } & Record<string, unknown>, ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
251
+ } & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
266
252
  after(session: {
267
253
  id: string;
268
254
  createdAt: Date;
@@ -272,193 +258,29 @@ declare const sentinel: (options?: SentinelOptions) => {
272
258
  token: string;
273
259
  ipAddress?: string | null | undefined;
274
260
  userAgent?: string | null | undefined;
275
- } & Record<string, unknown>, ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
261
+ } & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
276
262
  };
277
263
  };
278
264
  };
265
+ emailNormalization?: {
266
+ enabled?: boolean;
267
+ } | undefined;
268
+ emailValidation?: {
269
+ enabled?: boolean;
270
+ strictness?: "low" | "medium" | "high";
271
+ action?: SecurityAction;
272
+ domainAllowlist?: string[];
273
+ } | undefined;
279
274
  };
280
275
  };
281
276
  hooks: {
282
- before: ({
283
- matcher: (context: Pick<import("better-auth").HookEndpointContext, "path">) => boolean;
284
- handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
285
- context: {
286
- method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
287
- path: string;
288
- body: any;
289
- query: Record<string, any> | undefined;
290
- params: Record<string, any> & string;
291
- request: Request | undefined;
292
- headers: Headers | undefined;
293
- setHeader: ((key: string, value: string) => void) & ((key: string, value: string) => void);
294
- setStatus: (status: import("better-call").Status) => void;
295
- getHeader: ((key: string) => string | null) & ((key: string) => string | null);
296
- getCookie: (key: string, prefix?: import("better-call").CookiePrefixOptions) => string | null;
297
- getSignedCookie: (key: string, secret: string, prefix?: import("better-call").CookiePrefixOptions) => Promise<string | null | false>;
298
- setCookie: (key: string, value: string, options?: import("better-call").CookieOptions) => string;
299
- setSignedCookie: (key: string, value: string, secret: string, options?: import("better-call").CookieOptions) => Promise<string>;
300
- responseHeaders: Headers;
301
- json: (<R extends Record<string, any> | null>(json: R, routerResponse?: {
302
- status?: number;
303
- headers?: Record<string, string>;
304
- response?: Response;
305
- body?: Record<string, string>;
306
- } | Response) => Promise<R>) & (<R extends Record<string, any> | null>(json: R, routerResponse?: {
307
- status?: number;
308
- headers?: Record<string, string>;
309
- response?: Response;
310
- } | Response) => Promise<R>);
311
- context: {
312
- [x: string]: any;
313
- } & {
314
- returned?: unknown | undefined;
315
- responseHeaders?: Headers | undefined;
316
- getPlugin: <ID extends import("better-auth").BetterAuthPluginRegistryIdentifier | import("better-auth").LiteralString, PluginOptions extends never>(pluginId: ID) => (ID extends keyof import("better-auth").BetterAuthPluginRegistry<unknown, unknown> ? import("better-auth").BetterAuthPluginRegistry<import("better-auth").BetterAuthOptions, PluginOptions>[ID] extends {
317
- creator: infer C;
318
- } ? C extends ((...args: any[]) => infer R) ? R : never : never : BetterAuthPlugin) | null;
319
- hasPlugin: <ID extends import("better-auth").BetterAuthPluginRegistryIdentifier | import("better-auth").LiteralString>(pluginId: ID) => ID extends never ? true : boolean;
320
- appName: string;
321
- baseURL: string;
322
- version: string;
323
- options: import("better-auth").BetterAuthOptions;
324
- trustedOrigins: string[];
325
- trustedProviders: string[];
326
- isTrustedOrigin: (url: string, settings?: {
327
- allowRelativePaths: boolean;
328
- }) => boolean;
329
- oauthConfig: {
330
- skipStateCookieCheck?: boolean | undefined;
331
- storeStateStrategy: "database" | "cookie";
332
- };
333
- newSession: {
334
- session: {
335
- id: string;
336
- createdAt: Date;
337
- updatedAt: Date;
338
- userId: string;
339
- expiresAt: Date;
340
- token: string;
341
- ipAddress?: string | null | undefined;
342
- userAgent?: string | null | undefined;
343
- } & Record<string, any>;
344
- user: {
345
- id: string;
346
- createdAt: Date;
347
- updatedAt: Date;
348
- email: string;
349
- emailVerified: boolean;
350
- name: string;
351
- image?: string | null | undefined;
352
- } & Record<string, any>;
353
- } | null;
354
- session: {
355
- session: {
356
- id: string;
357
- createdAt: Date;
358
- updatedAt: Date;
359
- userId: string;
360
- expiresAt: Date;
361
- token: string;
362
- ipAddress?: string | null | undefined;
363
- userAgent?: string | null | undefined;
364
- } & Record<string, any>;
365
- user: {
366
- id: string;
367
- createdAt: Date;
368
- updatedAt: Date;
369
- email: string;
370
- emailVerified: boolean;
371
- name: string;
372
- image?: string | null | undefined;
373
- } & Record<string, any>;
374
- } | null;
375
- setNewSession: (session: {
376
- session: {
377
- id: string;
378
- createdAt: Date;
379
- updatedAt: Date;
380
- userId: string;
381
- expiresAt: Date;
382
- token: string;
383
- ipAddress?: string | null | undefined;
384
- userAgent?: string | null | undefined;
385
- } & Record<string, any>;
386
- user: {
387
- id: string;
388
- createdAt: Date;
389
- updatedAt: Date;
390
- email: string;
391
- emailVerified: boolean;
392
- name: string;
393
- image?: string | null | undefined;
394
- } & Record<string, any>;
395
- } | null) => void;
396
- socialProviders: import("better-auth").OAuthProvider[];
397
- authCookies: import("better-auth").BetterAuthCookies;
398
- logger: ReturnType<(options?: import("better-auth").Logger | undefined) => import("better-auth").InternalLogger>;
399
- rateLimit: {
400
- enabled: boolean;
401
- window: number;
402
- max: number;
403
- storage: "memory" | "database" | "secondary-storage";
404
- } & Omit<import("better-auth").BetterAuthRateLimitOptions, "enabled" | "window" | "max" | "storage">;
405
- adapter: import("better-auth").DBAdapter<import("better-auth").BetterAuthOptions>;
406
- internalAdapter: import("better-auth").InternalAdapter<import("better-auth").BetterAuthOptions>;
407
- createAuthCookie: (cookieName: string, overrideAttributes?: Partial<import("better-call").CookieOptions> | undefined) => import("better-auth").BetterAuthCookie;
408
- secret: string;
409
- secretConfig: string | import("better-auth").SecretConfig;
410
- sessionConfig: {
411
- updateAge: number;
412
- expiresIn: number;
413
- freshAge: number;
414
- cookieRefreshCache: false | {
415
- enabled: true;
416
- updateAge: number;
417
- };
418
- };
419
- generateId: (options: {
420
- model: import("better-auth").ModelNames;
421
- size?: number | undefined;
422
- }) => string | false;
423
- secondaryStorage: import("better-auth").SecondaryStorage | undefined;
424
- password: {
425
- hash: (password: string) => Promise<string>;
426
- verify: (data: {
427
- password: string;
428
- hash: string;
429
- }) => Promise<boolean>;
430
- config: {
431
- minPasswordLength: number;
432
- maxPasswordLength: number;
433
- };
434
- checkPassword: (userId: string, ctx: import("better-auth").GenericEndpointContext<import("better-auth").BetterAuthOptions>) => Promise<boolean>;
435
- };
436
- tables: import("better-auth").BetterAuthDBSchema;
437
- runMigrations: () => Promise<void>;
438
- publishTelemetry: (event: {
439
- type: string;
440
- anonymousId?: string | undefined;
441
- payload: Record<string, any>;
442
- }) => Promise<void>;
443
- skipOriginCheck: boolean | string[];
444
- skipCSRFCheck: boolean;
445
- runInBackground: (promise: Promise<unknown>) => void;
446
- runInBackgroundOrAwait: (promise: Promise<unknown> | void) => import("better-auth").Awaitable<unknown>;
447
- };
448
- redirect: (url: string) => import("better-call").APIError;
449
- error: (status: ("OK" | "CREATED" | "ACCEPTED" | "NO_CONTENT" | "MULTIPLE_CHOICES" | "MOVED_PERMANENTLY" | "FOUND" | "SEE_OTHER" | "NOT_MODIFIED" | "TEMPORARY_REDIRECT" | "BAD_REQUEST" | "UNAUTHORIZED" | "PAYMENT_REQUIRED" | "FORBIDDEN" | "NOT_FOUND" | "METHOD_NOT_ALLOWED" | "NOT_ACCEPTABLE" | "PROXY_AUTHENTICATION_REQUIRED" | "REQUEST_TIMEOUT" | "CONFLICT" | "GONE" | "LENGTH_REQUIRED" | "PRECONDITION_FAILED" | "PAYLOAD_TOO_LARGE" | "URI_TOO_LONG" | "UNSUPPORTED_MEDIA_TYPE" | "RANGE_NOT_SATISFIABLE" | "EXPECTATION_FAILED" | "I'M_A_TEAPOT" | "MISDIRECTED_REQUEST" | "UNPROCESSABLE_ENTITY" | "LOCKED" | "FAILED_DEPENDENCY" | "TOO_EARLY" | "UPGRADE_REQUIRED" | "PRECONDITION_REQUIRED" | "TOO_MANY_REQUESTS" | "REQUEST_HEADER_FIELDS_TOO_LARGE" | "UNAVAILABLE_FOR_LEGAL_REASONS" | "INTERNAL_SERVER_ERROR" | "NOT_IMPLEMENTED" | "BAD_GATEWAY" | "SERVICE_UNAVAILABLE" | "GATEWAY_TIMEOUT" | "HTTP_VERSION_NOT_SUPPORTED" | "VARIANT_ALSO_NEGOTIATES" | "INSUFFICIENT_STORAGE" | "LOOP_DETECTED" | "NOT_EXTENDED" | "NETWORK_AUTHENTICATION_REQUIRED") | import("better-call").Status, body?: {
450
- message?: string;
451
- code?: string;
452
- } & Record<string, any>, headers?: HeadersInit) => import("better-call").APIError;
453
- };
454
- } | undefined>;
455
- } | {
456
- matcher: (ctx: import("better-auth").HookEndpointContext) => boolean;
457
- handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
458
- })[];
277
+ before: {
278
+ matcher: (context: import("better-auth").HookEndpointContext) => boolean;
279
+ handler: import("better-auth/api").AuthMiddleware;
280
+ }[];
459
281
  after: {
460
282
  matcher: (ctx: import("better-auth").HookEndpointContext) => boolean;
461
- handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
283
+ handler: import("better-call").Middleware<import("better-call").MiddlewareOptions, (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<unknown>>;
462
284
  }[];
463
285
  };
464
286
  };
@@ -497,11 +319,19 @@ interface ApiOptions {
497
319
  * @default 3000
498
320
  */
499
321
  timeout?: number;
322
+ /**
323
+ * Extra headers on every Dash API request.
324
+ * Cannot override built-in headers (`user-agent`, `x-api-key`).
325
+ */
326
+ headers?: Record<string, string>;
500
327
  }
501
328
  /**
502
329
  * Resolved {@link ApiOptions} with defaults applied.
503
330
  */
504
- type ApiOptionsResolved = Required<ApiOptions>;
331
+ type ApiOptionsResolved = {
332
+ timeout: number;
333
+ headers?: Record<string, string>;
334
+ };
505
335
  /**
506
336
  * KV HTTP client options.
507
337
  */
@@ -516,6 +346,11 @@ interface KvOptions {
516
346
  * @default { attempts: 2, baseDelay: 400, maxDelay: 600 }
517
347
  */
518
348
  retry?: KvRetryOptions;
349
+ /**
350
+ * Extra headers on every KV request.
351
+ * Cannot override built-in headers (`user-agent`, `x-api-key`).
352
+ */
353
+ headers?: Record<string, string>;
519
354
  }
520
355
  /**
521
356
  * Resolved {@link KvOptions} with defaults applied.
@@ -523,6 +358,7 @@ interface KvOptions {
523
358
  interface KvOptionsResolved {
524
359
  timeout: number;
525
360
  retry: KvRetryOptionsResolved;
361
+ headers?: Record<string, string>;
526
362
  }
527
363
  /**
528
364
  * Shared connection options used by infra plugins.
@@ -678,15 +514,44 @@ interface LocationData {
678
514
  }
679
515
  /** @deprecated Use LocationData instead */
680
516
  type LocationDataContext = LocationData;
681
- type InfraEndpointContext = (GenericEndpointContext & {
682
- context: {
683
- identification?: Identification | null | undefined;
684
- visitorId: string | null;
685
- requestId: string | null;
686
- ip: string | null;
687
- untrustedVisitorId: string | null;
688
- location: LocationData | undefined;
689
- };
690
- }) | undefined;
517
+ /**
518
+ * Plugin-attached AuthContext fields. better-auth types AuthContext as a fixed
519
+ * object; prefer {@link createAuthMiddleware} for hooks, {@link asInfraContext}
520
+ * for database hooks / getCurrentAuthContext.
521
+ */
522
+ type InfraAuthContext = GenericEndpointContext["context"] & {
523
+ identification?: Identification | null;
524
+ visitorId: string | null;
525
+ requestId: string | null;
526
+ ip: string | null;
527
+ untrustedVisitorId: string | null;
528
+ location: LocationData | undefined;
529
+ infraRidCookieSet?: boolean;
530
+ freeTrialReservationId?: string;
531
+ returned?: unknown;
532
+ payload?: unknown;
533
+ };
534
+ type InfraEndpointContextValue = Omit<GenericEndpointContext, "context"> & {
535
+ context: InfraAuthContext;
536
+ };
537
+ type InfraEndpointContext = InfraEndpointContextValue | undefined;
538
+ /** Type-only cast — does not wrap or mutate ctx. */
539
+ declare function asInfraContext<T extends {
540
+ context: object;
541
+ }>(ctx: T): Omit<T, "context"> & {
542
+ context: InfraAuthContext;
543
+ };
544
+ /**
545
+ * better-auth createAuthMiddleware with InfraAuthContext on `ctx.context`.
546
+ * Pass-through at runtime — type-only (does not wrap the handler).
547
+ *
548
+ * Prefer this for dash/sentinel/identification hooks. Keep better-auth's
549
+ * createAuthMiddleware where middleware return values must extend AuthContext
550
+ * (e.g. JWT `payload` via `use: [...]`).
551
+ */
552
+ declare const createAuthMiddleware$1: {
553
+ <R>(handler: (ctx: InfraEndpointContextValue) => R | Promise<R>): ReturnType<typeof createAuthMiddleware>;
554
+ <Options extends Record<string, unknown>, R>(options: Options, handler: (ctx: InfraEndpointContextValue) => R | Promise<R>): ReturnType<typeof createAuthMiddleware>;
555
+ };
691
556
  //#endregion
692
- export { ImpossibleTravelResult as C, SecurityVerdict as D, SecurityOptions as E, StaleUserResult as O, CredentialStuffingResult as S, SecurityEventType as T, LocationDataContext as _, DashOptionsInternal as a, sentinel as b, EndpointOptions as c, InfraPluginConnectionOptionsInternal as d, KvOptions as f, LocationData as g, KvRetryOptionsResolved as h, DashOptions as i, ThresholdConfig as k, InfraEndpointContext as l, KvRetryOptions as m, ApiOptions as n, DashOptionsResolved as o, KvOptionsResolved as p, ApiOptionsResolved as r, Endpoint as s, APIError$1 as t, InfraPluginConnectionOptions as u, SentinelOptions as v, SecurityEvent as w, CompromisedPasswordResult as x, SentinelOptionsInternal as y };
557
+ export { SecurityOptions as A, createAuthMiddleware$1 as C, ImpossibleTravelResult as D, CredentialStuffingResult as E, StaleUserResult as M, ThresholdConfig as N, SecurityEvent as O, asInfraContext as S, CompromisedPasswordResult as T, KvRetryOptionsResolved as _, DashOptionsInternal as a, SentinelOptions as b, EndpointOptions as c, InfraEndpointContextValue as d, InfraPluginConnectionOptions as f, KvRetryOptions as g, KvOptionsResolved as h, DashOptions as i, SecurityVerdict as j, SecurityEventType as k, InfraAuthContext as l, KvOptions as m, ApiOptions as n, DashOptionsResolved as o, InfraPluginConnectionOptionsInternal as p, ApiOptionsResolved as r, Endpoint as s, APIError$2 as t, InfraEndpointContext as u, LocationData as v, sentinel as w, SentinelOptionsInternal as x, LocationDataContext as y };