@better-auth/infra 0.4.7 → 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/CHANGELOG.md +6 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +2 -2
- package/dist/{constants-BypXAAvQ.mjs → constants-C8_UJzzu.mjs} +1 -1
- package/dist/{crypto-C9Iqqv8l.mjs → crypto-DRS7yhmR.mjs} +11 -8
- package/dist/email.d.mts +5 -0
- package/dist/email.mjs +4 -3
- package/dist/{identify-client-options-Be9mAljS.d.mts → identify-client-options-DgKA4Eq8.d.mts} +1 -1
- package/dist/index.d.mts +170 -165
- package/dist/index.mjs +55 -28
- package/dist/native.d.mts +1 -1
- package/dist/native.mjs +2 -2
- package/dist/{pow-retry-Bk5otjQT.mjs → pow-retry-Di0eUKbA.mjs} +1 -1
- package/dist/{types-Ba7NK8JV.d.mts → types-BkUWsMpe.d.mts} +67 -196
- package/package.json +18 -10
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-
|
|
2
|
-
import { a as createAPI, n as hash$1, o as createKV, r as hmacSha256Hex } from "./crypto-
|
|
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: {
|
|
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;
|
|
@@ -2582,8 +2603,9 @@ const sentinel = (options) => {
|
|
|
2582
2603
|
databaseHooks: {
|
|
2583
2604
|
user: {
|
|
2584
2605
|
create: {
|
|
2585
|
-
async before(user,
|
|
2586
|
-
if (!
|
|
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,
|
|
2621
|
-
if (!
|
|
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,
|
|
2637
|
-
if (!
|
|
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,
|
|
2670
|
-
if (!
|
|
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,
|
|
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 (
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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 {
|
|
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$
|
|
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;
|
|
@@ -193,7 +194,7 @@ declare const sentinel: (options?: SentinelOptions) => {
|
|
|
193
194
|
emailVerified: boolean;
|
|
194
195
|
name: string;
|
|
195
196
|
image?: string | null | undefined;
|
|
196
|
-
} & Record<string, unknown>,
|
|
197
|
+
} & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<{
|
|
197
198
|
data: {
|
|
198
199
|
email: string;
|
|
199
200
|
id: string;
|
|
@@ -212,7 +213,7 @@ declare const sentinel: (options?: SentinelOptions) => {
|
|
|
212
213
|
emailVerified: boolean;
|
|
213
214
|
name: string;
|
|
214
215
|
image?: string | null | undefined;
|
|
215
|
-
} & Record<string, unknown>,
|
|
216
|
+
} & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
|
|
216
217
|
};
|
|
217
218
|
update: {
|
|
218
219
|
before(user: Partial<{
|
|
@@ -247,7 +248,7 @@ declare const sentinel: (options?: SentinelOptions) => {
|
|
|
247
248
|
token: string;
|
|
248
249
|
ipAddress?: string | null | undefined;
|
|
249
250
|
userAgent?: string | null | undefined;
|
|
250
|
-
} & Record<string, unknown>,
|
|
251
|
+
} & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
|
|
251
252
|
after(session: {
|
|
252
253
|
id: string;
|
|
253
254
|
createdAt: Date;
|
|
@@ -257,7 +258,7 @@ declare const sentinel: (options?: SentinelOptions) => {
|
|
|
257
258
|
token: string;
|
|
258
259
|
ipAddress?: string | null | undefined;
|
|
259
260
|
userAgent?: string | null | undefined;
|
|
260
|
-
} & Record<string, unknown>,
|
|
261
|
+
} & Record<string, unknown>, _ctx: import("better-auth").GenericEndpointContext | null): Promise<void>;
|
|
261
262
|
};
|
|
262
263
|
};
|
|
263
264
|
};
|
|
@@ -273,186 +274,13 @@ declare const sentinel: (options?: SentinelOptions) => {
|
|
|
273
274
|
};
|
|
274
275
|
};
|
|
275
276
|
hooks: {
|
|
276
|
-
before:
|
|
277
|
-
matcher: (context:
|
|
278
|
-
handler:
|
|
279
|
-
|
|
280
|
-
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
281
|
-
path: string;
|
|
282
|
-
body: any;
|
|
283
|
-
query: Record<string, any> | undefined;
|
|
284
|
-
params: Record<string, any> & string;
|
|
285
|
-
request: Request | undefined;
|
|
286
|
-
headers: Headers | undefined;
|
|
287
|
-
setHeader: ((key: string, value: string) => void) & ((key: string, value: string) => void);
|
|
288
|
-
setStatus: (status: import("better-call").Status) => void;
|
|
289
|
-
getHeader: ((key: string) => string | null) & ((key: string) => string | null);
|
|
290
|
-
getCookie: (key: string, prefix?: import("better-call").CookiePrefixOptions) => string | null;
|
|
291
|
-
getSignedCookie: (key: string, secret: string, prefix?: import("better-call").CookiePrefixOptions) => Promise<string | null | false>;
|
|
292
|
-
setCookie: (key: string, value: string, options?: import("better-call").CookieOptions) => string;
|
|
293
|
-
setSignedCookie: (key: string, value: string, secret: string, options?: import("better-call").CookieOptions) => Promise<string>;
|
|
294
|
-
responseHeaders: Headers;
|
|
295
|
-
json: (<R extends Record<string, any> | null>(json: R, routerResponse?: {
|
|
296
|
-
status?: number;
|
|
297
|
-
headers?: Record<string, string>;
|
|
298
|
-
response?: Response;
|
|
299
|
-
body?: Record<string, string>;
|
|
300
|
-
} | Response) => Promise<R>) & (<R extends Record<string, any> | null>(json: R, routerResponse?: {
|
|
301
|
-
status?: number;
|
|
302
|
-
headers?: Record<string, string>;
|
|
303
|
-
response?: Response;
|
|
304
|
-
} | Response) => Promise<R>);
|
|
305
|
-
context: {
|
|
306
|
-
[x: string]: any;
|
|
307
|
-
} & {
|
|
308
|
-
returned?: unknown | undefined;
|
|
309
|
-
responseHeaders?: Headers | undefined;
|
|
310
|
-
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 {
|
|
311
|
-
creator: infer C;
|
|
312
|
-
} ? C extends ((...args: any[]) => infer R) ? R : never : never : BetterAuthPlugin) | null;
|
|
313
|
-
hasPlugin: <ID extends import("better-auth").BetterAuthPluginRegistryIdentifier | import("better-auth").LiteralString>(pluginId: ID) => ID extends never ? true : boolean;
|
|
314
|
-
appName: string;
|
|
315
|
-
baseURL: string;
|
|
316
|
-
version: string;
|
|
317
|
-
options: import("better-auth").BetterAuthOptions;
|
|
318
|
-
trustedOrigins: string[];
|
|
319
|
-
trustedProviders: string[];
|
|
320
|
-
isTrustedOrigin: (url: string, settings?: {
|
|
321
|
-
allowRelativePaths: boolean;
|
|
322
|
-
}) => boolean;
|
|
323
|
-
oauthConfig: {
|
|
324
|
-
skipStateCookieCheck?: boolean | undefined;
|
|
325
|
-
storeStateStrategy: "database" | "cookie";
|
|
326
|
-
};
|
|
327
|
-
newSession: {
|
|
328
|
-
session: {
|
|
329
|
-
id: string;
|
|
330
|
-
createdAt: Date;
|
|
331
|
-
updatedAt: Date;
|
|
332
|
-
userId: string;
|
|
333
|
-
expiresAt: Date;
|
|
334
|
-
token: string;
|
|
335
|
-
ipAddress?: string | null | undefined;
|
|
336
|
-
userAgent?: string | null | undefined;
|
|
337
|
-
} & Record<string, any>;
|
|
338
|
-
user: {
|
|
339
|
-
id: string;
|
|
340
|
-
createdAt: Date;
|
|
341
|
-
updatedAt: Date;
|
|
342
|
-
email: string;
|
|
343
|
-
emailVerified: boolean;
|
|
344
|
-
name: string;
|
|
345
|
-
image?: string | null | undefined;
|
|
346
|
-
} & Record<string, any>;
|
|
347
|
-
} | null;
|
|
348
|
-
session: {
|
|
349
|
-
session: {
|
|
350
|
-
id: string;
|
|
351
|
-
createdAt: Date;
|
|
352
|
-
updatedAt: Date;
|
|
353
|
-
userId: string;
|
|
354
|
-
expiresAt: Date;
|
|
355
|
-
token: string;
|
|
356
|
-
ipAddress?: string | null | undefined;
|
|
357
|
-
userAgent?: string | null | undefined;
|
|
358
|
-
} & Record<string, any>;
|
|
359
|
-
user: {
|
|
360
|
-
id: string;
|
|
361
|
-
createdAt: Date;
|
|
362
|
-
updatedAt: Date;
|
|
363
|
-
email: string;
|
|
364
|
-
emailVerified: boolean;
|
|
365
|
-
name: string;
|
|
366
|
-
image?: string | null | undefined;
|
|
367
|
-
} & Record<string, any>;
|
|
368
|
-
} | null;
|
|
369
|
-
setNewSession: (session: {
|
|
370
|
-
session: {
|
|
371
|
-
id: string;
|
|
372
|
-
createdAt: Date;
|
|
373
|
-
updatedAt: Date;
|
|
374
|
-
userId: string;
|
|
375
|
-
expiresAt: Date;
|
|
376
|
-
token: string;
|
|
377
|
-
ipAddress?: string | null | undefined;
|
|
378
|
-
userAgent?: string | null | undefined;
|
|
379
|
-
} & Record<string, any>;
|
|
380
|
-
user: {
|
|
381
|
-
id: string;
|
|
382
|
-
createdAt: Date;
|
|
383
|
-
updatedAt: Date;
|
|
384
|
-
email: string;
|
|
385
|
-
emailVerified: boolean;
|
|
386
|
-
name: string;
|
|
387
|
-
image?: string | null | undefined;
|
|
388
|
-
} & Record<string, any>;
|
|
389
|
-
} | null) => void;
|
|
390
|
-
socialProviders: import("better-auth").OAuthProvider[];
|
|
391
|
-
authCookies: import("better-auth").BetterAuthCookies;
|
|
392
|
-
logger: ReturnType<(options?: import("better-auth").Logger | undefined) => import("better-auth").InternalLogger>;
|
|
393
|
-
rateLimit: {
|
|
394
|
-
enabled: boolean;
|
|
395
|
-
window: number;
|
|
396
|
-
max: number;
|
|
397
|
-
storage: "memory" | "database" | "secondary-storage";
|
|
398
|
-
} & Omit<import("better-auth").BetterAuthRateLimitOptions, "enabled" | "window" | "max" | "storage">;
|
|
399
|
-
adapter: import("better-auth").DBAdapter<import("better-auth").BetterAuthOptions>;
|
|
400
|
-
internalAdapter: import("better-auth").InternalAdapter<import("better-auth").BetterAuthOptions>;
|
|
401
|
-
createAuthCookie: (cookieName: string, overrideAttributes?: Partial<import("better-call").CookieOptions> | undefined) => import("better-auth").BetterAuthCookie;
|
|
402
|
-
secret: string;
|
|
403
|
-
secretConfig: string | import("better-auth").SecretConfig;
|
|
404
|
-
sessionConfig: {
|
|
405
|
-
updateAge: number;
|
|
406
|
-
expiresIn: number;
|
|
407
|
-
freshAge: number;
|
|
408
|
-
cookieRefreshCache: false | {
|
|
409
|
-
enabled: true;
|
|
410
|
-
updateAge: number;
|
|
411
|
-
};
|
|
412
|
-
};
|
|
413
|
-
generateId: (options: {
|
|
414
|
-
model: import("better-auth").ModelNames;
|
|
415
|
-
size?: number | undefined;
|
|
416
|
-
}) => string | false;
|
|
417
|
-
secondaryStorage: import("better-auth").SecondaryStorage | undefined;
|
|
418
|
-
password: {
|
|
419
|
-
hash: (password: string) => Promise<string>;
|
|
420
|
-
verify: (data: {
|
|
421
|
-
password: string;
|
|
422
|
-
hash: string;
|
|
423
|
-
}) => Promise<boolean>;
|
|
424
|
-
config: {
|
|
425
|
-
minPasswordLength: number;
|
|
426
|
-
maxPasswordLength: number;
|
|
427
|
-
};
|
|
428
|
-
checkPassword: (userId: string, ctx: import("better-auth").GenericEndpointContext<import("better-auth").BetterAuthOptions>) => Promise<boolean>;
|
|
429
|
-
};
|
|
430
|
-
tables: import("better-auth").BetterAuthDBSchema;
|
|
431
|
-
runMigrations: () => Promise<void>;
|
|
432
|
-
publishTelemetry: (event: {
|
|
433
|
-
type: string;
|
|
434
|
-
anonymousId?: string | undefined;
|
|
435
|
-
payload: Record<string, any>;
|
|
436
|
-
}) => Promise<void>;
|
|
437
|
-
skipOriginCheck: boolean | string[];
|
|
438
|
-
skipCSRFCheck: boolean;
|
|
439
|
-
runInBackground: (promise: Promise<unknown>) => void;
|
|
440
|
-
runInBackgroundOrAwait: (promise: Promise<unknown> | void) => import("better-auth").Awaitable<unknown>;
|
|
441
|
-
};
|
|
442
|
-
redirect: (url: string) => import("better-call").APIError;
|
|
443
|
-
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?: {
|
|
444
|
-
message?: string;
|
|
445
|
-
code?: string;
|
|
446
|
-
} & Record<string, any>, headers?: HeadersInit) => import("better-call").APIError;
|
|
447
|
-
};
|
|
448
|
-
} | undefined>;
|
|
449
|
-
} | {
|
|
450
|
-
matcher: (ctx: import("better-auth").HookEndpointContext) => boolean;
|
|
451
|
-
handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
|
|
452
|
-
})[];
|
|
277
|
+
before: {
|
|
278
|
+
matcher: (context: import("better-auth").HookEndpointContext) => boolean;
|
|
279
|
+
handler: import("better-auth/api").AuthMiddleware;
|
|
280
|
+
}[];
|
|
453
281
|
after: {
|
|
454
282
|
matcher: (ctx: import("better-auth").HookEndpointContext) => boolean;
|
|
455
|
-
handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<
|
|
283
|
+
handler: import("better-call").Middleware<import("better-call").MiddlewareOptions, (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<unknown>>;
|
|
456
284
|
}[];
|
|
457
285
|
};
|
|
458
286
|
};
|
|
@@ -491,11 +319,19 @@ interface ApiOptions {
|
|
|
491
319
|
* @default 3000
|
|
492
320
|
*/
|
|
493
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>;
|
|
494
327
|
}
|
|
495
328
|
/**
|
|
496
329
|
* Resolved {@link ApiOptions} with defaults applied.
|
|
497
330
|
*/
|
|
498
|
-
type ApiOptionsResolved =
|
|
331
|
+
type ApiOptionsResolved = {
|
|
332
|
+
timeout: number;
|
|
333
|
+
headers?: Record<string, string>;
|
|
334
|
+
};
|
|
499
335
|
/**
|
|
500
336
|
* KV HTTP client options.
|
|
501
337
|
*/
|
|
@@ -510,6 +346,11 @@ interface KvOptions {
|
|
|
510
346
|
* @default { attempts: 2, baseDelay: 400, maxDelay: 600 }
|
|
511
347
|
*/
|
|
512
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>;
|
|
513
354
|
}
|
|
514
355
|
/**
|
|
515
356
|
* Resolved {@link KvOptions} with defaults applied.
|
|
@@ -517,6 +358,7 @@ interface KvOptions {
|
|
|
517
358
|
interface KvOptionsResolved {
|
|
518
359
|
timeout: number;
|
|
519
360
|
retry: KvRetryOptionsResolved;
|
|
361
|
+
headers?: Record<string, string>;
|
|
520
362
|
}
|
|
521
363
|
/**
|
|
522
364
|
* Shared connection options used by infra plugins.
|
|
@@ -672,15 +514,44 @@ interface LocationData {
|
|
|
672
514
|
}
|
|
673
515
|
/** @deprecated Use LocationData instead */
|
|
674
516
|
type LocationDataContext = LocationData;
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
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
|
+
};
|
|
685
556
|
//#endregion
|
|
686
|
-
export {
|
|
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 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/infra",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.8",
|
|
4
4
|
"description": "Dashboard and analytics plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"build": "bun --bun tsdown",
|
|
12
12
|
"dev": "bun --bun tsdown --watch --no-clean",
|
|
13
13
|
"typecheck": "tsc --noEmit",
|
|
14
|
-
"test": "
|
|
15
|
-
"test:watch": "
|
|
16
|
-
"coverage": "
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"coverage": "vitest run --coverage"
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
@@ -66,19 +66,22 @@
|
|
|
66
66
|
},
|
|
67
67
|
"homepage": "https://better-auth.com",
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@better-auth/kysely-adapter": "1.7.
|
|
70
|
-
"@better-auth/scim": "1.7.
|
|
71
|
-
"@better-auth/sso": "1.7.
|
|
69
|
+
"@better-auth/kysely-adapter": "1.7.3",
|
|
70
|
+
"@better-auth/scim": "1.7.3",
|
|
71
|
+
"@better-auth/sso": "1.7.3",
|
|
72
72
|
"@infra/mocks": "0.0.0",
|
|
73
73
|
"@infra/utils": "0.0.0",
|
|
74
74
|
"@types/bun": "latest",
|
|
75
75
|
"@types/node": "^24.12.0",
|
|
76
|
-
"
|
|
76
|
+
"@vitest/browser-playwright": "5.0.0",
|
|
77
|
+
"@vitest/coverage-istanbul": "^5.0.0",
|
|
78
|
+
"better-auth": "1.7.3",
|
|
77
79
|
"expo-crypto": "^57.0.1",
|
|
78
|
-
"happy-dom": "^20.9.0",
|
|
79
80
|
"msw": "^2.14.6",
|
|
81
|
+
"playwright": "^1.63.0",
|
|
80
82
|
"tsdown": "^0.22.14",
|
|
81
83
|
"typescript": "^6.0.3",
|
|
84
|
+
"vitest": "^5.0.0",
|
|
82
85
|
"zod": "4.5.4"
|
|
83
86
|
},
|
|
84
87
|
"dependencies": {
|
|
@@ -86,7 +89,7 @@
|
|
|
86
89
|
"@better-fetch/fetch": "1.3.1",
|
|
87
90
|
"@noble/hashes": "^2.2.0",
|
|
88
91
|
"@xmldom/xmldom": "^0.9.10",
|
|
89
|
-
"better-call": "1.
|
|
92
|
+
"better-call": "1.4.0",
|
|
90
93
|
"jose": "^6.2.10",
|
|
91
94
|
"libphonenumber-js": "^1.13.11"
|
|
92
95
|
},
|
|
@@ -116,5 +119,10 @@
|
|
|
116
119
|
"expo-device": {
|
|
117
120
|
"optional": true
|
|
118
121
|
}
|
|
122
|
+
},
|
|
123
|
+
"msw": {
|
|
124
|
+
"workerDirectory": [
|
|
125
|
+
"public"
|
|
126
|
+
]
|
|
119
127
|
}
|
|
120
128
|
}
|