@better-auth/infra 0.4.0 → 0.4.2

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-CcJHk5SE.mjs";
2
- import { a as createAPI, n as hash$1, o as createKV, r as hmacSha256Hex } from "./crypto-CAdWFWEz.mjs";
1
+ import { i as INFRA_USER_AGENT, n as INFRA_API_URL, o as PLUGIN_VERSION, r as INFRA_KV_URL } from "./constants-CDhjfr8S.mjs";
2
+ import { a as createAPI, n as hash$1, o as createKV, r as hmacSha256Hex } from "./crypto-D3yZH0Cy.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";
@@ -7,8 +7,11 @@ import { env } from "@better-auth/core/env";
7
7
  import { APIError as APIError$1, createAuthEndpoint, createAuthMiddleware, requestPasswordReset, sendVerificationEmailFn, sessionMiddleware } from "better-auth/api";
8
8
  import { deleteSessionCookie, setSessionCookie } from "better-auth/cookies";
9
9
  import { createFetch } from "@better-fetch/fetch";
10
+ import { sha256 } from "@noble/hashes/sha2.js";
10
11
  import { isValidPhoneNumber, parsePhoneNumberFromString } from "libphonenumber-js";
11
- import z$1, { z } from "zod";
12
+ import z, { z as z$1 } from "zod";
13
+ import { DOMParser } from "@xmldom/xmldom";
14
+ import { base64Url } from "@better-auth/utils/base64";
12
15
  import { createLocalJWKSet, jwtVerify } from "jose";
13
16
  import { generateRandomString, symmetricEncrypt } from "better-auth/crypto";
14
17
  import { createOTP } from "@better-auth/utils/otp";
@@ -313,7 +316,8 @@ function tryDecode(value) {
313
316
  const stripQuery = (value) => value.split("?")[0] || value;
314
317
  const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
315
318
  const routeToRegex = (route) => {
316
- const pattern = escapeRegex(stripQuery(route)).replace(/\/:([^/]+)/g, "/[^/]+");
319
+ const normalized = stripQuery(route);
320
+ const pattern = escapeRegex(normalized).replace(/\/:([^/]+)/g, "/[^/]+");
317
321
  return new RegExp(`^${pattern}(?:$|[/?])`);
318
322
  };
319
323
  const matchesAnyRoute = (path, routes) => {
@@ -373,6 +377,33 @@ function createLocalAccountIssuer(providerId) {
373
377
  function createOAuthAccountIssuer(providerId) {
374
378
  return `local:oauth:${encodeURIComponent(providerId)}`;
375
379
  }
380
+ /** Configured strategy when set; `null` when omitted (pre-option or default). */
381
+ function getConfiguredAccountIdentityStrategy(account) {
382
+ const strategy = account?.identityStrategy;
383
+ if (strategy === "provider-id" || strategy === "issuer") return strategy;
384
+ return null;
385
+ }
386
+ /**
387
+ * Effective strategy for account-key derivation.
388
+ * Matches better-auth: omit/`"issuer"` → issuer-scoped; `"provider-id"` → provider-scoped.
389
+ */
390
+ function resolveAccountIdentityStrategy(account) {
391
+ return getConfiguredAccountIdentityStrategy(account) ?? "issuer";
392
+ }
393
+ /**
394
+ * Resolves the OAuth account issuer the same way better-auth does under
395
+ * `account.identityStrategy`, including provider-scoped compatibility mode.
396
+ */
397
+ async function resolveOAuthAccountIssuer(params) {
398
+ if (params.identityStrategy === "provider-id") return createOAuthAccountIssuer(params.providerId);
399
+ const { accountIssuer } = params;
400
+ if (typeof accountIssuer === "function") {
401
+ const issuer = await accountIssuer(params.context);
402
+ return typeof issuer === "string" && issuer.trim().length > 0 ? issuer : void 0;
403
+ }
404
+ if (typeof accountIssuer === "string" && accountIssuer.trim().length > 0) return accountIssuer;
405
+ return createOAuthAccountIssuer(params.providerId);
406
+ }
376
407
  /** True when the installed better-auth build scopes accounts by issuer. */
377
408
  function supportsIssuerScopedAccounts(adapter) {
378
409
  return typeof adapter.findAccountByKey === "function";
@@ -407,7 +438,7 @@ function normalizeProviderSubject(subject) {
407
438
  if (!subject || subject === "undefined" || subject === "null") return;
408
439
  return subject;
409
440
  }
410
- async function resolveAccountKey(provider, tokens, profile) {
441
+ async function resolveAccountKey(provider, tokens, profile, identityStrategy) {
411
442
  const keyedProvider = provider;
412
443
  const context = {
413
444
  tokens,
@@ -423,7 +454,12 @@ async function resolveAccountKey(provider, tokens, profile) {
423
454
  }
424
455
  const accountId = rawSubject ? normalizeProviderSubject(rawSubject) : void 0;
425
456
  if (!accountId) return void 0;
426
- const issuer = typeof keyedProvider.accountIssuer === "function" ? await keyedProvider.accountIssuer(context) : keyedProvider.accountIssuer ?? createOAuthAccountIssuer(provider.id);
457
+ const issuer = await resolveOAuthAccountIssuer({
458
+ providerId: provider.id,
459
+ identityStrategy,
460
+ accountIssuer: keyedProvider.accountIssuer,
461
+ context
462
+ });
427
463
  if (!issuer) return void 0;
428
464
  return {
429
465
  issuer,
@@ -446,7 +482,8 @@ function instrumentSocialProviders(providers) {
446
482
  if (user) try {
447
483
  const endpointCtx = await getCurrentAuthContext();
448
484
  const adapter = endpointCtx.context.internalAdapter;
449
- const accountKey = result.data && typeof adapter.findAccountOwnerByKey === "function" ? await resolveAccountKey(provider, token, result.data) : void 0;
485
+ const identityStrategy = resolveAccountIdentityStrategy(endpointCtx.context.options.account);
486
+ const accountKey = result.data && typeof adapter.findAccountOwnerByKey === "function" ? await resolveAccountKey(provider, token, result.data, identityStrategy) : void 0;
450
487
  endpointCtx.context[OAUTH_CALLBACK_USER] = {
451
488
  user,
452
489
  accountKey
@@ -1052,6 +1089,49 @@ function resolveClientIpFromHeaders(headers, ipAddressHeaders) {
1052
1089
  * when a request includes an X-Request-Id header.
1053
1090
  */
1054
1091
  const IDENTIFICATION_COOKIE_NAME = "__infra-rid";
1092
+ /** GET routes that need identification (OAuth callbacks, verify links, etc.). */
1093
+ const IDENTIFICATION_GET_ROUTES = [
1094
+ routes.SIGN_IN_SOCIAL_CALLBACK,
1095
+ routes.SIGN_IN_OAUTH_CALLBACK,
1096
+ routes.DASH_IMPERSONATE_USER,
1097
+ routes.VERIFY_EMAIL,
1098
+ routes.MAGIC_LINK_VERIFY,
1099
+ routes.DASH_ACCEPT_INVITATION,
1100
+ routes.DASH_COMPLETE_INVITATION_SOCIAL
1101
+ ];
1102
+ /** GET OAuth callbacks where user creation can run without identify headers. */
1103
+ const IDENTIFICATION_OAUTH_CALLBACK_GET_ROUTES = [routes.SIGN_IN_SOCIAL_CALLBACK, routes.SIGN_IN_OAUTH_CALLBACK];
1104
+ /**
1105
+ * Whether identification middleware should run for this request.
1106
+ * Non-GET always runs; GET only for routes that need cookie/KV resolution.
1107
+ */
1108
+ function shouldRunIdentification(ctx, getRoutes = IDENTIFICATION_GET_ROUTES) {
1109
+ if (ctx.request?.method !== "GET") return true;
1110
+ return matchesAnyRoute(ctx.path, [...getRoutes]);
1111
+ }
1112
+ /**
1113
+ * Persist `X-Request-Id` as `__infra-rid` so redirect-flow OAuth callbacks
1114
+ * (GET, no identify headers) can resolve visitor identification from KV.
1115
+ * Must run in an after hook so Set-Cookie reaches the response.
1116
+ */
1117
+ function createIdentificationCookieAfterMiddleware() {
1118
+ return createAuthMiddleware(async (ctx) => {
1119
+ const headerRequestId = ctx.request?.headers.get("X-Request-Id");
1120
+ if (headerRequestId) {
1121
+ ctx.setCookie(IDENTIFICATION_COOKIE_NAME, headerRequestId, {
1122
+ maxAge: 600,
1123
+ sameSite: "lax",
1124
+ httpOnly: true,
1125
+ path: "/"
1126
+ });
1127
+ return;
1128
+ }
1129
+ if (ctx.context.requestId) ctx.setCookie(IDENTIFICATION_COOKIE_NAME, "", {
1130
+ maxAge: 0,
1131
+ path: "/"
1132
+ });
1133
+ });
1134
+ }
1055
1135
  const identificationCache = /* @__PURE__ */ new Map();
1056
1136
  const CACHE_TTL_MS = 6e4;
1057
1137
  const CACHE_MAX_SIZE = 1e3;
@@ -1296,8 +1376,9 @@ function isEmailNormalizationEnabled(security) {
1296
1376
  * @param $api — Dash client from `createAPI(opts, { throw: true })`.
1297
1377
  */
1298
1378
  function createSecurityClient(conn, $api, options, onSecurityEvent) {
1379
+ const resolvedApiUrl = conn.apiUrl || INFRA_API_URL;
1299
1380
  const emailSender = createEmailSender({
1300
- apiUrl: conn.apiUrl || INFRA_API_URL,
1381
+ apiUrl: resolvedApiUrl,
1301
1382
  apiKey: conn.apiKey
1302
1383
  });
1303
1384
  function logEvent(event) {
@@ -1741,7 +1822,7 @@ const authPaths = [
1741
1822
  "/email-otp/send-verification-otp"
1742
1823
  ];
1743
1824
  const registration = new Set(registrationPaths);
1744
- const all = new Set([...registrationPaths, ...authPaths]);
1825
+ const all = /* @__PURE__ */ new Set([...registrationPaths, ...authPaths]);
1745
1826
  /** Path carries an email we hook for normalization + syntax validation. */
1746
1827
  const allEmail = ({ path }) => !!path && all.has(path);
1747
1828
  /**
@@ -1754,11 +1835,11 @@ const registrationEmail = ({ path }) => !!path && registration.has(path);
1754
1835
  /**
1755
1836
  * Gmail-like providers that ignore dots in the local part
1756
1837
  */
1757
- const GMAIL_LIKE_DOMAINS = new Set(["gmail.com", "googlemail.com"]);
1838
+ const GMAIL_LIKE_DOMAINS = /* @__PURE__ */ new Set(["gmail.com", "googlemail.com"]);
1758
1839
  /**
1759
1840
  * Providers known to support plus addressing
1760
1841
  */
1761
- const PLUS_ADDRESSING_DOMAINS = new Set([
1842
+ const PLUS_ADDRESSING_DOMAINS = /* @__PURE__ */ new Set([
1762
1843
  "gmail.com",
1763
1844
  "googlemail.com",
1764
1845
  "outlook.com",
@@ -2028,7 +2109,7 @@ function createEmailHooks(options = {}) {
2028
2109
  * Common fake/test phone numbers that should be blocked
2029
2110
  * These are numbers commonly used in testing, movies, documentation, etc.
2030
2111
  */
2031
- const INVALID_PHONE_NUMBERS = new Set([
2112
+ const INVALID_PHONE_NUMBERS = /* @__PURE__ */ new Set([
2032
2113
  "+15550000000",
2033
2114
  "+15550001111",
2034
2115
  "+15550001234",
@@ -2117,7 +2198,7 @@ const INVALID_PHONE_PATTERNS = [
2117
2198
  * Key: country code, Value: set of invalid prefixes
2118
2199
  */
2119
2200
  const INVALID_PREFIXES_BY_COUNTRY = {
2120
- US: new Set([
2201
+ US: /* @__PURE__ */ new Set([
2121
2202
  "555",
2122
2203
  "000",
2123
2204
  "111",
@@ -2125,17 +2206,17 @@ const INVALID_PREFIXES_BY_COUNTRY = {
2125
2206
  "411",
2126
2207
  "611"
2127
2208
  ]),
2128
- CA: new Set([
2209
+ CA: /* @__PURE__ */ new Set([
2129
2210
  "555",
2130
2211
  "000",
2131
2212
  "911"
2132
2213
  ]),
2133
- GB: new Set([
2214
+ GB: /* @__PURE__ */ new Set([
2134
2215
  "7700900",
2135
2216
  "1632960",
2136
2217
  "1134960"
2137
2218
  ]),
2138
- AU: new Set([
2219
+ AU: /* @__PURE__ */ new Set([
2139
2220
  "0491570",
2140
2221
  "0491571",
2141
2222
  "0491572"
@@ -2205,7 +2286,7 @@ const validatePhone = (phone, options = {}) => {
2205
2286
  if (blockVoip && phoneType === "VOIP") return false;
2206
2287
  return true;
2207
2288
  };
2208
- const allPhonePaths = new Set([
2289
+ const allPhonePaths = /* @__PURE__ */ new Set([
2209
2290
  "/phone-number/send-otp",
2210
2291
  "/phone-number/verify",
2211
2292
  "/sign-in/phone-number",
@@ -2463,7 +2544,7 @@ const sentinel = (options) => {
2463
2544
  hooks: {
2464
2545
  before: [
2465
2546
  {
2466
- matcher: (ctx) => ctx.request?.method !== "GET",
2547
+ matcher: (ctx) => shouldRunIdentification(ctx, IDENTIFICATION_OAUTH_CALLBACK_GET_ROUTES),
2467
2548
  handler: createIdentificationMiddleware($kv, {
2468
2549
  skipIdentification: (ctx) => isDashRoute(ctx.path),
2469
2550
  retry: opts.kvOptions.retry
@@ -2565,74 +2646,81 @@ const sentinel = (options) => {
2565
2646
  })
2566
2647
  }
2567
2648
  ],
2568
- after: [{
2569
- matcher: (ctx) => !!opts.security?.staleUsers?.enabled && !isDashRoute(ctx.path),
2570
- handler: createAuthMiddleware(async (ctx) => {
2571
- if (ctx.context.returned instanceof Error) return;
2572
- const created = ctx.context.newSession;
2573
- const userId = created?.user?.id ?? created?.session?.userId;
2574
- const sessionToken = created?.session?.token;
2575
- if (!userId || !sessionToken) return;
2576
- let user = created?.user ?? null;
2577
- try {
2578
- user = await getUserById(userId, ctx, { includeLastActiveAt: activityTrackingEnabled }) ?? user;
2579
- } catch (error) {
2580
- logger.warn("[Sentinel] Failed to fetch user for stale-account check:", error);
2649
+ after: [
2650
+ {
2651
+ matcher: (ctx) => shouldRunIdentification(ctx, IDENTIFICATION_OAUTH_CALLBACK_GET_ROUTES),
2652
+ handler: createIdentificationCookieAfterMiddleware()
2653
+ },
2654
+ {
2655
+ matcher: (ctx) => !!opts.security?.staleUsers?.enabled && !isDashRoute(ctx.path),
2656
+ handler: createAuthMiddleware(async (ctx) => {
2657
+ if (ctx.context.returned instanceof Error) return;
2658
+ const created = ctx.context.newSession;
2659
+ const userId = created?.user?.id ?? created?.session?.userId;
2660
+ const sessionToken = created?.session?.token;
2661
+ if (!userId || !sessionToken) return;
2662
+ let user = created?.user ?? null;
2663
+ try {
2664
+ user = await getUserById(userId, ctx, { includeLastActiveAt: activityTrackingEnabled }) ?? user;
2665
+ } catch (error) {
2666
+ logger.warn("[Sentinel] Failed to fetch user for stale-account check:", error);
2667
+ if (!user) return;
2668
+ }
2581
2669
  if (!user) return;
2582
- }
2583
- if (!user) return;
2584
- recordCheck(ctx, "stale_users");
2585
- const staleCheck = await securityService.checkStaleUser(userId, activityTrackingEnabled ? user.lastActiveAt ?? null : null);
2586
- if (!staleCheck.isStale) return;
2587
- const identification = ctx.context.identification;
2588
- const staleOpts = opts.security?.staleUsers;
2589
- const notificationPromises = [];
2590
- if (staleCheck.notifyUser && user.email) notificationPromises.push(securityService.notifyStaleAccountUser(user.email, user.name || null, staleCheck.daysSinceLastActive || 0, identification));
2591
- if (staleCheck.notifyAdmin && staleOpts?.adminEmail) notificationPromises.push(securityService.notifyStaleAccountAdmin(staleOpts.adminEmail, userId, user.email || "unknown", user.name || null, staleCheck.daysSinceLastActive || 0, identification));
2592
- if (notificationPromises.length > 0) Promise.all(notificationPromises).catch((error) => {
2593
- logger.error("[Sentinel] Failed to send stale account notifications:", error);
2594
- });
2595
- if (staleCheck.action !== "block") return;
2596
- setOutcome(ctx, "blocked", "stale_users", {
2597
- userId,
2598
- daysSinceLastActive: staleCheck.daysSinceLastActive,
2599
- staleDays: staleCheck.staleDays,
2600
- lastActiveAt: staleCheck.lastActiveAt,
2601
- notifyUser: staleCheck.notifyUser,
2602
- notifyAdmin: staleCheck.notifyAdmin
2603
- });
2604
- emitEvaluation(ctx, trackEvent);
2605
- try {
2606
- await ctx.context.internalAdapter.deleteSession(sessionToken);
2607
- } catch (error) {
2608
- logger.warn("[Sentinel] Failed to delete stale-blocked session:", error);
2609
- }
2610
- deleteSessionCookie(ctx);
2611
- ctx.context.setNewSession(null);
2612
- throw new APIError("FORBIDDEN", STALE_ACCOUNT_BLOCK_ERROR);
2613
- })
2614
- }, {
2615
- matcher: (ctx) => ctx.request?.method !== "GET" && !isDashRoute(ctx.path),
2616
- handler: createAuthMiddleware(async (ctx) => {
2617
- const untrustedVisitorId = ctx.context.untrustedVisitorId;
2618
- const ip = ctx.context.ip;
2619
- const body = ctx.body;
2620
- const loginId = matchesAnyRoute(ctx.path, [routes.SIGN_IN_USERNAME]) ? body?.username : body?.email;
2621
- const isPasswordSignInRoute = matchesAnyRoute(ctx.path, [
2622
- routes.SIGN_IN_EMAIL,
2623
- routes.SIGN_IN_USERNAME,
2624
- routes.SIGN_IN_EMAIL_OTP
2625
- ]);
2626
- emitEvaluation(ctx, trackEvent, {
2627
- identifier: loginId,
2628
- userAgent: ctx.headers?.get?.("user-agent") || ""
2629
- });
2630
- const returned = ctx.context.returned;
2631
- const staleBlocked = isStaleAccountError(returned);
2632
- if (isPasswordSignInRoute && returned instanceof Error && !staleBlocked && loginId && body?.password && untrustedVisitorId) await ctx.context.runInBackgroundOrAwait(securityService.trackFailedAttempt(loginId, untrustedVisitorId, body.password, ip, ctx.context.requestId ?? null));
2633
- if (isPasswordSignInRoute && (!(returned instanceof Error) || staleBlocked) && loginId) await ctx.context.runInBackgroundOrAwait(securityService.clearFailedAttempts(loginId));
2634
- })
2635
- }]
2670
+ recordCheck(ctx, "stale_users");
2671
+ const staleCheck = await securityService.checkStaleUser(userId, activityTrackingEnabled ? user.lastActiveAt ?? null : null);
2672
+ if (!staleCheck.isStale) return;
2673
+ const identification = ctx.context.identification;
2674
+ const staleOpts = opts.security?.staleUsers;
2675
+ const notificationPromises = [];
2676
+ if (staleCheck.notifyUser && user.email) notificationPromises.push(securityService.notifyStaleAccountUser(user.email, user.name || null, staleCheck.daysSinceLastActive || 0, identification));
2677
+ if (staleCheck.notifyAdmin && staleOpts?.adminEmail) notificationPromises.push(securityService.notifyStaleAccountAdmin(staleOpts.adminEmail, userId, user.email || "unknown", user.name || null, staleCheck.daysSinceLastActive || 0, identification));
2678
+ if (notificationPromises.length > 0) Promise.all(notificationPromises).catch((error) => {
2679
+ logger.error("[Sentinel] Failed to send stale account notifications:", error);
2680
+ });
2681
+ if (staleCheck.action !== "block") return;
2682
+ setOutcome(ctx, "blocked", "stale_users", {
2683
+ userId,
2684
+ daysSinceLastActive: staleCheck.daysSinceLastActive,
2685
+ staleDays: staleCheck.staleDays,
2686
+ lastActiveAt: staleCheck.lastActiveAt,
2687
+ notifyUser: staleCheck.notifyUser,
2688
+ notifyAdmin: staleCheck.notifyAdmin
2689
+ });
2690
+ emitEvaluation(ctx, trackEvent);
2691
+ try {
2692
+ await ctx.context.internalAdapter.deleteSession(sessionToken);
2693
+ } catch (error) {
2694
+ logger.warn("[Sentinel] Failed to delete stale-blocked session:", error);
2695
+ }
2696
+ deleteSessionCookie(ctx);
2697
+ ctx.context.setNewSession(null);
2698
+ throw new APIError("FORBIDDEN", STALE_ACCOUNT_BLOCK_ERROR);
2699
+ })
2700
+ },
2701
+ {
2702
+ matcher: (ctx) => ctx.request?.method !== "GET" && !isDashRoute(ctx.path),
2703
+ handler: createAuthMiddleware(async (ctx) => {
2704
+ const untrustedVisitorId = ctx.context.untrustedVisitorId;
2705
+ const ip = ctx.context.ip;
2706
+ const body = ctx.body;
2707
+ const loginId = matchesAnyRoute(ctx.path, [routes.SIGN_IN_USERNAME]) ? body?.username : body?.email;
2708
+ const isPasswordSignInRoute = matchesAnyRoute(ctx.path, [
2709
+ routes.SIGN_IN_EMAIL,
2710
+ routes.SIGN_IN_USERNAME,
2711
+ routes.SIGN_IN_EMAIL_OTP
2712
+ ]);
2713
+ emitEvaluation(ctx, trackEvent, {
2714
+ identifier: loginId,
2715
+ userAgent: ctx.headers?.get?.("user-agent") || ""
2716
+ });
2717
+ const returned = ctx.context.returned;
2718
+ const staleBlocked = isStaleAccountError(returned);
2719
+ if (isPasswordSignInRoute && returned instanceof Error && !staleBlocked && loginId && body?.password && untrustedVisitorId) await ctx.context.runInBackgroundOrAwait(securityService.trackFailedAttempt(loginId, untrustedVisitorId, body.password, ip, ctx.context.requestId ?? null));
2720
+ if (isPasswordSignInRoute && (!(returned instanceof Error) || staleBlocked) && loginId) await ctx.context.runInBackgroundOrAwait(securityService.clearFailedAttempts(loginId));
2721
+ })
2722
+ }
2723
+ ]
2636
2724
  }
2637
2725
  };
2638
2726
  };
@@ -2786,45 +2874,131 @@ const ALL_SCIM_SCOPES = [
2786
2874
  "scim.groups.read",
2787
2875
  "scim.groups.write"
2788
2876
  ];
2789
- const scimScopeSchema = z$1.enum(ALL_SCIM_SCOPES);
2877
+ const scimScopeSchema = z.enum(ALL_SCIM_SCOPES);
2790
2878
  const credentialPolicySchema = {
2791
- scopes: z$1.array(scimScopeSchema).min(1).optional(),
2792
- expiresAt: z$1.coerce.date().optional()
2879
+ scopes: z.array(scimScopeSchema).min(1).optional(),
2880
+ expiresAt: z.coerce.date().optional()
2793
2881
  };
2794
- const directorySyncSSOPairingSchema = z$1.discriminatedUnion("protocol", [z$1.object({
2795
- ssoProviderId: z$1.string().trim().min(1).max(255),
2796
- protocol: z$1.literal("oidc"),
2797
- externalIdSource: z$1.discriminatedUnion("kind", [z$1.object({ kind: z$1.literal("subject") }), z$1.object({
2798
- kind: z$1.literal("verifiedIdTokenClaim"),
2799
- name: z$1.string().trim().min(1).max(255)
2882
+ const directorySyncSSOPairingSchema = z.discriminatedUnion("protocol", [z.object({
2883
+ ssoProviderId: z.string().trim().min(1).max(255),
2884
+ protocol: z.literal("oidc"),
2885
+ externalIdSource: z.discriminatedUnion("kind", [z.object({ kind: z.literal("subject") }), z.object({
2886
+ kind: z.literal("verifiedIdTokenClaim"),
2887
+ name: z.string().trim().min(1).max(255)
2800
2888
  })])
2801
- }), z$1.object({
2802
- ssoProviderId: z$1.string().trim().min(1).max(255),
2803
- protocol: z$1.literal("saml"),
2804
- externalIdSource: z$1.discriminatedUnion("kind", [z$1.object({ kind: z$1.literal("nameId") }), z$1.object({
2805
- kind: z$1.literal("attribute"),
2806
- name: z$1.string().trim().min(1).max(255)
2889
+ }), z.object({
2890
+ ssoProviderId: z.string().trim().min(1).max(255),
2891
+ protocol: z.literal("saml"),
2892
+ externalIdSource: z.discriminatedUnion("kind", [z.object({ kind: z.literal("nameId") }), z.object({
2893
+ kind: z.literal("attribute"),
2894
+ name: z.string().trim().min(1).max(255)
2807
2895
  })])
2808
2896
  })]);
2809
- const createDirectoryBodySchema = z$1.object({
2810
- providerId: z$1.string().trim().min(1).max(255),
2897
+ const createDirectoryBodySchema = z.object({
2898
+ providerId: z.string().trim().min(1).max(255),
2811
2899
  pairing: directorySyncSSOPairingSchema.optional(),
2812
2900
  ...credentialPolicySchema
2813
2901
  });
2814
- const rotateCredentialBodySchema = z$1.object(credentialPolicySchema);
2815
- const emptyBodySchema = z$1.object({});
2902
+ const rotateCredentialBodySchema = z.object(credentialPolicySchema);
2903
+ const emptyBodySchema = z.object({});
2816
2904
  function setCredentialResponseSecurityHeaders(ctx) {
2817
2905
  ctx.setHeader("Cache-Control", "no-store, max-age=0");
2818
2906
  ctx.setHeader("Pragma", "no-cache");
2819
2907
  ctx.setHeader("Referrer-Policy", "no-referrer");
2820
2908
  }
2821
2909
  //#endregion
2822
- //#region src/directory-sync/pairing.ts
2823
- let samlPolicyModule;
2824
- function loadSAMLPolicy() {
2825
- samlPolicyModule ??= import("./saml-policy-BTVLoTyS.mjs");
2826
- return samlPolicyModule;
2910
+ //#region src/directory-sync/saml-policy.ts
2911
+ /**
2912
+ * Aligned with `@better-auth/sso` SAML metadata constants / helpers.
2913
+ * @see better-auth packages/sso parseSAMLServiceProviderMetadata
2914
+ */
2915
+ const SAML_METADATA_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:metadata";
2916
+ const HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
2917
+ /**
2918
+ * Whether a SAML provider config requires signed assertions.
2919
+ *
2920
+ * Matches `@better-auth/sso` `deriveSAMLServiceProviderPolicy(...).wantAssertionsSigned`.
2921
+ * Invalid or unusable custom SP metadata throws (pairing maps this to BAD_REQUEST).
2922
+ */
2923
+ function requiresSignedSAMLAssertions(config) {
2924
+ const metadata = config.spMetadata?.metadata;
2925
+ if (!metadata) return config.wantAssertionsSigned === true;
2926
+ const parsedMetadata = parseSAMLServiceProviderMetadata(metadata);
2927
+ if (!parsedMetadata.postAssertionConsumerServiceUrls.length) throw new Error("Unusable SAML service provider metadata");
2928
+ return parsedMetadata.wantAssertionsSigned;
2929
+ }
2930
+ /**
2931
+ * Parses the security- and identity-relevant parts of SAML service-provider
2932
+ * metadata without relying on local-name-only XML matching.
2933
+ *
2934
+ * Port of `@better-auth/sso` `parseSAMLServiceProviderMetadata`.
2935
+ */
2936
+ function parseSAMLServiceProviderMetadata(metadata) {
2937
+ const document = new DOMParser({ onError: (_level, message) => {
2938
+ throw new Error(message);
2939
+ } }).parseFromString(metadata, "text/xml");
2940
+ const entityDescriptor = document.documentElement;
2941
+ if (!entityDescriptor || entityDescriptor.localName !== "EntityDescriptor" || entityDescriptor.namespaceURI !== SAML_METADATA_NAMESPACE) throw new Error("Invalid SAML EntityDescriptor");
2942
+ const entityID = entityDescriptor.getAttribute("entityID")?.trim();
2943
+ if (!entityID) throw new Error("Missing SAML entityID");
2944
+ const serviceProviderDescriptors = directMetadataChildren(entityDescriptor, "SPSSODescriptor");
2945
+ if (serviceProviderDescriptors.length === 0) throw new Error("SAML metadata must contain an SPSSODescriptor");
2946
+ const acceptedServiceProviderDescriptors = new Set(serviceProviderDescriptors);
2947
+ for (const element of Array.from(document.getElementsByTagName("*"))) {
2948
+ if (element.localName === "EntityDescriptor" && element !== entityDescriptor) throw new Error("Invalid nested SAML EntityDescriptor");
2949
+ if (element.localName === "SPSSODescriptor" && !acceptedServiceProviderDescriptors.has(element)) throw new Error("Invalid SAML SPSSODescriptor namespace or position");
2950
+ if ((element.localName === "AssertionConsumerService" || element.localName === "NameIDFormat") && (element.namespaceURI !== SAML_METADATA_NAMESPACE || !element.parentNode || !isElement(element.parentNode) || !acceptedServiceProviderDescriptors.has(element.parentNode))) throw new Error(`Invalid SAML ${element.localName} namespace or position`);
2951
+ }
2952
+ const postAssertionConsumerServiceUrls = [];
2953
+ const nameIDFormats = [];
2954
+ let wantAssertionsSigned = false;
2955
+ for (const descriptor of serviceProviderDescriptors) {
2956
+ wantAssertionsSigned = parseXMLSchemaBoolean(descriptor.getAttribute("WantAssertionsSigned")) || wantAssertionsSigned;
2957
+ for (const nameIDFormat of directMetadataChildren(descriptor, "NameIDFormat")) {
2958
+ const value = nameIDFormat.textContent?.trim();
2959
+ if (value) nameIDFormats.push(value);
2960
+ }
2961
+ for (const service of directMetadataChildren(descriptor, "AssertionConsumerService")) {
2962
+ if (service.getAttribute("Binding") !== HTTP_POST_BINDING) continue;
2963
+ const location = service.getAttribute("Location")?.trim();
2964
+ if (!location || !isAbsoluteHttpUrl(location)) throw new Error("Invalid SAML POST AssertionConsumerService");
2965
+ postAssertionConsumerServiceUrls.push(location);
2966
+ }
2967
+ }
2968
+ return {
2969
+ entityID,
2970
+ nameIDFormats: [...new Set(nameIDFormats)],
2971
+ postAssertionConsumerServiceUrls: [...new Set(postAssertionConsumerServiceUrls)],
2972
+ wantAssertionsSigned
2973
+ };
2974
+ }
2975
+ function isElement(node) {
2976
+ return node.nodeType === 1;
2977
+ }
2978
+ function directMetadataChildren(element, localName) {
2979
+ return Array.from(element.childNodes).filter((node) => isElement(node) && node.localName === localName && node.namespaceURI === SAML_METADATA_NAMESPACE);
2827
2980
  }
2981
+ function parseXMLSchemaBoolean(value) {
2982
+ if (value === null) return false;
2983
+ switch (value.trim()) {
2984
+ case "true":
2985
+ case "1": return true;
2986
+ case "false":
2987
+ case "0": return false;
2988
+ default: throw new Error("Invalid XML Schema boolean");
2989
+ }
2990
+ }
2991
+ function isAbsoluteHttpUrl(value) {
2992
+ if (value.includes("#")) return false;
2993
+ try {
2994
+ const url = new URL(value);
2995
+ return url.protocol === "http:" || url.protocol === "https:";
2996
+ } catch {
2997
+ return false;
2998
+ }
2999
+ }
3000
+ //#endregion
3001
+ //#region src/directory-sync/pairing.ts
2828
3002
  function isRecord$1(value) {
2829
3003
  return typeof value === "object" && value !== null && !Array.isArray(value);
2830
3004
  }
@@ -2877,10 +3051,9 @@ async function resolveDirectorySyncSSOPairing(ctx, organizationId, pairing) {
2877
3051
  if (!oidcConfiguration || samlConfiguration) throw ctx.error("BAD_REQUEST", { message: "The selected SSO provider is not an OIDC provider" });
2878
3052
  } else {
2879
3053
  if (!samlConfiguration || oidcConfiguration) throw ctx.error("BAD_REQUEST", { message: "The selected SSO provider is not a SAML provider" });
2880
- const samlPolicy = await loadSAMLPolicy();
2881
3054
  let wantAssertionsSigned = false;
2882
3055
  try {
2883
- wantAssertionsSigned = await samlPolicy.requiresSignedSAMLAssertions({
3056
+ wantAssertionsSigned = requiresSignedSAMLAssertions({
2884
3057
  spMetadata: isRecord$1(samlConfiguration.spMetadata) ? { metadata: typeof samlConfiguration.spMetadata.metadata === "string" ? samlConfiguration.spMetadata.metadata : void 0 } : void 0,
2885
3058
  wantAssertionsSigned: samlConfiguration.wantAssertionsSigned === true
2886
3059
  });
@@ -2927,17 +3100,228 @@ async function guardDirectorySyncSSOProviderMutation(input, context) {
2927
3100
  }
2928
3101
  }
2929
3102
  //#endregion
3103
+ //#region src/directory-sync/scim-user-link.ts
3104
+ function createScopedKey(parts) {
3105
+ return base64Url.encode(sha256(new TextEncoder().encode(JSON.stringify(parts))), { padding: false });
3106
+ }
3107
+ function createSCIMUserExternalIdKey(connectionId, externalId) {
3108
+ return createScopedKey([
3109
+ "scim-user-external-id",
3110
+ connectionId,
3111
+ externalId
3112
+ ]);
3113
+ }
3114
+ function createSCIMConnectionKey(connectionId) {
3115
+ return createScopedKey(["scim-connection", connectionId]);
3116
+ }
3117
+ var SCIMIdentityMutationConflict = class extends Error {
3118
+ constructor() {
3119
+ super("The SCIM identity changed concurrently; retry the request");
3120
+ this.name = "SCIMIdentityMutationConflict";
3121
+ }
3122
+ };
3123
+ function concurrentIdentityMutation() {
3124
+ throw new SCIMIdentityMutationConflict();
3125
+ }
3126
+ function hasIncrementOne(database) {
3127
+ return typeof database.incrementOne === "function";
3128
+ }
3129
+ async function tryFenceActiveSCIMConnection(database, connectionId) {
3130
+ return database.incrementOne({
3131
+ model: "scimConnectionBinding",
3132
+ where: [
3133
+ {
3134
+ field: "connectionKey",
3135
+ value: createSCIMConnectionKey(connectionId)
3136
+ },
3137
+ {
3138
+ field: "connectionId",
3139
+ value: connectionId
3140
+ },
3141
+ {
3142
+ field: "decommissionStatus",
3143
+ value: "active"
3144
+ }
3145
+ ],
3146
+ increment: { decommissionRevision: 1 }
3147
+ });
3148
+ }
3149
+ /**
3150
+ * Acquires an active provisioned User link inside the caller's transaction.
3151
+ * Returns null when no active link exists. Throws on concurrent identity mutation.
3152
+ */
3153
+ async function acquireActiveSCIMUserLink(reference, context) {
3154
+ if (!hasIncrementOne(context.database)) return null;
3155
+ const database = context.database;
3156
+ const externalIdKey = createSCIMUserExternalIdKey(reference.connectionId, reference.externalId);
3157
+ const source = await database.findOne({
3158
+ model: "scimUser",
3159
+ where: [
3160
+ {
3161
+ field: "connectionId",
3162
+ value: reference.connectionId
3163
+ },
3164
+ {
3165
+ field: "externalIdKey",
3166
+ value: externalIdKey
3167
+ },
3168
+ {
3169
+ field: "externalId",
3170
+ value: reference.externalId
3171
+ },
3172
+ {
3173
+ field: "active",
3174
+ value: true
3175
+ }
3176
+ ]
3177
+ });
3178
+ if (!source) return null;
3179
+ const binding = await database.findOne({
3180
+ model: "scimConnectionBinding",
3181
+ where: [
3182
+ {
3183
+ field: "connectionKey",
3184
+ value: createSCIMConnectionKey(reference.connectionId)
3185
+ },
3186
+ {
3187
+ field: "connectionId",
3188
+ value: reference.connectionId
3189
+ },
3190
+ {
3191
+ field: "decommissionStatus",
3192
+ value: "active"
3193
+ }
3194
+ ]
3195
+ });
3196
+ if (!binding || binding.provisioningDomainId !== source.provisioningDomainId) return null;
3197
+ if (await database.findOne({
3198
+ model: "scimIdentityTombstone",
3199
+ where: [
3200
+ {
3201
+ field: "connectionId",
3202
+ value: reference.connectionId
3203
+ },
3204
+ {
3205
+ field: "externalIdKey",
3206
+ value: externalIdKey
3207
+ },
3208
+ {
3209
+ field: "externalId",
3210
+ value: reference.externalId
3211
+ }
3212
+ ]
3213
+ })) return null;
3214
+ const subject = await database.findOne({
3215
+ model: "scimSubject",
3216
+ where: [{
3217
+ field: "userId",
3218
+ value: source.userId
3219
+ }]
3220
+ });
3221
+ if (!subject) return null;
3222
+ if (!await database.findOne({
3223
+ model: "user",
3224
+ where: [{
3225
+ field: "id",
3226
+ value: source.userId
3227
+ }]
3228
+ })) return null;
3229
+ const acquiredSubject = await database.incrementOne({
3230
+ model: "scimSubject",
3231
+ where: [
3232
+ {
3233
+ field: "id",
3234
+ value: subject.id
3235
+ },
3236
+ {
3237
+ field: "userId",
3238
+ value: source.userId
3239
+ },
3240
+ {
3241
+ field: "revision",
3242
+ value: subject.revision
3243
+ }
3244
+ ],
3245
+ increment: { revision: 1 },
3246
+ set: { updatedAt: /* @__PURE__ */ new Date() }
3247
+ });
3248
+ if (!acquiredSubject) concurrentIdentityMutation();
3249
+ const acquiredSource = await database.findOne({
3250
+ model: "scimUser",
3251
+ where: [
3252
+ {
3253
+ field: "id",
3254
+ value: source.id
3255
+ },
3256
+ {
3257
+ field: "connectionId",
3258
+ value: reference.connectionId
3259
+ },
3260
+ {
3261
+ field: "provisioningDomainId",
3262
+ value: binding.provisioningDomainId
3263
+ },
3264
+ {
3265
+ field: "userId",
3266
+ value: source.userId
3267
+ },
3268
+ {
3269
+ field: "connectionUserKey",
3270
+ value: source.connectionUserKey
3271
+ },
3272
+ {
3273
+ field: "externalIdKey",
3274
+ value: externalIdKey
3275
+ },
3276
+ {
3277
+ field: "externalId",
3278
+ value: reference.externalId
3279
+ },
3280
+ {
3281
+ field: "active",
3282
+ value: true
3283
+ }
3284
+ ]
3285
+ });
3286
+ if (!acquiredSource || !acquiredSource.active || acquiredSource.userId !== acquiredSubject.userId) concurrentIdentityMutation();
3287
+ if (!await database.findOne({
3288
+ model: "user",
3289
+ where: [{
3290
+ field: "id",
3291
+ value: acquiredSource.userId
3292
+ }]
3293
+ })) concurrentIdentityMutation();
3294
+ if (await database.findOne({
3295
+ model: "scimIdentityTombstone",
3296
+ where: [
3297
+ {
3298
+ field: "connectionId",
3299
+ value: reference.connectionId
3300
+ },
3301
+ {
3302
+ field: "externalIdKey",
3303
+ value: externalIdKey
3304
+ },
3305
+ {
3306
+ field: "externalId",
3307
+ value: reference.externalId
3308
+ }
3309
+ ]
3310
+ })) concurrentIdentityMutation();
3311
+ const acquiredBinding = await tryFenceActiveSCIMConnection(database, reference.connectionId);
3312
+ if (!acquiredBinding || acquiredBinding.id !== binding.id || acquiredBinding.provisioningDomainId !== acquiredSource.provisioningDomainId) concurrentIdentityMutation();
3313
+ return {
3314
+ scimUserId: source.id,
3315
+ userId: source.userId
3316
+ };
3317
+ }
3318
+ //#endregion
2930
3319
  //#region src/directory-sync/sso-user-resolution.ts
2931
3320
  const GENERIC_REJECTION = {
2932
3321
  action: "reject",
2933
3322
  code: "DIRECTORY_SYNC_AUTHENTICATION_FAILED",
2934
3323
  message: "Unable to sign in with this SSO connection"
2935
3324
  };
2936
- let scimCatalogModule;
2937
- function loadSCIMCatalog() {
2938
- scimCatalogModule ??= import("@better-auth/scim");
2939
- return scimCatalogModule;
2940
- }
2941
3325
  function readStringExternalId(value) {
2942
3326
  if (typeof value === "string" && value.length > 0) return value;
2943
3327
  return null;
@@ -2983,9 +3367,7 @@ async function resolveOrganizationDirectorySyncUser(input, context) {
2983
3367
  const externalId = readExternalId(input, pairing);
2984
3368
  if (!externalId) return GENERIC_REJECTION;
2985
3369
  try {
2986
- const catalog = await loadSCIMCatalog();
2987
- if (typeof catalog.acquireActiveSCIMUserLink !== "function") return GENERIC_REJECTION;
2988
- const link = await catalog.acquireActiveSCIMUserLink({
3370
+ const link = await acquireActiveSCIMUserLink({
2989
3371
  connectionId: directory.connectionId,
2990
3372
  externalId
2991
3373
  }, { database: context.database });
@@ -3017,35 +3399,41 @@ function instrumentDirectorySyncIntegration(ctx, options) {
3017
3399
  logger.debug("[Dash] Managed directory sync enabled but SSO/SCIM plugins are not active. Skipping integration instrumentation");
3018
3400
  return;
3019
3401
  }
3020
- if (options.ssoPairing) if (ssoPlugin) if (!ssoPlugin.options) logger.error("[Dash] Managed directory sync ssoPairing requires sso({ ... }) (at least sso({})) so pairing callbacks can be installed on the shared options object.");
3021
- else {
3022
- const ssoOptions = ssoPlugin.options;
3023
- const previousResolveUser = ssoOptions.resolveUser;
3024
- ssoOptions.resolveUser = async (input, context) => {
3025
- const result = await resolveOrganizationDirectorySyncUser(input, context);
3026
- if (result.action !== "continue") return result;
3027
- if (previousResolveUser) return previousResolveUser(input, context);
3028
- return { action: "continue" };
3029
- };
3030
- const previousGuard = ssoOptions.guardProviderMutation;
3031
- ssoOptions.guardProviderMutation = async (input, context) => {
3032
- await guardDirectorySyncSSOProviderMutation(input, context);
3033
- if (previousGuard) await previousGuard(input, context);
3034
- };
3402
+ if (options.ssoPairing) {
3403
+ if (ssoPlugin) {
3404
+ if (!ssoPlugin.options) logger.error("[Dash] Managed directory sync ssoPairing requires sso({ ... }) (at least sso({})) so pairing callbacks can be installed on the shared options object.");
3405
+ else {
3406
+ const ssoOptions = ssoPlugin.options;
3407
+ const previousResolveUser = ssoOptions.resolveUser;
3408
+ ssoOptions.resolveUser = async (input, context) => {
3409
+ const result = await resolveOrganizationDirectorySyncUser(input, context);
3410
+ if (result.action !== "continue") return result;
3411
+ if (previousResolveUser) return previousResolveUser(input, context);
3412
+ return { action: "continue" };
3413
+ };
3414
+ const previousGuard = ssoOptions.guardProviderMutation;
3415
+ ssoOptions.guardProviderMutation = async (input, context) => {
3416
+ await guardDirectorySyncSSOProviderMutation(input, context);
3417
+ if (previousGuard) await previousGuard(input, context);
3418
+ };
3419
+ }
3420
+ } else logger.debug("[Dash] Managed directory sync ssoPairing enabled but SSO plugin is not active. Skipping SSO pairing instrumentation");
3035
3421
  }
3036
- else logger.debug("[Dash] Managed directory sync ssoPairing enabled but SSO plugin is not active. Skipping SSO pairing instrumentation");
3037
- if (options.membershipProjection.enabled) if (scimPlugin) if (!scimPlugin.options) logger.error("[Dash] Managed directory sync membershipProjection requires scim({ ... }) with an options object so membership projection can be installed.");
3038
- else {
3039
- const scimOptions = scimPlugin.options;
3040
- const projection = scimOptions.projection ??= {};
3041
- const previousReconcileUser = projection.reconcileUser;
3042
- const reconcileUser = createOrganizationMembershipProjection({ role: options.membershipProjection.role });
3043
- projection.reconcileUser = async (input, context) => {
3044
- await reconcileUser(input, context);
3045
- if (previousReconcileUser) await previousReconcileUser(input, context);
3046
- };
3422
+ if (options.membershipProjection.enabled) {
3423
+ if (scimPlugin) {
3424
+ if (!scimPlugin.options) logger.error("[Dash] Managed directory sync membershipProjection requires scim({ ... }) with an options object so membership projection can be installed.");
3425
+ else {
3426
+ const scimOptions = scimPlugin.options;
3427
+ const projection = scimOptions.projection ??= {};
3428
+ const previousReconcileUser = projection.reconcileUser;
3429
+ const reconcileUser = createOrganizationMembershipProjection({ role: options.membershipProjection.role });
3430
+ projection.reconcileUser = async (input, context) => {
3431
+ await reconcileUser(input, context);
3432
+ if (previousReconcileUser) await previousReconcileUser(input, context);
3433
+ };
3434
+ }
3435
+ } else logger.debug("[Dash] Managed directory sync membershipProjection enabled but SCIM plugin is not active. Skipping membership projection instrumentation");
3047
3436
  }
3048
- else logger.debug("[Dash] Managed directory sync membershipProjection enabled but SCIM plugin is not active. Skipping membership projection instrumentation");
3049
3437
  }
3050
3438
  //#endregion
3051
3439
  //#region src/events/organization/events-invitation.ts
@@ -3462,7 +3850,7 @@ function snakeCaseToCamelCase(key) {
3462
3850
  function keyVariantsForMatching(key) {
3463
3851
  const trimmed = key.replace(/^[\s._-]+/, "");
3464
3852
  if (!trimmed) return [key];
3465
- const out = new Set([key, trimmed]);
3853
+ const out = /* @__PURE__ */ new Set([key, trimmed]);
3466
3854
  if (trimmed.includes("_")) out.add(snakeCaseToCamelCase(trimmed));
3467
3855
  return [...out];
3468
3856
  }
@@ -3482,7 +3870,7 @@ function matchesNormalizedPatterns(key, patterns) {
3482
3870
  if (!hasAnyPatterns(patterns)) return false;
3483
3871
  const variants = keyVariantsForMatching(key);
3484
3872
  const compactLower = key.replace(/[\s._-]/g, "").toLowerCase();
3485
- const forms = new Set([compactLower]);
3873
+ const forms = /* @__PURE__ */ new Set([compactLower]);
3486
3874
  for (const raw of variants) {
3487
3875
  forms.add(raw);
3488
3876
  forms.add(raw.toLowerCase());
@@ -3540,9 +3928,9 @@ function redact(value, options) {
3540
3928
  const patterns = normalizePatterns(options?.patterns);
3541
3929
  return redactInner(value, /* @__PURE__ */ new WeakSet(), options, patterns);
3542
3930
  }
3543
- const DASH_PLUGIN_OPTIONS_EXCLUDE_KEYS = { stripe: new Set(["stripeClient"]) };
3931
+ const DASH_PLUGIN_OPTIONS_EXCLUDE_KEYS = { stripe: /* @__PURE__ */ new Set(["stripeClient"]) };
3544
3932
  /** Storage-strategy enums that match sensitive key suffixes but are not secrets. */
3545
- const DASH_PLUGIN_OPTIONS_IGNORE_KEYS = new Set([
3933
+ const DASH_PLUGIN_OPTIONS_IGNORE_KEYS = /* @__PURE__ */ new Set([
3546
3934
  "storeApiKey",
3547
3935
  "storeClientSecret",
3548
3936
  "storeSCIMToken",
@@ -3623,7 +4011,7 @@ function timingSafeEqualHash(a, b) {
3623
4011
  * A freshly issued token is almost certainly legitimate.
3624
4012
  */
3625
4013
  const JTI_CHECK_GRACE_PERIOD_SECONDS = 30;
3626
- const JWKS_CACHE_TTL_MS = 900 * 1e3;
4014
+ const JWKS_CACHE_TTL_MS = 9e5;
3627
4015
  const jwksCache = /* @__PURE__ */ new Map();
3628
4016
  const inflightRequests = /* @__PURE__ */ new Map();
3629
4017
  async function fetchJWKS(ctx, cacheKey, $api) {
@@ -3672,7 +4060,8 @@ const jwtMiddleware = (options, schema, getJWT) => {
3672
4060
  ctx.context.logger.warn("[Dash] JWT is missing from header");
3673
4061
  throw ctx.error("UNAUTHORIZED", { message: "Invalid API key" });
3674
4062
  }
3675
- const { payload } = await jwtVerify(jwsFromHeader, await getJWKs(ctx, cacheKey, $api), { maxTokenAge: "5m" }).catch((e) => {
4063
+ const remoteJWKs = await getJWKs(ctx, cacheKey, $api);
4064
+ const { payload } = await jwtVerify(jwsFromHeader, remoteJWKs, { maxTokenAge: "5m" }).catch((e) => {
3676
4065
  ctx.context.logger.warn("[Dash] JWT verification failed:", e);
3677
4066
  throw ctx.error("UNAUTHORIZED", { message: "Invalid API key" });
3678
4067
  });
@@ -3726,7 +4115,8 @@ const jwtValidateMiddleware = (options) => {
3726
4115
  ctx.context.logger.warn("[Dash] JWT is missing from header");
3727
4116
  throw ctx.error("UNAUTHORIZED", { message: "Invalid API key" });
3728
4117
  }
3729
- const { payload } = await jwtVerify(jwsFromHeader, await getJWKs(ctx, cacheKey, $api), { maxTokenAge: "5m" }).catch((e) => {
4118
+ const remoteJWKs = await getJWKs(ctx, cacheKey, $api);
4119
+ const { payload } = await jwtVerify(jwsFromHeader, remoteJWKs, { maxTokenAge: "5m" }).catch((e) => {
3730
4120
  ctx.context.logger.error("[Dash] JWT verification failed:", e);
3731
4121
  throw ctx.error("UNAUTHORIZED", { message: "Invalid API key" });
3732
4122
  });
@@ -3901,6 +4291,7 @@ const getConfig = (options) => {
3901
4291
  disableCSRFCheck: ctx.context.options.advanced?.disableCSRFCheck || false,
3902
4292
  disableOriginCheck: ctx.context.options.advanced?.disableOriginCheck || false,
3903
4293
  allowDifferentEmails: ctx.context.options.account?.accountLinking?.enabled && ctx.context.options.account?.accountLinking?.allowDifferentEmails || false,
4294
+ identityStrategy: getConfiguredAccountIdentityStrategy(ctx.context.options.account),
3904
4295
  skipStateCookieCheck: ctx.context.options.account?.skipStateCookieCheck || false,
3905
4296
  storeStateCookieStrategy: ctx.context.options.account?.storeStateStrategy || null,
3906
4297
  cookieCache: {
@@ -4055,12 +4446,12 @@ function assertManagedDirectorySyncEnabled(ctx) {
4055
4446
  }
4056
4447
  //#endregion
4057
4448
  //#region src/routes/directory-sync/route-contract.ts
4058
- const DIRECTORY_SYNC_CREDENTIAL_LIFETIME_MS = 365 * 24 * 60 * 60 * 1e3;
4059
- const directorySyncClaimsSchema = z$1.object({
4060
- purpose: z$1.literal(DIRECTORY_SYNC_PURPOSE),
4061
- organizationId: z$1.string().trim().min(1),
4062
- actorId: z$1.string().trim().min(1),
4063
- setupOperationId: z$1.string().trim().min(16).max(255).optional()
4449
+ const DIRECTORY_SYNC_CREDENTIAL_LIFETIME_MS = 31536e6;
4450
+ const directorySyncClaimsSchema = z.object({
4451
+ purpose: z.literal(DIRECTORY_SYNC_PURPOSE),
4452
+ organizationId: z.string().trim().min(1),
4453
+ actorId: z.string().trim().min(1),
4454
+ setupOperationId: z.string().trim().min(16).max(255).optional()
4064
4455
  });
4065
4456
  function getScimEndpoint$1(baseUrl) {
4066
4457
  return `${baseUrl}/scim/v2`;
@@ -4326,14 +4717,6 @@ async function recoverManagedDirectoryConnection(ctx, row, input, policy) {
4326
4717
  async function createManagedDirectoryConnection(ctx, input, policy) {
4327
4718
  await assertManagedDirectoryTransactionsConfigured(ctx);
4328
4719
  if (input.pairing) await assertDirectorySyncSSOIntegrationConfigured(ctx);
4329
- if (input.pairing?.protocol === "saml") try {
4330
- await loadSAMLPolicy();
4331
- } catch {
4332
- throw ctx.error("NOT_IMPLEMENTED", {
4333
- code: "DIRECTORY_SYNC_SAML_POLICY_UNAVAILABLE",
4334
- message: "SAML pairing requires a compatible SSO package with service provider metadata policy support"
4335
- });
4336
- }
4337
4720
  const aliasKey = await createAliasKey(input.organizationId, input.providerId);
4338
4721
  const provisioningDomainId = await createProvisioningDomainId(input.organizationId, input.providerId);
4339
4722
  const activeOrganizationKey = await createActiveOrganizationKey(input.organizationId);
@@ -4772,10 +5155,10 @@ const revokeDirectoryCredential = (options) => createAuthEndpoint("/dash/organiz
4772
5155
  const DIRECTORY_EVENTS_DEFAULT_LIMIT = 10;
4773
5156
  const DIRECTORY_PAGE_MAX_LIMIT = 100;
4774
5157
  const DIRECTORY_EVENTS_DEFAULT_SORT_DIRECTION = "desc";
4775
- const directoryEventsQuerySchema = z$1.object({
4776
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
4777
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
4778
- sortDirection: z$1.enum(["asc", "desc"]).optional()
5158
+ const directoryEventsQuerySchema = z.object({
5159
+ limit: z.number().or(z.string().transform(Number)).optional(),
5160
+ offset: z.number().or(z.string().transform(Number)).optional(),
5161
+ sortDirection: z.enum(["asc", "desc"]).optional()
4779
5162
  }).optional();
4780
5163
  function resolveDirectoryEventsPage(query) {
4781
5164
  const requestedLimit = query?.limit;
@@ -4927,7 +5310,7 @@ function parseMemberRoles(role) {
4927
5310
  }
4928
5311
  function getScimManagementRoles(ctx) {
4929
5312
  const creatorRole = ctx.context.getPlugin("organization")?.options?.creatorRole ?? "owner";
4930
- return Array.from(new Set(["admin", creatorRole]));
5313
+ return Array.from(/* @__PURE__ */ new Set(["admin", creatorRole]));
4931
5314
  }
4932
5315
  async function findOrganizationScimManagerUserId(ctx, organizationId) {
4933
5316
  const requiredRoles = getScimManagementRoles(ctx);
@@ -5028,10 +5411,10 @@ const listOrganizationDirectories = (options) => {
5028
5411
  const createOrganizationDirectoryLegacy = (options) => {
5029
5412
  return createAuthEndpoint("/dash/organization/directory/create", {
5030
5413
  method: "POST",
5031
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
5032
- body: z$1.object({
5033
- providerId: z$1.string().min(1, "Provider ID is required"),
5034
- ownerUserId: z$1.string().min(1, "Owner user ID is required")
5414
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
5415
+ body: z.object({
5416
+ providerId: z.string().min(1, "Provider ID is required"),
5417
+ ownerUserId: z.string().min(1, "Owner user ID is required")
5035
5418
  })
5036
5419
  }, async (ctx) => {
5037
5420
  requireOrganizationPlugin(ctx);
@@ -5068,8 +5451,8 @@ const createOrganizationDirectoryLegacy = (options) => {
5068
5451
  const deleteOrganizationDirectoryLegacy = (options) => {
5069
5452
  return createAuthEndpoint("/dash/organization/directory/delete", {
5070
5453
  method: "POST",
5071
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
5072
- body: z$1.object({ providerId: z$1.string().min(1, "Provider ID is required") })
5454
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
5455
+ body: z.object({ providerId: z.string().min(1, "Provider ID is required") })
5073
5456
  }, async (ctx) => {
5074
5457
  requireOrganizationPlugin(ctx);
5075
5458
  const scimPlugin = getSCIMPlugin(ctx);
@@ -5092,8 +5475,8 @@ const deleteOrganizationDirectoryLegacy = (options) => {
5092
5475
  const regenerateDirectoryTokenLegacy = (options) => {
5093
5476
  return createAuthEndpoint("/dash/organization/directory/regenerate-token", {
5094
5477
  method: "POST",
5095
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
5096
- body: z$1.object({ providerId: z$1.string().min(1, "Provider ID is required") })
5478
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
5479
+ body: z.object({ providerId: z.string().min(1, "Provider ID is required") })
5097
5480
  }, async (ctx) => {
5098
5481
  requireOrganizationPlugin(ctx);
5099
5482
  const scimPlugin = getSCIMPlugin(ctx);
@@ -5163,13 +5546,13 @@ const getUserEvents = (options) => {
5163
5546
  return createAuthEndpoint("/events/list", {
5164
5547
  method: "GET",
5165
5548
  use: [sessionMiddleware],
5166
- query: z$1.object({
5549
+ query: z.object({
5167
5550
  /** Maximum number of events to return (default: 50, max: 100) */
5168
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
5551
+ limit: z.number().or(z.string().transform(Number)).optional(),
5169
5552
  /** Number of events to skip for pagination (default: 0) */
5170
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
5553
+ offset: z.number().or(z.string().transform(Number)).optional(),
5171
5554
  /** Filter by event type (e.g., "user_signed_in") */
5172
- eventType: z$1.string().optional()
5555
+ eventType: z.string().optional()
5173
5556
  }).optional()
5174
5557
  }, async (ctx) => {
5175
5558
  const session = ctx.context.session;
@@ -5232,13 +5615,13 @@ const getAuditLogs = (options) => {
5232
5615
  return createAuthEndpoint("/events/audit-logs", {
5233
5616
  method: "GET",
5234
5617
  use: [sessionMiddleware],
5235
- query: z$1.object({
5236
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
5237
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
5238
- userId: z$1.string().optional(),
5239
- organizationId: z$1.string().optional(),
5240
- identifier: z$1.string().optional(),
5241
- eventType: z$1.string().optional()
5618
+ query: z.object({
5619
+ limit: z.number().or(z.string().transform(Number)).optional(),
5620
+ offset: z.number().or(z.string().transform(Number)).optional(),
5621
+ userId: z.string().optional(),
5622
+ organizationId: z.string().optional(),
5623
+ identifier: z.string().optional(),
5624
+ eventType: z.string().optional()
5242
5625
  }).optional()
5243
5626
  }, async (ctx) => {
5244
5627
  const session = ctx.context.session;
@@ -5313,7 +5696,7 @@ const getAuditLogs = (options) => {
5313
5696
  };
5314
5697
  });
5315
5698
  };
5316
- const OWNER_ADMIN_ROLES = new Set(["owner", "admin"]);
5699
+ const OWNER_ADMIN_ROLES = /* @__PURE__ */ new Set(["owner", "admin"]);
5317
5700
  function isOwnerOrAdminRole(role) {
5318
5701
  return role !== void 0 && OWNER_ADMIN_ROLES.has(role);
5319
5702
  }
@@ -5354,15 +5737,15 @@ const getAllAuditLogs = (options) => {
5354
5737
  return createAuthEndpoint("/events/all-audit-logs", {
5355
5738
  method: "GET",
5356
5739
  use: [sessionMiddleware],
5357
- query: z$1.object({
5358
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
5359
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
5360
- userId: z$1.string().optional(),
5361
- organizationId: z$1.string().optional(),
5740
+ query: z.object({
5741
+ limit: z.number().or(z.string().transform(Number)).optional(),
5742
+ offset: z.number().or(z.string().transform(Number)).optional(),
5743
+ userId: z.string().optional(),
5744
+ organizationId: z.string().optional(),
5362
5745
  /** Filter by event type (e.g. `organization_member_added`) */
5363
- eventType: z$1.string().optional(),
5746
+ eventType: z.string().optional(),
5364
5747
  /** Match `eventData.identifier` (organization-scoped actor identity) */
5365
- identifier: z$1.string().optional()
5748
+ identifier: z.string().optional()
5366
5749
  }).refine((q) => {
5367
5750
  const u = q.userId?.trim();
5368
5751
  const o = q.organizationId?.trim();
@@ -5419,10 +5802,10 @@ const getAllAuditLogs = (options) => {
5419
5802
  };
5420
5803
  //#endregion
5421
5804
  //#region src/routes/execute-adapter/index.ts
5422
- const whereClause = z.object({
5423
- field: z.string(),
5424
- value: z.unknown(),
5425
- operator: z.enum([
5805
+ const whereClause = z$1.object({
5806
+ field: z$1.string(),
5807
+ value: z$1.unknown(),
5808
+ operator: z$1.enum([
5426
5809
  "eq",
5427
5810
  "ne",
5428
5811
  "gt",
@@ -5434,44 +5817,44 @@ const whereClause = z.object({
5434
5817
  "starts_with",
5435
5818
  "ends_with"
5436
5819
  ]).optional(),
5437
- connector: z.enum(["AND", "OR"]).optional()
5820
+ connector: z$1.enum(["AND", "OR"]).optional()
5438
5821
  });
5439
- const sortBySchema = z.object({
5440
- field: z.string(),
5441
- direction: z.enum(["asc", "desc"])
5822
+ const sortBySchema = z$1.object({
5823
+ field: z$1.string(),
5824
+ direction: z$1.enum(["asc", "desc"])
5442
5825
  });
5443
- const actionSchema = z.discriminatedUnion("action", [
5444
- z.object({
5445
- action: z.literal("findOne"),
5446
- model: z.string(),
5447
- where: z.array(whereClause).optional(),
5448
- select: z.array(z.string()).optional(),
5449
- join: z.record(z.string(), z.boolean()).optional()
5826
+ const actionSchema = z$1.discriminatedUnion("action", [
5827
+ z$1.object({
5828
+ action: z$1.literal("findOne"),
5829
+ model: z$1.string(),
5830
+ where: z$1.array(whereClause).optional(),
5831
+ select: z$1.array(z$1.string()).optional(),
5832
+ join: z$1.record(z$1.string(), z$1.boolean()).optional()
5450
5833
  }),
5451
- z.object({
5452
- action: z.literal("findMany"),
5453
- model: z.string(),
5454
- where: z.array(whereClause).optional(),
5455
- limit: z.number().optional(),
5456
- offset: z.number().optional(),
5834
+ z$1.object({
5835
+ action: z$1.literal("findMany"),
5836
+ model: z$1.string(),
5837
+ where: z$1.array(whereClause).optional(),
5838
+ limit: z$1.number().optional(),
5839
+ offset: z$1.number().optional(),
5457
5840
  sortBy: sortBySchema.optional(),
5458
- join: z.record(z.string(), z.boolean()).optional()
5841
+ join: z$1.record(z$1.string(), z$1.boolean()).optional()
5459
5842
  }),
5460
- z.object({
5461
- action: z.literal("create"),
5462
- model: z.string(),
5463
- data: z.record(z.string(), z.unknown())
5843
+ z$1.object({
5844
+ action: z$1.literal("create"),
5845
+ model: z$1.string(),
5846
+ data: z$1.record(z$1.string(), z$1.unknown())
5464
5847
  }),
5465
- z.object({
5466
- action: z.literal("update"),
5467
- model: z.string(),
5468
- where: z.array(whereClause),
5469
- update: z.record(z.string(), z.unknown())
5848
+ z$1.object({
5849
+ action: z$1.literal("update"),
5850
+ model: z$1.string(),
5851
+ where: z$1.array(whereClause),
5852
+ update: z$1.record(z$1.string(), z$1.unknown())
5470
5853
  }),
5471
- z.object({
5472
- action: z.literal("count"),
5473
- model: z.string(),
5474
- where: z.array(whereClause).optional()
5854
+ z$1.object({
5855
+ action: z$1.literal("count"),
5856
+ model: z$1.string(),
5857
+ where: z$1.array(whereClause).optional()
5475
5858
  })
5476
5859
  ]);
5477
5860
  const executeAdapter = (options) => {
@@ -5589,8 +5972,8 @@ function isSafeHttpUrl(value) {
5589
5972
  }
5590
5973
  }
5591
5974
  /** http(s) absolute URL without embedded credentials. */
5592
- const safeUrlSchema = z$1.string().trim().min(1).pipe(z$1.url().refine(isSafeHttpUrl, { message: "URL must be a valid http(s) URL without credentials" })).transform((value) => new URL(value).href);
5593
- const optionalSafeUrlSchema = z$1.union([safeUrlSchema, z$1.literal("")]).optional();
5975
+ const safeUrlSchema = z.string().trim().min(1).pipe(z.url().refine(isSafeHttpUrl, { message: "URL must be a valid http(s) URL without credentials" })).transform((value) => new URL(value).href);
5976
+ const optionalSafeUrlSchema = z.union([safeUrlSchema, z.literal("")]).optional();
5594
5977
  function getAuthBaseUrl(ctx) {
5595
5978
  const baseURL = ctx.context.options.baseURL;
5596
5979
  return typeof baseURL === "string" && baseURL.trim() ? baseURL : "/";
@@ -5669,10 +6052,13 @@ async function executePlatformInvitationCompletion(ctx, $api, invitation, args)
5669
6052
  }
5670
6053
  });
5671
6054
  if (markError) ctx.context.logger.warn("[Dash] Failed to mark invitation as accepted", markError);
5672
- if (shouldCreateSessionOnInviteComplete(invitation.authMode)) await setSessionCookie(ctx, {
5673
- session: await ctx.context.internalAdapter.createSession(existingUser.id),
5674
- user: existingUser
5675
- });
6055
+ if (shouldCreateSessionOnInviteComplete(invitation.authMode)) {
6056
+ const session = await ctx.context.internalAdapter.createSession(existingUser.id);
6057
+ await setSessionCookie(ctx, {
6058
+ session,
6059
+ user: existingUser
6060
+ });
6061
+ }
5676
6062
  return { redirectUrl: resolveTrustedAuthRedirectUrl(ctx, invitation.redirectUrl, getAuthBaseUrl(ctx)) };
5677
6063
  }
5678
6064
  if (!password && !allowsPasswordlessInviteComplete(invitation.authMode)) throw new APIError("BAD_REQUEST", { message: "Password is required to complete this invitation." });
@@ -5697,10 +6083,13 @@ async function executePlatformInvitationCompletion(ctx, $api, invitation, args)
5697
6083
  }
5698
6084
  });
5699
6085
  if (markError) ctx.context.logger.warn("[Dash] Failed to mark invitation as accepted", markError);
5700
- if (shouldCreateSessionOnInviteComplete(invitation.authMode)) await setSessionCookie(ctx, {
5701
- session: await ctx.context.internalAdapter.createSession(user.id),
5702
- user
5703
- });
6086
+ if (shouldCreateSessionOnInviteComplete(invitation.authMode)) {
6087
+ const session = await ctx.context.internalAdapter.createSession(user.id);
6088
+ await setSessionCookie(ctx, {
6089
+ session,
6090
+ user
6091
+ });
6092
+ }
5704
6093
  return { redirectUrl: resolveTrustedAuthRedirectUrl(ctx, invitation.redirectUrl, getAuthBaseUrl(ctx)) };
5705
6094
  }
5706
6095
  /**
@@ -5712,7 +6101,7 @@ const acceptInvitation = (options) => {
5712
6101
  const { $api } = options;
5713
6102
  return createAuthEndpoint("/dash/accept-invitation", {
5714
6103
  method: "GET",
5715
- query: z$1.object({ token: z$1.string() })
6104
+ query: z.object({ token: z.string() })
5716
6105
  }, async (ctx) => {
5717
6106
  const { token } = ctx.query;
5718
6107
  const invitation = await verifyPendingInvitation(token, $api, ctx);
@@ -5727,10 +6116,13 @@ const acceptInvitation = (options) => {
5727
6116
  }
5728
6117
  });
5729
6118
  if (markError) ctx.context.logger.warn("[Dash] Failed to mark invitation as accepted (existing user)", markError);
5730
- if (shouldCreateSessionOnInviteComplete(invitation.authMode)) await setSessionCookie(ctx, {
5731
- session: await ctx.context.internalAdapter.createSession(existingUser.id),
5732
- user: existingUser
5733
- });
6119
+ if (shouldCreateSessionOnInviteComplete(invitation.authMode)) {
6120
+ const session = await ctx.context.internalAdapter.createSession(existingUser.id);
6121
+ await setSessionCookie(ctx, {
6122
+ session,
6123
+ user: existingUser
6124
+ });
6125
+ }
5734
6126
  const redirectUrl = resolveTrustedAuthRedirectUrl(ctx, invitation.redirectUrl, getAuthBaseUrl(ctx));
5735
6127
  return ctx.redirect(redirectUrl);
5736
6128
  }
@@ -5759,10 +6151,13 @@ const acceptInvitation = (options) => {
5759
6151
  }
5760
6152
  });
5761
6153
  if (markError) ctx.context.logger.warn("[Dash] Failed to mark invitation as accepted", markError);
5762
- if (shouldCreateSessionOnInviteComplete(invitation.authMode)) await setSessionCookie(ctx, {
5763
- session: await ctx.context.internalAdapter.createSession(user.id),
5764
- user
5765
- });
6154
+ if (shouldCreateSessionOnInviteComplete(invitation.authMode)) {
6155
+ const session = await ctx.context.internalAdapter.createSession(user.id);
6156
+ await setSessionCookie(ctx, {
6157
+ session,
6158
+ user
6159
+ });
6160
+ }
5766
6161
  const redirectUrl = resolveTrustedAuthRedirectUrl(ctx, invitation.redirectUrl, getAuthBaseUrl(ctx));
5767
6162
  return ctx.redirect(redirectUrl);
5768
6163
  });
@@ -5776,13 +6171,14 @@ const completeInvitation = (options) => {
5776
6171
  const { $api } = options;
5777
6172
  return createAuthEndpoint("/dash/complete-invitation", {
5778
6173
  method: "POST",
5779
- body: z$1.object({
5780
- token: z$1.string(),
5781
- password: z$1.string().optional()
6174
+ body: z.object({
6175
+ token: z.string(),
6176
+ password: z.string().optional()
5782
6177
  })
5783
6178
  }, async (ctx) => {
5784
6179
  const { token, password } = ctx.body;
5785
- const { redirectUrl } = await executePlatformInvitationCompletion(ctx, $api, await verifyPendingInvitation(token, $api, ctx), {
6180
+ const invitation = await verifyPendingInvitation(token, $api, ctx);
6181
+ const { redirectUrl } = await executePlatformInvitationCompletion(ctx, $api, invitation, {
5786
6182
  token,
5787
6183
  password
5788
6184
  });
@@ -5800,14 +6196,15 @@ const completeInvitationHandoff = (options) => {
5800
6196
  const { $api } = options;
5801
6197
  return createAuthEndpoint("/dash/complete-invitation-handoff", {
5802
6198
  method: "GET",
5803
- query: z$1.object({ handoff: z$1.string().min(1) })
6199
+ query: z.object({ handoff: z.string().min(1) })
5804
6200
  }, async (ctx) => {
5805
6201
  const { data, error } = await $api("/api/internal/invitations/redeem-handoff", {
5806
6202
  method: "POST",
5807
6203
  body: { handoff: ctx.query.handoff }
5808
6204
  });
5809
6205
  if (error || !data?.invitationToken) throw new APIError("BAD_REQUEST", { message: "This invitation link has expired. Please try again." });
5810
- const { redirectUrl } = await executePlatformInvitationCompletion(ctx, $api, await verifyPendingInvitation(data.invitationToken, $api, ctx), {
6206
+ const invitation = await verifyPendingInvitation(data.invitationToken, $api, ctx);
6207
+ const { redirectUrl } = await executePlatformInvitationCompletion(ctx, $api, invitation, {
5811
6208
  token: data.invitationToken,
5812
6209
  password: data.password ?? void 0
5813
6210
  });
@@ -5818,7 +6215,7 @@ const completeInvitationSocial = (options) => {
5818
6215
  const { $api } = options;
5819
6216
  return createAuthEndpoint("/dash/complete-invitation-social", {
5820
6217
  method: "GET",
5821
- query: z$1.object({ token: z$1.string() }),
6218
+ query: z.object({ token: z.string() }),
5822
6219
  use: [sessionMiddleware]
5823
6220
  }, async (ctx) => {
5824
6221
  const sessionUser = ctx.context.session?.user;
@@ -5853,7 +6250,7 @@ const checkUserExists = (options) => {
5853
6250
  return createAuthEndpoint("/dash/check-user-exists", {
5854
6251
  method: "POST",
5855
6252
  use: [jwtMiddleware(options)],
5856
- body: z$1.object({ email: z$1.email() })
6253
+ body: z.object({ email: z.email() })
5857
6254
  }, async (ctx) => {
5858
6255
  const { email } = ctx.body;
5859
6256
  const normalizedEmail = normalizeEmail(email, ctx.context);
@@ -5883,7 +6280,7 @@ function getOrganizationRoleKeys(orgOptions) {
5883
6280
  if (roles && typeof roles === "object" && Object.keys(roles).length > 0) return Object.keys(roles);
5884
6281
  return [...DEFAULT_ORG_MEMBER_ROLES];
5885
6282
  }
5886
- const organizationMemberRoleInputSchema = z$1.string().trim().min(1, "Role is required").max(64, "Role is too long").regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/, "Role must start with a letter and contain only letters, numbers, hyphens, and underscores");
6283
+ const organizationMemberRoleInputSchema = z.string().trim().min(1, "Role is required").max(64, "Role is too long").regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/, "Role must start with a letter and contain only letters, numbers, hyphens, and underscores");
5887
6284
  function validateOrganizationMemberRole(ctx, role, orgOptions) {
5888
6285
  const allowedRoles = getOrganizationRoleKeys(orgOptions);
5889
6286
  if (!allowedRoles.includes(role)) throw ctx.error("BAD_REQUEST", { message: `Invalid role. Allowed roles: ${allowedRoles.join(", ")}` });
@@ -5945,14 +6342,14 @@ const listOrganizationInvitations = (options) => {
5945
6342
  const inviteMember = (options) => {
5946
6343
  return createAuthEndpoint("/dash/organization/invite-member", {
5947
6344
  method: "POST",
5948
- body: z$1.object({
5949
- email: z$1.string(),
6345
+ body: z.object({
6346
+ email: z.string(),
5950
6347
  role: organizationMemberRoleInputSchema,
5951
- invitedBy: z$1.string()
6348
+ invitedBy: z.string()
5952
6349
  }),
5953
- use: [jwtMiddleware(options, z$1.object({
5954
- organizationId: z$1.string(),
5955
- invitedBy: z$1.string()
6350
+ use: [jwtMiddleware(options, z.object({
6351
+ organizationId: z.string(),
6352
+ invitedBy: z.string()
5956
6353
  }))]
5957
6354
  }, async (ctx) => {
5958
6355
  const { organizationId } = ctx.context.payload;
@@ -5989,8 +6386,8 @@ const inviteMember = (options) => {
5989
6386
  const checkUserByEmail = (options) => {
5990
6387
  return createAuthEndpoint("/dash/organization/check-user-by-email", {
5991
6388
  method: "POST",
5992
- body: z$1.object({ email: z$1.string() }),
5993
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))]
6389
+ body: z.object({ email: z.string() }),
6390
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))]
5994
6391
  }, async (ctx) => {
5995
6392
  requireOrganizationPlugin(ctx);
5996
6393
  const { organizationId } = ctx.context.payload;
@@ -6033,11 +6430,11 @@ const checkUserByEmail = (options) => {
6033
6430
  const cancelInvitation = (options) => {
6034
6431
  return createAuthEndpoint("/dash/organization/cancel-invitation", {
6035
6432
  method: "POST",
6036
- use: [jwtMiddleware(options, z$1.object({
6037
- organizationId: z$1.string(),
6038
- invitationId: z$1.string()
6433
+ use: [jwtMiddleware(options, z.object({
6434
+ organizationId: z.string(),
6435
+ invitationId: z.string()
6039
6436
  }))],
6040
- body: z$1.object({ invitationId: z$1.string() })
6437
+ body: z.object({ invitationId: z.string() })
6041
6438
  }, async (ctx) => {
6042
6439
  const orgOptions = requireOrganizationPlugin(ctx).options || {};
6043
6440
  const { invitationId, organizationId } = ctx.context.payload;
@@ -6091,11 +6488,11 @@ const cancelInvitation = (options) => {
6091
6488
  const resendInvitation = (options) => {
6092
6489
  return createAuthEndpoint("/dash/organization/resend-invitation", {
6093
6490
  method: "POST",
6094
- use: [jwtMiddleware(options, z$1.object({
6095
- organizationId: z$1.string(),
6096
- invitationId: z$1.string()
6491
+ use: [jwtMiddleware(options, z.object({
6492
+ organizationId: z.string(),
6493
+ invitationId: z.string()
6097
6494
  }))],
6098
- body: z$1.object({ invitationId: z$1.string() })
6495
+ body: z.object({ invitationId: z.string() })
6099
6496
  }, async (ctx) => {
6100
6497
  const organizationPlugin = requireOrganizationPlugin(ctx);
6101
6498
  const { invitationId, organizationId } = ctx.context.payload;
@@ -6204,9 +6601,9 @@ const listOrganizationMembers = (options) => {
6204
6601
  const addMember = (options) => {
6205
6602
  return createAuthEndpoint("/dash/organization/add-member", {
6206
6603
  method: "POST",
6207
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
6208
- body: z$1.object({
6209
- userId: z$1.string(),
6604
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
6605
+ body: z.object({
6606
+ userId: z.string(),
6210
6607
  role: organizationMemberRoleInputSchema
6211
6608
  })
6212
6609
  }, async (ctx) => {
@@ -6261,8 +6658,8 @@ const addMember = (options) => {
6261
6658
  const removeMember = (options) => {
6262
6659
  return createAuthEndpoint("/dash/organization/remove-member", {
6263
6660
  method: "POST",
6264
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
6265
- body: z$1.object({ memberId: z$1.string() })
6661
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
6662
+ body: z.object({ memberId: z.string() })
6266
6663
  }, async (ctx) => {
6267
6664
  const { organizationId } = ctx.context.payload;
6268
6665
  const orgOptions = requireOrganizationPlugin(ctx).options || {};
@@ -6331,9 +6728,9 @@ const removeMember = (options) => {
6331
6728
  const updateMemberRole = (options) => {
6332
6729
  return createAuthEndpoint("/dash/organization/update-member-role", {
6333
6730
  method: "POST",
6334
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
6335
- body: z$1.object({
6336
- memberId: z$1.string(),
6731
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
6732
+ body: z.object({
6733
+ memberId: z.string(),
6337
6734
  role: organizationMemberRoleInputSchema
6338
6735
  })
6339
6736
  }, async (ctx) => {
@@ -6392,7 +6789,7 @@ const updateMemberRole = (options) => {
6392
6789
  //#region src/export-factory.ts
6393
6790
  const exportFactory = (input, options) => async (ctx) => {
6394
6791
  const batchSize = options?.batchSize || 1e4;
6395
- const staleMs = options?.staleMs || 300 * 1e3;
6792
+ const staleMs = options?.staleMs || 3e5;
6396
6793
  const enabledFields = options?.enabledFields || [];
6397
6794
  const userLimit = input.limit;
6398
6795
  const userOffset = input.offset || 0;
@@ -6489,16 +6886,16 @@ async function withConcurrency(items, fn, options) {
6489
6886
  return results;
6490
6887
  }
6491
6888
  /** Zod schema for validating organization/project slug format. */
6492
- const slugSchema = z.string().min(1, "Slug is required").regex(/^[a-z0-9-]+$/, "Slug can only contain lowercase letters, numbers, and hyphens");
6889
+ const slugSchema = z$1.string().min(1, "Slug is required").regex(/^[a-z0-9-]+$/, "Slug can only contain lowercase letters, numbers, and hyphens");
6493
6890
  //#endregion
6494
6891
  //#region src/routes/organizations/schemas.ts
6495
- const DENIED_ORG_WRITE_KEYS = new Set([
6892
+ const DENIED_ORG_WRITE_KEYS = /* @__PURE__ */ new Set([
6496
6893
  "id",
6497
6894
  "createdAt",
6498
6895
  "updatedAt"
6499
6896
  ]);
6500
- const CREATE_NON_PERSISTED_KEYS = new Set(["defaultTeamName"]);
6501
- const CREATE_REQUEST_ONLY_KEYS$1 = new Set(["userId", "skipDefaultTeam"]);
6897
+ const CREATE_NON_PERSISTED_KEYS = /* @__PURE__ */ new Set(["defaultTeamName"]);
6898
+ const CREATE_REQUEST_ONLY_KEYS$1 = /* @__PURE__ */ new Set(["userId", "skipDefaultTeam"]);
6502
6899
  const CORE_CREATE_KEYS$1 = [
6503
6900
  "name",
6504
6901
  "slug",
@@ -6530,7 +6927,7 @@ function getWritableOrganizationFieldNames(orgOptions, mode) {
6530
6927
  */
6531
6928
  function pickWritableOrganizationFields(body, orgOptions, mode) {
6532
6929
  const allowed = getWritableOrganizationFieldNames(orgOptions, mode);
6533
- const skip = new Set([
6930
+ const skip = /* @__PURE__ */ new Set([
6534
6931
  ...DENIED_ORG_WRITE_KEYS,
6535
6932
  ...mode === "create" ? CREATE_NON_PERSISTED_KEYS : [],
6536
6933
  ...mode === "create" ? CREATE_REQUEST_ONLY_KEYS$1 : []
@@ -6542,26 +6939,26 @@ function pickWritableOrganizationFields(body, orgOptions, mode) {
6542
6939
  }
6543
6940
  return result;
6544
6941
  }
6545
- const BaseCreateOrgCoreBodySchema = z$1.object({
6546
- name: z$1.string(),
6942
+ const BaseCreateOrgCoreBodySchema = z.object({
6943
+ name: z.string(),
6547
6944
  slug: slugSchema,
6548
- logo: z$1.string().optional(),
6549
- defaultTeamName: z$1.string().optional()
6945
+ logo: z.string().optional(),
6946
+ defaultTeamName: z.string().optional()
6550
6947
  });
6551
- const BaseUpdateOrgCoreBodySchema = z$1.object({
6948
+ const BaseUpdateOrgCoreBodySchema = z.object({
6552
6949
  logo: optionalSafeUrlSchema,
6553
- name: z$1.string().optional(),
6950
+ name: z.string().optional(),
6554
6951
  slug: slugSchema.optional(),
6555
- metadata: z$1.string().optional()
6952
+ metadata: z.string().optional()
6556
6953
  });
6557
- const CreateOrganizationBodySchema = BaseCreateOrgCoreBodySchema.catchall(z$1.unknown());
6558
- const UpdateOrganizationBodySchema = BaseUpdateOrgCoreBodySchema.catchall(z$1.unknown());
6954
+ const CreateOrganizationBodySchema = BaseCreateOrgCoreBodySchema.catchall(z.unknown());
6955
+ const UpdateOrganizationBodySchema = BaseUpdateOrgCoreBodySchema.catchall(z.unknown());
6559
6956
  function createSchemaForDBField$1(field) {
6560
6957
  switch (field.type) {
6561
- case "number": return field.required ? z$1.coerce.number() : z$1.coerce.number().optional();
6562
- case "boolean": return field.required ? z$1.coerce.boolean() : z$1.coerce.boolean().optional();
6563
- case "date": return field.required ? z$1.union([z$1.string().min(1), z$1.coerce.date()]) : z$1.union([z$1.string(), z$1.coerce.date()]).optional();
6564
- default: return field.required ? z$1.string().min(1) : z$1.string().optional();
6958
+ case "number": return field.required ? z.coerce.number() : z.coerce.number().optional();
6959
+ case "boolean": return field.required ? z.coerce.boolean() : z.coerce.boolean().optional();
6960
+ case "date": return field.required ? z.union([z.string().min(1), z.coerce.date()]) : z.union([z.string(), z.coerce.date()]).optional();
6961
+ default: return field.required ? z.string().min(1) : z.string().optional();
6565
6962
  }
6566
6963
  }
6567
6964
  /**
@@ -6570,39 +6967,39 @@ function createSchemaForDBField$1(field) {
6570
6967
  */
6571
6968
  function validateWritableCreateOrganizationFields(data, options) {
6572
6969
  const shape = {
6573
- name: z$1.string().min(1),
6970
+ name: z.string().min(1),
6574
6971
  slug: slugSchema,
6575
- logo: z$1.string().optional()
6972
+ logo: z.string().optional()
6576
6973
  };
6577
6974
  const additional = getOrganizationAdditionalFields(options);
6578
6975
  for (const [name, field] of Object.entries(additional)) {
6579
6976
  if (field.input === false) continue;
6580
6977
  shape[name] = createSchemaForDBField$1(field);
6581
6978
  }
6582
- const result = z$1.object(shape).strict().safeParse(data);
6979
+ const result = z.object(shape).strict().safeParse(data);
6583
6980
  if (!result.success) throw result.error;
6584
6981
  }
6585
6982
  /**
6586
6983
  * Ensures at least one field is present on update and validates additional field types.
6587
6984
  */
6588
6985
  function validateWritableOrganizationUpdateFields(data, orgOptions) {
6589
- if (Object.keys(data).length === 0) throw new z$1.ZodError([{
6986
+ if (Object.keys(data).length === 0) throw new z.ZodError([{
6590
6987
  code: "custom",
6591
6988
  message: "No valid fields to update",
6592
6989
  path: []
6593
6990
  }]);
6594
6991
  const shape = {
6595
- name: z$1.string().min(1).optional(),
6992
+ name: z.string().min(1).optional(),
6596
6993
  slug: slugSchema.optional(),
6597
6994
  logo: optionalSafeUrlSchema,
6598
- metadata: z$1.string().optional()
6995
+ metadata: z.string().optional()
6599
6996
  };
6600
6997
  const additional = getOrganizationAdditionalFields(orgOptions);
6601
6998
  for (const [name, field] of Object.entries(additional)) {
6602
6999
  if (field.input === false) continue;
6603
7000
  shape[name] = createSchemaForDBField$1(field);
6604
7001
  }
6605
- const result = z$1.object(shape).partial().strict().safeParse(data);
7002
+ const result = z.object(shape).partial().strict().safeParse(data);
6606
7003
  if (!result.success) throw result.error;
6607
7004
  }
6608
7005
  //#endregion
@@ -6644,26 +7041,26 @@ const listOrganizations = (options) => {
6644
7041
  return createAuthEndpoint("/dash/list-organizations", {
6645
7042
  method: "GET",
6646
7043
  use: [jwtMiddleware(options)],
6647
- query: z$1.object({
6648
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
6649
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
6650
- sortBy: z$1.enum([
7044
+ query: z.object({
7045
+ limit: z.number().or(z.string().transform(Number)).optional(),
7046
+ offset: z.number().or(z.string().transform(Number)).optional(),
7047
+ sortBy: z.enum([
6651
7048
  "createdAt",
6652
7049
  "name",
6653
7050
  "slug",
6654
7051
  "members"
6655
7052
  ]).optional(),
6656
- sortOrder: z$1.enum(["asc", "desc"]).optional(),
6657
- filterMembers: z$1.enum([
7053
+ sortOrder: z.enum(["asc", "desc"]).optional(),
7054
+ filterMembers: z.enum([
6658
7055
  "abandoned",
6659
7056
  "eq1",
6660
7057
  "gt1",
6661
7058
  "gt5",
6662
7059
  "gt10"
6663
7060
  ]).optional(),
6664
- search: z$1.string().optional(),
6665
- startDate: z$1.date().or(z$1.string().transform((val) => new Date(val))).optional(),
6666
- endDate: z$1.date().or(z$1.string().transform((val) => new Date(val))).optional()
7061
+ search: z.string().optional(),
7062
+ startDate: z.date().or(z.string().transform((val) => new Date(val))).optional(),
7063
+ endDate: z.date().or(z.string().transform((val) => new Date(val))).optional()
6667
7064
  }).optional()
6668
7065
  }, async (ctx) => {
6669
7066
  const { limit = 10, offset = 0, sortBy = "createdAt", sortOrder = "desc", search, filterMembers } = ctx.query || {};
@@ -6784,12 +7181,12 @@ function parseWhereClause$1(val) {
6784
7181
  if (!Array.isArray(parsed)) return [];
6785
7182
  return parsed;
6786
7183
  }
6787
- const exportOrganizationsQuerySchema = z$1.object({
6788
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
6789
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
6790
- sortBy: z$1.string().optional(),
6791
- sortOrder: z$1.enum(["asc", "desc"]).optional(),
6792
- where: z$1.string().transform(parseWhereClause$1).optional()
7184
+ const exportOrganizationsQuerySchema = z.object({
7185
+ limit: z.number().or(z.string().transform(Number)).optional(),
7186
+ offset: z.number().or(z.string().transform(Number)).optional(),
7187
+ sortBy: z.string().optional(),
7188
+ sortOrder: z.enum(["asc", "desc"]).optional(),
7189
+ where: z.string().transform(parseWhereClause$1).optional()
6793
7190
  }).optional();
6794
7191
  const exportOrganizations = (options) => {
6795
7192
  return createAuthEndpoint("/dash/export-organizations", {
@@ -6854,8 +7251,8 @@ const getOrganization = (options) => {
6854
7251
  const deleteOrganization = (options) => {
6855
7252
  return createAuthEndpoint("/dash/organization/delete", {
6856
7253
  method: "POST",
6857
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
6858
- body: z$1.object({ organizationId: z$1.string() })
7254
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7255
+ body: z.object({ organizationId: z.string() })
6859
7256
  }, async (ctx) => {
6860
7257
  const { organizationId } = ctx.context.payload;
6861
7258
  const { organizationId: bodyOrganizationId } = ctx.body;
@@ -6904,7 +7301,7 @@ const deleteOrganization = (options) => {
6904
7301
  const deleteManyOrganizations = (options) => {
6905
7302
  return createAuthEndpoint("/dash/organization/delete-many", {
6906
7303
  method: "POST",
6907
- use: [jwtMiddleware(options, z$1.object({ organizationIds: z$1.string().array() }))]
7304
+ use: [jwtMiddleware(options, z.object({ organizationIds: z.string().array() }))]
6908
7305
  }, async (ctx) => {
6909
7306
  requireOrganizationPlugin(ctx);
6910
7307
  const { organizationIds } = ctx.context.payload;
@@ -6941,9 +7338,9 @@ const deleteManyOrganizations = (options) => {
6941
7338
  const createOrganization = (options) => {
6942
7339
  return createAuthEndpoint("/dash/organization/create", {
6943
7340
  method: "POST",
6944
- use: [jwtMiddleware(options, z$1.object({
6945
- userId: z$1.string(),
6946
- skipDefaultTeam: z$1.boolean().optional().default(false)
7341
+ use: [jwtMiddleware(options, z.object({
7342
+ userId: z.string(),
7343
+ skipDefaultTeam: z.boolean().optional().default(false)
6947
7344
  }))],
6948
7345
  body: CreateOrganizationBodySchema
6949
7346
  }, async (ctx) => {
@@ -6969,7 +7366,7 @@ const createOrganization = (options) => {
6969
7366
  try {
6970
7367
  validateWritableCreateOrganizationFields(orgData, orgOptions);
6971
7368
  } catch (error) {
6972
- if (error instanceof z$1.ZodError) throw ctx.error("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid organization data" });
7369
+ if (error instanceof z.ZodError) throw ctx.error("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid organization data" });
6973
7370
  throw error;
6974
7371
  }
6975
7372
  if (orgOptions.organizationCreation?.beforeCreate) {
@@ -7105,7 +7502,7 @@ const createOrganization = (options) => {
7105
7502
  const updateOrganization = (options) => {
7106
7503
  return createAuthEndpoint("/dash/organization/update", {
7107
7504
  method: "POST",
7108
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7505
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7109
7506
  body: UpdateOrganizationBodySchema
7110
7507
  }, async (ctx) => {
7111
7508
  const { organizationId } = ctx.context.payload;
@@ -7145,7 +7542,7 @@ const updateOrganization = (options) => {
7145
7542
  try {
7146
7543
  validateWritableOrganizationUpdateFields(updateData, orgOptions);
7147
7544
  } catch (error) {
7148
- if (error instanceof z$1.ZodError) throw ctx.error("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid organization data" });
7545
+ if (error instanceof z.ZodError) throw ctx.error("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid organization data" });
7149
7546
  throw error;
7150
7547
  }
7151
7548
  if (typeof updateData.metadata === "string") try {
@@ -7232,10 +7629,10 @@ const listOrganizationTeams = (options) => {
7232
7629
  const updateTeam = (options) => {
7233
7630
  return createAuthEndpoint("/dash/organization/update-team", {
7234
7631
  method: "POST",
7235
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7236
- body: z$1.object({
7237
- teamId: z$1.string(),
7238
- name: z$1.string().optional()
7632
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7633
+ body: z.object({
7634
+ teamId: z.string(),
7635
+ name: z.string().optional()
7239
7636
  })
7240
7637
  }, async (ctx) => {
7241
7638
  const { organizationId } = ctx.context.payload;
@@ -7306,8 +7703,8 @@ const updateTeam = (options) => {
7306
7703
  const deleteTeam = (options) => {
7307
7704
  return createAuthEndpoint("/dash/organization/delete-team", {
7308
7705
  method: "POST",
7309
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7310
- body: z$1.object({ teamId: z$1.string() })
7706
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7707
+ body: z.object({ teamId: z.string() })
7311
7708
  }, async (ctx) => {
7312
7709
  const { organizationId } = ctx.context.payload;
7313
7710
  const orgOptions = requireTeamsEnabled(ctx);
@@ -7375,8 +7772,8 @@ const deleteTeam = (options) => {
7375
7772
  const createTeam = (options) => {
7376
7773
  return createAuthEndpoint("/dash/organization/create-team", {
7377
7774
  method: "POST",
7378
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7379
- body: z$1.object({ name: z$1.string() })
7775
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7776
+ body: z.object({ name: z.string() })
7380
7777
  }, async (ctx) => {
7381
7778
  const { organizationId } = ctx.context.payload;
7382
7779
  const orgOptions = requireTeamsEnabled(ctx);
@@ -7494,10 +7891,10 @@ const listTeamMembers = (options) => {
7494
7891
  const addTeamMember = (options) => {
7495
7892
  return createAuthEndpoint("/dash/organization/add-team-member", {
7496
7893
  method: "POST",
7497
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7498
- body: z$1.object({
7499
- teamId: z$1.string(),
7500
- userId: z$1.string()
7894
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7895
+ body: z.object({
7896
+ teamId: z.string(),
7897
+ userId: z.string()
7501
7898
  })
7502
7899
  }, async (ctx) => {
7503
7900
  const { organizationId } = ctx.context.payload;
@@ -7587,10 +7984,10 @@ const addTeamMember = (options) => {
7587
7984
  const removeTeamMember = (options) => {
7588
7985
  return createAuthEndpoint("/dash/organization/remove-team-member", {
7589
7986
  method: "POST",
7590
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7591
- body: z$1.object({
7592
- teamId: z$1.string(),
7593
- userId: z$1.string()
7987
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
7988
+ body: z.object({
7989
+ teamId: z.string(),
7990
+ userId: z.string()
7594
7991
  })
7595
7992
  }, async (ctx) => {
7596
7993
  const { organizationId } = ctx.context.payload;
@@ -7693,7 +8090,7 @@ const revokeSession = (options) => createAuthEndpoint("/dash/sessions/revoke", {
7693
8090
  const revokeAllSessions = (options) => createAuthEndpoint("/dash/sessions/revoke-all", {
7694
8091
  method: "POST",
7695
8092
  use: [jwtMiddleware(options)],
7696
- body: z$1.object({ userId: z$1.string() })
8093
+ body: z.object({ userId: z.string() })
7697
8094
  }, async (ctx) => {
7698
8095
  const { userId } = ctx.body;
7699
8096
  if (!await ctx.context.internalAdapter.findUserById(userId)) throw ctx.error("NOT_FOUND", { message: "User not found" });
@@ -7702,7 +8099,7 @@ const revokeAllSessions = (options) => createAuthEndpoint("/dash/sessions/revoke
7702
8099
  });
7703
8100
  const revokeManySessions = (options) => createAuthEndpoint("/dash/sessions/revoke-many", {
7704
8101
  method: "POST",
7705
- use: [jwtMiddleware(options, z$1.object({ userIds: z$1.string().array() }))]
8102
+ use: [jwtMiddleware(options, z.object({ userIds: z.string().array() }))]
7706
8103
  }, async (ctx) => {
7707
8104
  const { userIds } = ctx.context.payload;
7708
8105
  await withConcurrency(chunkArray(userIds, { batchSize: 50 }), async (chunk) => {
@@ -7747,7 +8144,7 @@ function getSSOPlugin(ctx) {
7747
8144
  * (see packages/sso dist constants). Inlined so consumers (e.g. Metro) never
7748
8145
  * statically pull @better-auth/sso for validation-only code paths.
7749
8146
  */
7750
- const DEFAULT_MAX_SAML_METADATA_SIZE = 100 * 1024;
8147
+ const DEFAULT_MAX_SAML_METADATA_SIZE = 102400;
7751
8148
  const RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
7752
8149
  const SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1";
7753
8150
  /** @public */
@@ -7831,44 +8228,44 @@ function requireOrganizationAccess(ctx) {
7831
8228
  const orgIdFromToken = ctx.context.payload?.organizationId;
7832
8229
  if (!orgIdFromToken || orgIdFromUrl !== orgIdFromToken) throw ctx.error("FORBIDDEN", { message: "You do not have access to this organization" });
7833
8230
  }
7834
- const samlConfigSchema = z$1.object({
7835
- idpMetadata: z$1.object({
7836
- metadata: z$1.string().optional(),
7837
- metadataUrl: z$1.string().optional()
8231
+ const samlConfigSchema = z.object({
8232
+ idpMetadata: z.object({
8233
+ metadata: z.string().optional(),
8234
+ metadataUrl: z.string().optional()
7838
8235
  }).optional(),
7839
- entryPoint: z$1.string().optional(),
7840
- cert: z$1.string().optional(),
7841
- entityId: z$1.string().optional(),
7842
- mapping: z$1.object({
8236
+ entryPoint: z.string().optional(),
8237
+ cert: z.string().optional(),
8238
+ entityId: z.string().optional(),
8239
+ mapping: z.object({
7843
8240
  /** @deprecated Removed in better-auth 1.7+; SAML subject is NameID. */
7844
- id: z$1.string().optional(),
7845
- email: z$1.string().optional(),
7846
- emailVerified: z$1.string().optional(),
7847
- name: z$1.string().optional(),
7848
- firstName: z$1.string().optional(),
7849
- lastName: z$1.string().optional(),
7850
- extraFields: z$1.record(z$1.string(), z$1.any()).optional()
8241
+ id: z.string().optional(),
8242
+ email: z.string().optional(),
8243
+ emailVerified: z.string().optional(),
8244
+ name: z.string().optional(),
8245
+ firstName: z.string().optional(),
8246
+ lastName: z.string().optional(),
8247
+ extraFields: z.record(z.string(), z.any()).optional()
7851
8248
  }).optional()
7852
8249
  });
7853
- const oidcConfigSchema = z$1.object({
7854
- clientId: z$1.string(),
7855
- clientSecret: z$1.string().optional(),
7856
- discoveryUrl: z$1.string().optional(),
7857
- issuer: z$1.string().optional(),
7858
- discoveryEndpoint: z$1.string().optional(),
7859
- authorizationEndpoint: z$1.string().optional(),
7860
- tokenEndpoint: z$1.string().optional(),
7861
- jwksEndpoint: z$1.string().optional(),
7862
- userInfoEndpoint: z$1.string().optional(),
7863
- tokenEndpointAuthentication: z$1.enum(["client_secret_post", "client_secret_basic"]).optional(),
7864
- mapping: z$1.object({
8250
+ const oidcConfigSchema = z.object({
8251
+ clientId: z.string(),
8252
+ clientSecret: z.string().optional(),
8253
+ discoveryUrl: z.string().optional(),
8254
+ issuer: z.string().optional(),
8255
+ discoveryEndpoint: z.string().optional(),
8256
+ authorizationEndpoint: z.string().optional(),
8257
+ tokenEndpoint: z.string().optional(),
8258
+ jwksEndpoint: z.string().optional(),
8259
+ userInfoEndpoint: z.string().optional(),
8260
+ tokenEndpointAuthentication: z.enum(["client_secret_post", "client_secret_basic"]).optional(),
8261
+ mapping: z.object({
7865
8262
  /** @deprecated Removed in better-auth 1.7+; OIDC subject is `sub`. */
7866
- id: z$1.string().optional(),
7867
- email: z$1.string().optional(),
7868
- emailVerified: z$1.string().optional(),
7869
- name: z$1.string().optional(),
7870
- image: z$1.string().optional(),
7871
- extraFields: z$1.record(z$1.string(), z$1.any()).optional()
8263
+ id: z.string().optional(),
8264
+ email: z.string().optional(),
8265
+ emailVerified: z.string().optional(),
8266
+ name: z.string().optional(),
8267
+ image: z.string().optional(),
8268
+ extraFields: z.record(z.string(), z.any()).optional()
7872
8269
  }).optional()
7873
8270
  });
7874
8271
  async function resolveSAMLConfig(samlConfig, providerId, baseURL, ctx) {
@@ -7961,7 +8358,7 @@ async function resolveOIDCConfig(oidcConfig, _domain, ctx) {
7961
8358
  const listOrganizationSsoProviders = (options) => {
7962
8359
  return createAuthEndpoint("/dash/organization/:id/sso-providers", {
7963
8360
  method: "GET",
7964
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))]
8361
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))]
7965
8362
  }, async (ctx) => {
7966
8363
  if (!isOrganizationEnabled(ctx)) {
7967
8364
  ctx.context.logger.warn("[Dash] Organization plugin not enabled, returning empty SSO providers list");
@@ -7990,12 +8387,12 @@ const listOrganizationSsoProviders = (options) => {
7990
8387
  const createSsoProvider = (options) => {
7991
8388
  return createAuthEndpoint("/dash/organization/:id/sso-provider/create", {
7992
8389
  method: "POST",
7993
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
7994
- body: z$1.object({
7995
- providerId: z$1.string(),
7996
- domain: z$1.string(),
7997
- protocol: z$1.enum(["SAML", "OIDC"]),
7998
- userId: z$1.string(),
8390
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
8391
+ body: z.object({
8392
+ providerId: z.string(),
8393
+ domain: z.string(),
8394
+ protocol: z.enum(["SAML", "OIDC"]),
8395
+ userId: z.string(),
7999
8396
  samlConfig: samlConfigSchema.optional(),
8000
8397
  oidcConfig: oidcConfigSchema.optional()
8001
8398
  })
@@ -8057,11 +8454,11 @@ const createSsoProvider = (options) => {
8057
8454
  const updateSsoProvider = (options) => {
8058
8455
  return createAuthEndpoint("/dash/organization/:id/sso-provider/update", {
8059
8456
  method: "POST",
8060
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
8061
- body: z$1.object({
8062
- providerId: z$1.string(),
8063
- domain: z$1.string(),
8064
- protocol: z$1.enum(["SAML", "OIDC"]),
8457
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
8458
+ body: z.object({
8459
+ providerId: z.string(),
8460
+ domain: z.string(),
8461
+ protocol: z.enum(["SAML", "OIDC"]),
8065
8462
  samlConfig: samlConfigSchema.optional(),
8066
8463
  oidcConfig: oidcConfigSchema.optional()
8067
8464
  })
@@ -8140,8 +8537,8 @@ const updateSsoProvider = (options) => {
8140
8537
  const requestSsoVerificationToken = (options) => {
8141
8538
  return createAuthEndpoint("/dash/organization/:id/sso-provider/request-verification-token", {
8142
8539
  method: "POST",
8143
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
8144
- body: z$1.object({ providerId: z$1.string() })
8540
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
8541
+ body: z.object({ providerId: z.string() })
8145
8542
  }, async (ctx) => {
8146
8543
  requireOrganizationPlugin(ctx);
8147
8544
  requireOrganizationAccess(ctx);
@@ -8188,8 +8585,8 @@ const requestSsoVerificationToken = (options) => {
8188
8585
  const verifySsoProviderDomain = (options) => {
8189
8586
  return createAuthEndpoint("/dash/organization/:id/sso-provider/verify-domain", {
8190
8587
  method: "POST",
8191
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
8192
- body: z$1.object({ providerId: z$1.string() })
8588
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
8589
+ body: z.object({ providerId: z.string() })
8193
8590
  }, async (ctx) => {
8194
8591
  requireOrganizationPlugin(ctx);
8195
8592
  requireOrganizationAccess(ctx);
@@ -8235,8 +8632,8 @@ const verifySsoProviderDomain = (options) => {
8235
8632
  const deleteSsoProvider = (options) => {
8236
8633
  return createAuthEndpoint("/dash/organization/:id/sso-provider/delete", {
8237
8634
  method: "POST",
8238
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
8239
- body: z$1.object({ providerId: z$1.string() })
8635
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
8636
+ body: z.object({ providerId: z.string() })
8240
8637
  }, async (ctx) => {
8241
8638
  requireOrganizationPlugin(ctx);
8242
8639
  requireOrganizationAccess(ctx);
@@ -8278,10 +8675,10 @@ const deleteSsoProvider = (options) => {
8278
8675
  const markSsoProviderDomainVerified = (options) => {
8279
8676
  return createAuthEndpoint("/dash/organization/:id/sso-provider/mark-domain-verified", {
8280
8677
  method: "POST",
8281
- use: [jwtMiddleware(options, z$1.object({ organizationId: z$1.string() }))],
8282
- body: z$1.object({
8283
- providerId: z$1.string(),
8284
- verified: z$1.literal(false).describe("Clears domain verification. Domains can only be marked verified via DNS (verify-domain).")
8678
+ use: [jwtMiddleware(options, z.object({ organizationId: z.string() }))],
8679
+ body: z.object({
8680
+ providerId: z.string(),
8681
+ verified: z.literal(false).describe("Clears domain verification. Domains can only be marked verified via DNS (verify-domain).")
8285
8682
  })
8286
8683
  }, async (ctx) => {
8287
8684
  requireOrganizationPlugin(ctx);
@@ -8377,7 +8774,7 @@ function buildTotpUri(params) {
8377
8774
  //#region src/routes/two-factor/index.ts
8378
8775
  const enableTwoFactor = (options) => createAuthEndpoint("/dash/enable-two-factor", {
8379
8776
  method: "POST",
8380
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
8777
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8381
8778
  }, async (ctx) => {
8382
8779
  const { userId } = ctx.context.payload;
8383
8780
  const twoFactorPlugin = ctx.context.getPlugin("two-factor");
@@ -8438,7 +8835,7 @@ const enableTwoFactor = (options) => createAuthEndpoint("/dash/enable-two-factor
8438
8835
  });
8439
8836
  const completeTwoFactorSetup = (options) => createAuthEndpoint("/dash/complete-two-factor-setup", {
8440
8837
  method: "POST",
8441
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
8838
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8442
8839
  }, async (ctx) => {
8443
8840
  const { userId } = ctx.context.payload;
8444
8841
  const twoFactorPlugin = ctx.context.getPlugin("two-factor");
@@ -8466,7 +8863,7 @@ const completeTwoFactorSetup = (options) => createAuthEndpoint("/dash/complete-t
8466
8863
  const viewTwoFactorTotpUri = (options) => createAuthEndpoint("/dash/view-two-factor-totp-uri", {
8467
8864
  method: "POST",
8468
8865
  metadata: { scope: "http" },
8469
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
8866
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8470
8867
  }, async (ctx) => {
8471
8868
  const { userId } = ctx.context.payload;
8472
8869
  const twoFactorPlugin = ctx.context.getPlugin("two-factor");
@@ -8504,13 +8901,13 @@ const viewTwoFactorTotpUri = (options) => createAuthEndpoint("/dash/view-two-fac
8504
8901
  });
8505
8902
  const viewBackupCodes = (options) => createAuthEndpoint("/dash/view-backup-codes", {
8506
8903
  method: "POST",
8507
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
8904
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8508
8905
  }, async () => {
8509
8906
  throw new APIError("FORBIDDEN", { message: "Backup codes cannot be viewed after initial setup. Generate new codes instead." });
8510
8907
  });
8511
8908
  const disableTwoFactor = (options) => createAuthEndpoint("/dash/disable-two-factor", {
8512
8909
  method: "POST",
8513
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
8910
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8514
8911
  }, async (ctx) => {
8515
8912
  const { userId } = ctx.context.payload;
8516
8913
  const twoFactorPlugin = ctx.context.getPlugin("two-factor");
@@ -8531,7 +8928,7 @@ const disableTwoFactor = (options) => createAuthEndpoint("/dash/disable-two-fact
8531
8928
  });
8532
8929
  const generateBackupCodes = (options) => createAuthEndpoint("/dash/generate-backup-codes", {
8533
8930
  method: "POST",
8534
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
8931
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8535
8932
  }, async (ctx) => {
8536
8933
  const { userId } = ctx.context.payload;
8537
8934
  const twoFactorPlugin = ctx.context.getPlugin("two-factor");
@@ -8596,13 +8993,13 @@ async function resolveTwoFactorStatus(context, userId, user) {
8596
8993
  }
8597
8994
  //#endregion
8598
8995
  //#region src/routes/users/schemas.ts
8599
- const DENIED_USER_WRITE_KEYS = new Set([
8996
+ const DENIED_USER_WRITE_KEYS = /* @__PURE__ */ new Set([
8600
8997
  "id",
8601
8998
  "createdAt",
8602
8999
  "updatedAt"
8603
9000
  ]);
8604
9001
  /** Fields that must be changed through dedicated permission-checked endpoints. */
8605
- const DENIED_SENSITIVE_USER_KEYS = new Set([
9002
+ const DENIED_SENSITIVE_USER_KEYS = /* @__PURE__ */ new Set([
8606
9003
  "banned",
8607
9004
  "banReason",
8608
9005
  "banExpires",
@@ -8611,7 +9008,7 @@ const DENIED_SENSITIVE_USER_KEYS = new Set([
8611
9008
  "twoFactorEnabled",
8612
9009
  "twoFactorSecret"
8613
9010
  ]);
8614
- const CREATE_REQUEST_ONLY_KEYS = new Set([
9011
+ const CREATE_REQUEST_ONLY_KEYS = /* @__PURE__ */ new Set([
8615
9012
  "password",
8616
9013
  "generatePassword",
8617
9014
  "sendVerificationEmail",
@@ -8667,7 +9064,7 @@ function getWritableUserFieldNames(options, mode) {
8667
9064
  */
8668
9065
  function pickWritableUserFields(body, options, mode) {
8669
9066
  const allowed = getWritableUserFieldNames(options, mode);
8670
- const skip = new Set([
9067
+ const skip = /* @__PURE__ */ new Set([
8671
9068
  ...DENIED_USER_WRITE_KEYS,
8672
9069
  ...DENIED_SENSITIVE_USER_KEYS,
8673
9070
  ...mode === "create" ? CREATE_REQUEST_ONLY_KEYS : []
@@ -8679,32 +9076,32 @@ function pickWritableUserFields(body, options, mode) {
8679
9076
  }
8680
9077
  return result;
8681
9078
  }
8682
- const BaseCreateUserCoreBodySchema = z$1.object({
8683
- name: z$1.string(),
8684
- email: z$1.email(),
8685
- image: z$1.string().optional(),
8686
- password: z$1.string().optional(),
8687
- generatePassword: z$1.boolean().optional(),
8688
- emailVerified: z$1.boolean().optional(),
8689
- sendVerificationEmail: z$1.boolean().optional(),
8690
- sendOrganizationInvite: z$1.boolean().optional(),
8691
- organizationRole: z$1.string().optional(),
8692
- organizationId: z$1.string().optional()
9079
+ const BaseCreateUserCoreBodySchema = z.object({
9080
+ name: z.string(),
9081
+ email: z.email(),
9082
+ image: z.string().optional(),
9083
+ password: z.string().optional(),
9084
+ generatePassword: z.boolean().optional(),
9085
+ emailVerified: z.boolean().optional(),
9086
+ sendVerificationEmail: z.boolean().optional(),
9087
+ sendOrganizationInvite: z.boolean().optional(),
9088
+ organizationRole: z.string().optional(),
9089
+ organizationId: z.string().optional()
8693
9090
  });
8694
- const BaseUpdateUserCoreBodySchema = z$1.object({
8695
- name: z$1.string().nullable().optional(),
8696
- email: z$1.email().optional(),
8697
- image: z$1.string().nullable().optional(),
8698
- emailVerified: z$1.boolean().optional()
9091
+ const BaseUpdateUserCoreBodySchema = z.object({
9092
+ name: z.string().nullable().optional(),
9093
+ email: z.email().optional(),
9094
+ image: z.string().nullable().optional(),
9095
+ emailVerified: z.boolean().optional()
8699
9096
  });
8700
- const CreateUserBodySchema = BaseCreateUserCoreBodySchema.catchall(z$1.unknown());
8701
- const UpdateUserBodySchema = BaseUpdateUserCoreBodySchema.catchall(z$1.unknown());
9097
+ const CreateUserBodySchema = BaseCreateUserCoreBodySchema.catchall(z.unknown());
9098
+ const UpdateUserBodySchema = BaseUpdateUserCoreBodySchema.catchall(z.unknown());
8702
9099
  function createSchemaForDBField(field) {
8703
9100
  switch (field.type) {
8704
- case "number": return field.required ? z$1.coerce.number() : z$1.coerce.number().optional();
8705
- case "boolean": return field.required ? z$1.coerce.boolean() : z$1.coerce.boolean().optional();
8706
- case "date": return field.required ? z$1.union([z$1.string().min(1), z$1.coerce.date()]) : z$1.union([z$1.string(), z$1.coerce.date()]).optional();
8707
- default: return field.required ? z$1.string().min(1) : z$1.string().optional();
9101
+ case "number": return field.required ? z.coerce.number() : z.coerce.number().optional();
9102
+ case "boolean": return field.required ? z.coerce.boolean() : z.coerce.boolean().optional();
9103
+ case "date": return field.required ? z.union([z.string().min(1), z.coerce.date()]) : z.union([z.string(), z.coerce.date()]).optional();
9104
+ default: return field.required ? z.string().min(1) : z.string().optional();
8708
9105
  }
8709
9106
  }
8710
9107
  /**
@@ -8712,38 +9109,38 @@ function createSchemaForDBField(field) {
8712
9109
  */
8713
9110
  function validateWritableCreateUserFields(data, options) {
8714
9111
  const shape = {
8715
- name: z$1.string().min(1),
8716
- email: z$1.email(),
8717
- image: z$1.string().optional(),
8718
- emailVerified: z$1.boolean().optional()
9112
+ name: z.string().min(1),
9113
+ email: z.email(),
9114
+ image: z.string().optional(),
9115
+ emailVerified: z.boolean().optional()
8719
9116
  };
8720
9117
  for (const [name, field] of Object.entries(getUserInputFields(options))) {
8721
9118
  if (!isWritableUserInputField(field)) continue;
8722
9119
  shape[name] = createSchemaForDBField(field);
8723
9120
  }
8724
- const result = z$1.object(shape).strict().safeParse(data);
9121
+ const result = z.object(shape).strict().safeParse(data);
8725
9122
  if (!result.success) throw result.error;
8726
9123
  }
8727
9124
  /**
8728
9125
  * Ensures at least one field is present on update and validates additional field types.
8729
9126
  */
8730
9127
  function validateWritableUserUpdateFields(data, options) {
8731
- if (Object.keys(data).length === 0) throw new z$1.ZodError([{
9128
+ if (Object.keys(data).length === 0) throw new z.ZodError([{
8732
9129
  code: "custom",
8733
9130
  message: "No valid fields to update",
8734
9131
  path: []
8735
9132
  }]);
8736
9133
  const shape = {
8737
- name: z$1.string().nullable().optional(),
8738
- email: z$1.email().optional(),
8739
- image: z$1.string().nullable().optional(),
8740
- emailVerified: z$1.boolean().optional()
9134
+ name: z.string().nullable().optional(),
9135
+ email: z.email().optional(),
9136
+ image: z.string().nullable().optional(),
9137
+ emailVerified: z.boolean().optional()
8741
9138
  };
8742
9139
  for (const [name, field] of Object.entries(getUserInputFields(options))) {
8743
9140
  if (!isWritableUserInputField(field)) continue;
8744
9141
  shape[name] = createSchemaForDBField(field);
8745
9142
  }
8746
- const result = z$1.object(shape).partial().strict().safeParse(data);
9143
+ const result = z.object(shape).partial().strict().safeParse(data);
8747
9144
  if (!result.success) throw result.error;
8748
9145
  }
8749
9146
  //#endregion
@@ -8766,13 +9163,13 @@ function clampUserListOffset(value, fallback = 0) {
8766
9163
  if (!Number.isFinite(n)) return fallback;
8767
9164
  return Math.max(0, Math.floor(n));
8768
9165
  }
8769
- const getUsersQuerySchema = z$1.object({
8770
- limit: z$1.number().or(z$1.string().transform(Number)).optional(),
8771
- offset: z$1.number().or(z$1.string().transform(Number)).optional(),
8772
- sortBy: z$1.string().optional(),
8773
- sortOrder: z$1.enum(["asc", "desc"]).optional(),
8774
- where: z$1.string().transform(parseWhereClause).optional(),
8775
- countWhere: z$1.string().transform(parseWhereClause).optional()
9166
+ const getUsersQuerySchema = z.object({
9167
+ limit: z.number().or(z.string().transform(Number)).optional(),
9168
+ offset: z.number().or(z.string().transform(Number)).optional(),
9169
+ sortBy: z.string().optional(),
9170
+ sortOrder: z.enum(["asc", "desc"]).optional(),
9171
+ where: z.string().transform(parseWhereClause).optional(),
9172
+ countWhere: z.string().transform(parseWhereClause).optional()
8776
9173
  }).optional();
8777
9174
  const getUsers = (options) => {
8778
9175
  return createAuthEndpoint("/dash/list-users", {
@@ -8809,7 +9206,7 @@ const getUsers = (options) => {
8809
9206
  model: "user",
8810
9207
  where: [{
8811
9208
  field: "lastActiveAt",
8812
- value: /* @__PURE__ */ new Date(Date.now() - 1e3 * 60 * 2),
9209
+ value: /* @__PURE__ */ new Date(Date.now() - 12e4),
8813
9210
  operator: "gte"
8814
9211
  }]
8815
9212
  }).catch((e) => {
@@ -8867,7 +9264,7 @@ const exportUsers = (options) => {
8867
9264
  const deleteUser = (options) => {
8868
9265
  return createAuthEndpoint("/dash/delete-user", {
8869
9266
  method: "POST",
8870
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
9267
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
8871
9268
  }, async (ctx) => {
8872
9269
  try {
8873
9270
  await ctx.context.adapter.delete({
@@ -8886,7 +9283,7 @@ const deleteUser = (options) => {
8886
9283
  const deleteManyUsers = (options) => {
8887
9284
  return createAuthEndpoint("/dash/delete-many-users", {
8888
9285
  method: "POST",
8889
- use: [jwtMiddleware(options, z$1.object({ userIds: z$1.string().array() }))]
9286
+ use: [jwtMiddleware(options, z.object({ userIds: z.string().array() }))]
8890
9287
  }, async (ctx) => {
8891
9288
  const { userIds } = ctx.context.payload;
8892
9289
  const deletedUserIds = /* @__PURE__ */ new Set();
@@ -8922,11 +9319,11 @@ const deleteManyUsers = (options) => {
8922
9319
  const impersonateUser = (options) => {
8923
9320
  return createAuthEndpoint("/dash/impersonate-user", {
8924
9321
  method: "GET",
8925
- query: z$1.object({ impersonation_token: z$1.string() }),
8926
- use: [jwtMiddleware(options, z$1.object({
8927
- userId: z$1.string(),
9322
+ query: z.object({ impersonation_token: z.string() }),
9323
+ use: [jwtMiddleware(options, z.object({
9324
+ userId: z.string(),
8928
9325
  redirectUrl: safeUrlSchema,
8929
- impersonatedBy: z$1.string().optional()
9326
+ impersonatedBy: z.string().optional()
8930
9327
  }), async (ctx) => {
8931
9328
  return ctx.query.impersonation_token;
8932
9329
  })]
@@ -8936,7 +9333,7 @@ const impersonateUser = (options) => {
8936
9333
  const trustedRedirectUrl = parseTrustedAuthRedirectUrl(ctx, redirectUrl);
8937
9334
  if (!trustedRedirectUrl) throw ctx.error("BAD_REQUEST", { message: "Invalid redirect URL" });
8938
9335
  const session = await ctx.context.internalAdapter.createSession(userId, true, {
8939
- expiresAt: new Date(Date.now() + 1e3 * 60 * 10),
9336
+ expiresAt: new Date(Date.now() + 6e5),
8940
9337
  impersonatedBy: impersonatedBy || void 0
8941
9338
  });
8942
9339
  const user = await ctx.context.internalAdapter.findUserById(userId);
@@ -8951,9 +9348,9 @@ const impersonateUser = (options) => {
8951
9348
  const createUser = (options) => {
8952
9349
  return createAuthEndpoint("/dash/create-user", {
8953
9350
  method: "POST",
8954
- use: [jwtMiddleware(options, z$1.object({
8955
- organizationId: z$1.string().optional(),
8956
- organizationRole: z$1.string().optional()
9351
+ use: [jwtMiddleware(options, z.object({
9352
+ organizationId: z.string().optional(),
9353
+ organizationRole: z.string().optional()
8957
9354
  }))],
8958
9355
  body: CreateUserBodySchema
8959
9356
  }, async (ctx) => {
@@ -8962,7 +9359,7 @@ const createUser = (options) => {
8962
9359
  try {
8963
9360
  validateWritableCreateUserFields(userData, ctx.context.options);
8964
9361
  } catch (error) {
8965
- if (error instanceof z$1.ZodError) throw new APIError("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid user data" });
9362
+ if (error instanceof z.ZodError) throw new APIError("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid user data" });
8966
9363
  throw error;
8967
9364
  }
8968
9365
  const email = normalizeEmail(userData.email, ctx.context);
@@ -9051,8 +9448,8 @@ const createUser = (options) => {
9051
9448
  const setPassword = (options) => {
9052
9449
  return createAuthEndpoint("/dash/set-password", {
9053
9450
  method: "POST",
9054
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))],
9055
- body: z$1.object({ password: z$1.string().min(8) })
9451
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))],
9452
+ body: z.object({ password: z.string().min(8) })
9056
9453
  }, async (ctx) => {
9057
9454
  const { userId } = ctx.context.payload;
9058
9455
  const { password } = ctx.body;
@@ -9073,10 +9470,10 @@ const setPassword = (options) => {
9073
9470
  const unlinkAccount = (options) => {
9074
9471
  return createAuthEndpoint("/dash/unlink-account", {
9075
9472
  method: "POST",
9076
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))],
9077
- body: z$1.object({
9078
- providerId: z$1.string(),
9079
- accountId: z$1.string()
9473
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))],
9474
+ body: z.object({
9475
+ providerId: z.string(),
9476
+ accountId: z.string()
9080
9477
  })
9081
9478
  }, async (ctx) => {
9082
9479
  const { userId } = ctx.context.payload;
@@ -9094,16 +9491,16 @@ const unlinkAccount = (options) => {
9094
9491
  return { success: true };
9095
9492
  });
9096
9493
  };
9097
- const getUserDetailsJwtSchema = z$1.object({
9098
- userId: z$1.string(),
9099
- sessionOnly: z$1.boolean().optional(),
9100
- accountOnly: z$1.boolean().optional()
9494
+ const getUserDetailsJwtSchema = z.object({
9495
+ userId: z.string(),
9496
+ sessionOnly: z.boolean().optional(),
9497
+ accountOnly: z.boolean().optional()
9101
9498
  });
9102
9499
  const getUserDetails = (options) => {
9103
9500
  return createAuthEndpoint("/dash/user", {
9104
9501
  method: "GET",
9105
9502
  use: [jwtMiddleware(options, getUserDetailsJwtSchema)],
9106
- query: z$1.object({ minimal: z$1.boolean().or(z$1.string().transform((val) => val === "true")).optional() }).optional()
9503
+ query: z.object({ minimal: z.boolean().or(z.string().transform((val) => val === "true")).optional() }).optional()
9107
9504
  }, async (ctx) => {
9108
9505
  const { userId, sessionOnly, accountOnly } = ctx.context.payload;
9109
9506
  const minimal = !!ctx.query?.minimal;
@@ -9200,7 +9597,7 @@ const getUserDetails = (options) => {
9200
9597
  const getUserOrganizations = (options) => {
9201
9598
  return createAuthEndpoint("/dash/user-organizations", {
9202
9599
  method: "GET",
9203
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
9600
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
9204
9601
  }, async (ctx) => {
9205
9602
  const { userId } = ctx.context.payload;
9206
9603
  if (!isOrganizationEnabled(ctx)) {
@@ -9245,7 +9642,7 @@ const getUserOrganizations = (options) => {
9245
9642
  };
9246
9643
  const updateUser = (options) => createAuthEndpoint("/dash/update-user", {
9247
9644
  method: "POST",
9248
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))],
9645
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))],
9249
9646
  body: UpdateUserBodySchema
9250
9647
  }, async (ctx) => {
9251
9648
  const userId = ctx.context.payload?.userId;
@@ -9254,7 +9651,7 @@ const updateUser = (options) => createAuthEndpoint("/dash/update-user", {
9254
9651
  try {
9255
9652
  validateWritableUserUpdateFields(updateData, ctx.context.options);
9256
9653
  } catch (error) {
9257
- if (error instanceof z$1.ZodError) throw new APIError("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid user data" });
9654
+ if (error instanceof z.ZodError) throw new APIError("BAD_REQUEST", { message: error.issues[0]?.message ?? "Invalid user data" });
9258
9655
  throw error;
9259
9656
  }
9260
9657
  const user = await ctx.context.internalAdapter.updateUser(userId, {
@@ -9340,12 +9737,12 @@ const getUserStats = (options) => createAuthEndpoint("/dash/user-stats", {
9340
9737
  use: [jwtMiddleware(options)]
9341
9738
  }, async (ctx) => {
9342
9739
  const now = /* @__PURE__ */ new Date();
9343
- const oneDayAgo = /* @__PURE__ */ new Date(now.getTime() - 1440 * 60 * 1e3);
9344
- const twoDaysAgo = /* @__PURE__ */ new Date(now.getTime() - 2880 * 60 * 1e3);
9345
- const oneWeekAgo = /* @__PURE__ */ new Date(now.getTime() - 10080 * 60 * 1e3);
9346
- const twoWeeksAgo = /* @__PURE__ */ new Date(now.getTime() - 336 * 60 * 60 * 1e3);
9347
- const oneMonthAgo = /* @__PURE__ */ new Date(now.getTime() - 720 * 60 * 60 * 1e3);
9348
- const twoMonthsAgo = /* @__PURE__ */ new Date(now.getTime() - 1440 * 60 * 60 * 1e3);
9740
+ const oneDayAgo = /* @__PURE__ */ new Date(now.getTime() - 864e5);
9741
+ const twoDaysAgo = /* @__PURE__ */ new Date(now.getTime() - 1728e5);
9742
+ const oneWeekAgo = /* @__PURE__ */ new Date(now.getTime() - 6048e5);
9743
+ const twoWeeksAgo = /* @__PURE__ */ new Date(now.getTime() - 12096e5);
9744
+ const oneMonthAgo = /* @__PURE__ */ new Date(now.getTime() - 2592e6);
9745
+ const twoMonthsAgo = /* @__PURE__ */ new Date(now.getTime() - 5184e6);
9349
9746
  const activityTrackingEnabled = !!options.activityTracking?.enabled;
9350
9747
  const storeInSecondaryStorageOnly = isSessionInSecondaryStorageOnly(ctx.context);
9351
9748
  const [rDailySignups, rPrevDaySignups, rWeeklySignups, rPrevWeekSignups, rMonthlySignups, rPrevMonthSignups, rTotalUsers, rActiveDaily, rActivePrevDay, rActiveWeekly, rActivePrevWeek, rActiveMonthly, rActivePrevMonth] = await withConcurrency([
@@ -9480,7 +9877,7 @@ const getUserStats = (options) => createAuthEndpoint("/dash/user-stats", {
9480
9877
  const getUserGraphData = (options) => createAuthEndpoint("/dash/user-graph-data", {
9481
9878
  method: "GET",
9482
9879
  use: [jwtMiddleware(options)],
9483
- query: z$1.object({ period: z$1.enum([
9880
+ query: z.object({ period: z.enum([
9484
9881
  "daily",
9485
9882
  "weekly",
9486
9883
  "monthly"
@@ -9491,7 +9888,7 @@ const getUserGraphData = (options) => createAuthEndpoint("/dash/user-graph-data"
9491
9888
  const activityTrackingEnabled = !!options.activityTracking?.enabled;
9492
9889
  const storeInSecondaryStorageOnly = isSessionInSecondaryStorageOnly(ctx.context);
9493
9890
  const intervals = period === "daily" ? 7 : period === "weekly" ? 8 : 6;
9494
- const msPerInterval = period === "daily" ? 1440 * 60 * 1e3 : period === "weekly" ? 10080 * 60 * 1e3 : 720 * 60 * 60 * 1e3;
9891
+ const msPerInterval = period === "daily" ? 864e5 : period === "weekly" ? 6048e5 : 2592e6;
9495
9892
  const intervalData = [];
9496
9893
  for (let i = intervals - 1; i >= 0; i--) {
9497
9894
  const endDate = new Date(now.getTime() - i * msPerInterval);
@@ -9552,7 +9949,7 @@ const getUserGraphData = (options) => createAuthEndpoint("/dash/user-graph-data"
9552
9949
  const getUserRetentionData = (options) => createAuthEndpoint("/dash/user-retention-data", {
9553
9950
  method: "GET",
9554
9951
  use: [jwtMiddleware(options)],
9555
- query: z$1.object({ period: z$1.enum([
9952
+ query: z.object({ period: z.enum([
9556
9953
  "daily",
9557
9954
  "weekly",
9558
9955
  "monthly"
@@ -9724,11 +10121,11 @@ const getUserRetentionData = (options) => createAuthEndpoint("/dash/user-retenti
9724
10121
  });
9725
10122
  const banUser = (options) => createAuthEndpoint("/dash/ban-user", {
9726
10123
  method: "POST",
9727
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))],
9728
- body: z$1.object({
9729
- banReason: z$1.string().optional(),
9730
- banExpires: z$1.number().optional(),
9731
- deleteAllSessions: z$1.boolean().optional().default(true)
10124
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))],
10125
+ body: z.object({
10126
+ banReason: z.string().optional(),
10127
+ banExpires: z.number().optional(),
10128
+ deleteAllSessions: z.boolean().optional().default(true)
9732
10129
  })
9733
10130
  }, async (ctx) => {
9734
10131
  const { userId } = ctx.context.payload;
@@ -9746,11 +10143,11 @@ const banUser = (options) => createAuthEndpoint("/dash/ban-user", {
9746
10143
  const banManyUsers = (options) => {
9747
10144
  return createAuthEndpoint("/dash/ban-many-users", {
9748
10145
  method: "POST",
9749
- use: [jwtMiddleware(options, z$1.object({ userIds: z$1.string().array() }))],
9750
- body: z$1.object({
9751
- banReason: z$1.string().optional(),
9752
- banExpires: z$1.number().optional(),
9753
- deleteAllSessions: z$1.boolean().optional().default(true)
10146
+ use: [jwtMiddleware(options, z.object({ userIds: z.string().array() }))],
10147
+ body: z.object({
10148
+ banReason: z.string().optional(),
10149
+ banExpires: z.number().optional(),
10150
+ deleteAllSessions: z.boolean().optional().default(true)
9754
10151
  })
9755
10152
  }, async (ctx) => {
9756
10153
  const { userIds } = ctx.context.payload;
@@ -9800,7 +10197,7 @@ const banManyUsers = (options) => {
9800
10197
  };
9801
10198
  const unbanUser = (options) => createAuthEndpoint("/dash/unban-user", {
9802
10199
  method: "POST",
9803
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))]
10200
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))]
9804
10201
  }, async (ctx) => {
9805
10202
  const { userId } = ctx.context.payload;
9806
10203
  if (!await ctx.context.internalAdapter.findUserById(userId)) throw new APIError("NOT_FOUND", { message: "User not found" });
@@ -9814,8 +10211,8 @@ const unbanUser = (options) => createAuthEndpoint("/dash/unban-user", {
9814
10211
  });
9815
10212
  const sendVerificationEmail = (options) => createAuthEndpoint("/dash/send-verification-email", {
9816
10213
  method: "POST",
9817
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))],
9818
- body: z$1.object({ callbackUrl: safeUrlSchema })
10214
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))],
10215
+ body: z.object({ callbackUrl: safeUrlSchema })
9819
10216
  }, async (ctx) => {
9820
10217
  const { userId } = ctx.context.payload;
9821
10218
  const callbackUrl = requireTrustedAuthCallbackUrl(ctx, ctx.body.callbackUrl);
@@ -9824,20 +10221,21 @@ const sendVerificationEmail = (options) => createAuthEndpoint("/dash/send-verifi
9824
10221
  if (user.emailVerified) throw ctx.error("BAD_REQUEST", { message: "Email is already verified" });
9825
10222
  if (!user.email) throw ctx.error("BAD_REQUEST", { message: "User has no associated email address" });
9826
10223
  if (!ctx.context.options.emailVerification?.sendVerificationEmail) throw ctx.error("BAD_REQUEST", { message: "Email verification is not enabled" });
9827
- await sendVerificationEmailFn({
10224
+ const modifiedCtx = {
9828
10225
  ...ctx,
9829
10226
  body: {
9830
10227
  ...ctx.body,
9831
10228
  callbackURL: callbackUrl
9832
10229
  }
9833
- }, user);
10230
+ };
10231
+ await sendVerificationEmailFn(modifiedCtx, user);
9834
10232
  return { success: true };
9835
10233
  });
9836
10234
  const sendManyVerificationEmails = (options) => {
9837
10235
  return createAuthEndpoint("/dash/send-many-verification-emails", {
9838
10236
  method: "POST",
9839
- use: [jwtMiddleware(options, z$1.object({ userIds: z$1.string().array() }))],
9840
- body: z$1.object({ callbackUrl: safeUrlSchema })
10237
+ use: [jwtMiddleware(options, z.object({ userIds: z.string().array() }))],
10238
+ body: z.object({ callbackUrl: safeUrlSchema })
9841
10239
  }, async (ctx) => {
9842
10240
  if (!ctx.context.options.emailVerification?.sendVerificationEmail) throw ctx.error("BAD_REQUEST", { message: "Email verification is not enabled" });
9843
10241
  const { userIds } = ctx.context.payload;
@@ -9881,9 +10279,10 @@ const sendManyVerificationEmails = (options) => {
9881
10279
  success: true,
9882
10280
  id: user.id
9883
10281
  };
9884
- }))) if (result.status === "fulfilled") if (result.value.success) sentEmailUserIds.add(result.value.id);
9885
- else skippedEmailUserIds.add(result.value.id);
9886
- else for (const { id } of users) skippedEmailUserIds.add(id);
10282
+ }))) if (result.status === "fulfilled") {
10283
+ if (result.value.success) sentEmailUserIds.add(result.value.id);
10284
+ else skippedEmailUserIds.add(result.value.id);
10285
+ } else for (const { id } of users) skippedEmailUserIds.add(id);
9887
10286
  }, { concurrency: 2 });
9888
10287
  const end = performance.now();
9889
10288
  console.log(`Time taken to send verification emails to ${sentEmailUserIds.size} users: ${Math.round((end - start) / 1e3)}s`, skippedEmailUserIds.size > 0 ? `Skipped: ${skippedEmailUserIds.size}` : "");
@@ -9896,8 +10295,8 @@ const sendManyVerificationEmails = (options) => {
9896
10295
  };
9897
10296
  const sendResetPasswordEmail = (options) => createAuthEndpoint("/dash/send-reset-password-email", {
9898
10297
  method: "POST",
9899
- use: [jwtMiddleware(options, z$1.object({ userId: z$1.string() }))],
9900
- body: z$1.object({ callbackUrl: safeUrlSchema })
10298
+ use: [jwtMiddleware(options, z.object({ userId: z.string() }))],
10299
+ body: z.object({ callbackUrl: safeUrlSchema })
9901
10300
  }, async (ctx) => {
9902
10301
  const { userId } = ctx.context.payload;
9903
10302
  const callbackUrl = requireTrustedAuthCallbackUrl(ctx, ctx.body.callbackUrl);
@@ -9910,19 +10309,17 @@ const sendResetPasswordEmail = (options) => createAuthEndpoint("/dash/send-reset
9910
10309
  });
9911
10310
  //#endregion
9912
10311
  //#region src/pow.ts
10312
+ /**
10313
+ * Proof of Work Challenge System - Client Side
10314
+ *
10315
+ * Client-side PoW solver and encoding utilities.
10316
+ * Server-side challenge generation and verification moved to Infra API.
10317
+ */
9913
10318
  /** Default difficulty in bits (18 = ~500ms solve time) */
9914
10319
  const DEFAULT_DIFFICULTY = 18;
9915
10320
  /** Challenge TTL in seconds */
9916
10321
  const CHALLENGE_TTL = 60;
9917
10322
  /**
9918
- * SHA-256 hash function that works in both Node.js and browser
9919
- */
9920
- async function sha256(message) {
9921
- const msgBuffer = new TextEncoder().encode(message);
9922
- const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
9923
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
9924
- }
9925
- /**
9926
10323
  * Check if a hash has the required number of leading zero bits
9927
10324
  */
9928
10325
  function hasLeadingZeroBits(hash, bits) {
@@ -9942,7 +10339,8 @@ async function solvePoWChallenge(challenge) {
9942
10339
  const { nonce, difficulty } = challenge;
9943
10340
  let counter = 0;
9944
10341
  while (true) {
9945
- if (hasLeadingZeroBits(await sha256(`${nonce}:${counter}`), difficulty)) return {
10342
+ const input = `${nonce}:${counter}`;
10343
+ if (hasLeadingZeroBits(await hash$1(input), difficulty)) return {
9946
10344
  nonce,
9947
10345
  counter
9948
10346
  };
@@ -9972,7 +10370,8 @@ function encodePoWSolution(solution) {
9972
10370
  * Verify a PoW solution locally (for testing purposes)
9973
10371
  */
9974
10372
  async function verifyPoWSolution(nonce, counter, difficulty) {
9975
- return hasLeadingZeroBits(await sha256(`${nonce}:${counter}`), difficulty);
10373
+ const input = `${nonce}:${counter}`;
10374
+ return hasLeadingZeroBits(await hash$1(input), difficulty);
9976
10375
  }
9977
10376
  //#endregion
9978
10377
  //#region src/sms.ts
@@ -10167,85 +10566,117 @@ const dash = (options) => {
10167
10566
  const afterCreateOrganization = organizationHooks.afterCreateOrganization;
10168
10567
  organizationHooks.afterCreateOrganization = async (...args) => {
10169
10568
  const [{ organization, user }] = args;
10170
- trackOrganizationCreated(organization, getOrganizationTriggerInfo(user), await getRequestLocation());
10569
+ const trigger = getOrganizationTriggerInfo(user);
10570
+ const location = await getRequestLocation();
10571
+ trackOrganizationCreated(organization, trigger, location);
10171
10572
  if (afterCreateOrganization) return afterCreateOrganization(...args);
10172
10573
  };
10173
10574
  const afterUpdateOrganization = organizationHooks.afterUpdateOrganization;
10174
10575
  organizationHooks.afterUpdateOrganization = async (...args) => {
10175
10576
  const [{ organization, user }] = args;
10176
- if (organization) trackOrganizationUpdated(organization, getOrganizationTriggerInfo(user), await getRequestLocation());
10577
+ if (organization) {
10578
+ const trigger = getOrganizationTriggerInfo(user);
10579
+ const location = await getRequestLocation();
10580
+ trackOrganizationUpdated(organization, trigger, location);
10581
+ }
10177
10582
  if (afterUpdateOrganization) return afterUpdateOrganization(...args);
10178
10583
  };
10179
10584
  const afterAddMember = organizationHooks.afterAddMember;
10180
10585
  organizationHooks.afterAddMember = async (...args) => {
10181
10586
  const [{ organization, member, user }] = args;
10182
- trackOrganizationMemberAdded(organization, member, user, getOrganizationTriggerInfo(user), await getRequestLocation());
10587
+ const trigger = getOrganizationTriggerInfo(user);
10588
+ const location = await getRequestLocation();
10589
+ trackOrganizationMemberAdded(organization, member, user, trigger, location);
10183
10590
  if (afterAddMember) return afterAddMember(...args);
10184
10591
  };
10185
10592
  const afterRemoveMember = organizationHooks.afterRemoveMember;
10186
10593
  organizationHooks.afterRemoveMember = async (...args) => {
10187
10594
  const [{ organization, member, user }] = args;
10188
- trackOrganizationMemberRemoved(organization, member, user, getOrganizationTriggerInfo(user), await getRequestLocation());
10595
+ const trigger = getOrganizationTriggerInfo(user);
10596
+ const location = await getRequestLocation();
10597
+ trackOrganizationMemberRemoved(organization, member, user, trigger, location);
10189
10598
  if (afterRemoveMember) return afterRemoveMember(...args);
10190
10599
  };
10191
10600
  const afterUpdateMemberRole = organizationHooks.afterUpdateMemberRole;
10192
10601
  organizationHooks.afterUpdateMemberRole = async (...args) => {
10193
10602
  const [{ organization, member, user, previousRole }] = args;
10194
- trackOrganizationMemberRoleUpdated(organization, member, user, previousRole, getOrganizationTriggerInfo(user), await getRequestLocation());
10603
+ const trigger = getOrganizationTriggerInfo(user);
10604
+ const location = await getRequestLocation();
10605
+ trackOrganizationMemberRoleUpdated(organization, member, user, previousRole, trigger, location);
10195
10606
  if (afterUpdateMemberRole) return afterUpdateMemberRole(...args);
10196
10607
  };
10197
10608
  const afterCreateInvitation = organizationHooks.afterCreateInvitation;
10198
10609
  organizationHooks.afterCreateInvitation = async (...args) => {
10199
10610
  const [{ organization, invitation, inviter }] = args;
10200
- trackOrganizationMemberInvited(organization, invitation, inviter, getOrganizationTriggerInfo(inviter), await getRequestLocation());
10611
+ const trigger = getOrganizationTriggerInfo(inviter);
10612
+ const location = await getRequestLocation();
10613
+ trackOrganizationMemberInvited(organization, invitation, inviter, trigger, location);
10201
10614
  if (afterCreateInvitation) return afterCreateInvitation(...args);
10202
10615
  };
10203
10616
  const afterAcceptInvitation = organizationHooks.afterAcceptInvitation;
10204
10617
  organizationHooks.afterAcceptInvitation = async (...args) => {
10205
10618
  const [{ organization, invitation, member, user }] = args;
10206
- trackOrganizationMemberInviteAccepted(organization, invitation, member, user, getOrganizationTriggerInfo(user), await getRequestLocation());
10619
+ const trigger = getOrganizationTriggerInfo(user);
10620
+ const location = await getRequestLocation();
10621
+ trackOrganizationMemberInviteAccepted(organization, invitation, member, user, trigger, location);
10207
10622
  if (afterAcceptInvitation) return afterAcceptInvitation(...args);
10208
10623
  };
10209
10624
  const afterRejectInvitation = organizationHooks.afterRejectInvitation;
10210
10625
  organizationHooks.afterRejectInvitation = async (...args) => {
10211
10626
  const [{ organization, invitation, user }] = args;
10212
- trackOrganizationMemberInviteRejected(organization, invitation, user, getOrganizationTriggerInfo(user), await getRequestLocation());
10627
+ const trigger = getOrganizationTriggerInfo(user);
10628
+ const location = await getRequestLocation();
10629
+ trackOrganizationMemberInviteRejected(organization, invitation, user, trigger, location);
10213
10630
  if (afterRejectInvitation) return afterRejectInvitation(...args);
10214
10631
  };
10215
10632
  const afterCancelInvitation = organizationHooks.afterCancelInvitation;
10216
10633
  organizationHooks.afterCancelInvitation = async (...args) => {
10217
10634
  const [{ organization, invitation, cancelledBy }] = args;
10218
- trackOrganizationMemberInviteCanceled(organization, invitation, cancelledBy, getOrganizationTriggerInfo(cancelledBy), await getRequestLocation());
10635
+ const trigger = getOrganizationTriggerInfo(cancelledBy);
10636
+ const location = await getRequestLocation();
10637
+ trackOrganizationMemberInviteCanceled(organization, invitation, cancelledBy, trigger, location);
10219
10638
  if (afterCancelInvitation) return afterCancelInvitation(...args);
10220
10639
  };
10221
10640
  const afterCreateTeam = organizationHooks.afterCreateTeam;
10222
10641
  organizationHooks.afterCreateTeam = async (...args) => {
10223
10642
  const [{ organization, team, user }] = args;
10224
- trackOrganizationTeamCreated(organization, team, getOrganizationTriggerInfo(user), await getRequestLocation());
10643
+ const trigger = getOrganizationTriggerInfo(user);
10644
+ const location = await getRequestLocation();
10645
+ trackOrganizationTeamCreated(organization, team, trigger, location);
10225
10646
  if (afterCreateTeam) return afterCreateTeam(...args);
10226
10647
  };
10227
10648
  const afterUpdateTeam = organizationHooks.afterUpdateTeam;
10228
10649
  organizationHooks.afterUpdateTeam = async (...args) => {
10229
10650
  const [{ organization, team, user }] = args;
10230
- if (team) trackOrganizationTeamUpdated(organization, team, getOrganizationTriggerInfo(user), await getRequestLocation());
10651
+ if (team) {
10652
+ const trigger = getOrganizationTriggerInfo(user);
10653
+ const location = await getRequestLocation();
10654
+ trackOrganizationTeamUpdated(organization, team, trigger, location);
10655
+ }
10231
10656
  if (afterUpdateTeam) return afterUpdateTeam(...args);
10232
10657
  };
10233
10658
  const afterDeleteTeam = organizationHooks.afterDeleteTeam;
10234
10659
  organizationHooks.afterDeleteTeam = async (...args) => {
10235
10660
  const [{ organization, team, user }] = args;
10236
- trackOrganizationTeamDeleted(organization, team, getOrganizationTriggerInfo(user), await getRequestLocation());
10661
+ const trigger = getOrganizationTriggerInfo(user);
10662
+ const location = await getRequestLocation();
10663
+ trackOrganizationTeamDeleted(organization, team, trigger, location);
10237
10664
  if (afterDeleteTeam) return afterDeleteTeam(...args);
10238
10665
  };
10239
10666
  const afterAddTeamMember = organizationHooks.afterAddTeamMember;
10240
10667
  organizationHooks.afterAddTeamMember = async (...args) => {
10241
10668
  const [{ organization, team, user, teamMember }] = args;
10242
- trackOrganizationTeamMemberAdded(organization, team, user, teamMember, getOrganizationTriggerInfo(user), await getRequestLocation());
10669
+ const trigger = getOrganizationTriggerInfo(user);
10670
+ const location = await getRequestLocation();
10671
+ trackOrganizationTeamMemberAdded(organization, team, user, teamMember, trigger, location);
10243
10672
  if (afterAddTeamMember) return afterAddTeamMember(...args);
10244
10673
  };
10245
10674
  const afterRemoveTeamMember = organizationHooks.afterRemoveTeamMember;
10246
10675
  organizationHooks.afterRemoveTeamMember = async (...args) => {
10247
10676
  const [{ organization, team, user, teamMember }] = args;
10248
- trackOrganizationTeamMemberRemoved(organization, team, user, teamMember, getOrganizationTriggerInfo(user), await getRequestLocation());
10677
+ const trigger = getOrganizationTriggerInfo(user);
10678
+ const location = await getRequestLocation();
10679
+ trackOrganizationTeamMemberRemoved(organization, team, user, teamMember, trigger, location);
10249
10680
  if (afterRemoveTeamMember) return afterRemoveTeamMember(...args);
10250
10681
  };
10251
10682
  };
@@ -10368,7 +10799,10 @@ const dash = (options) => {
10368
10799
  }
10369
10800
  } else if (matchesAnyRoute(path, [routes.SIGN_OUT])) trackUserSignedOut(enrichedSession, trigger, ctx, location, eventUser);
10370
10801
  else trackSessionRevoked(enrichedSession, trigger, ctx, location, eventUser);
10371
- if ("impersonatedBy" in session && session.impersonatedBy) trackUserImpersonationStop(enrichedSession, trigger, ctx, location, eventUser, resolveUserFromContext(session.impersonatedBy, ctx));
10802
+ if ("impersonatedBy" in session && session.impersonatedBy) {
10803
+ const knownImpersonator = resolveUserFromContext(session.impersonatedBy, ctx);
10804
+ trackUserImpersonationStop(enrichedSession, trigger, ctx, location, eventUser, knownImpersonator);
10805
+ }
10372
10806
  } }
10373
10807
  },
10374
10808
  account: {
@@ -10407,14 +10841,16 @@ const dash = (options) => {
10407
10841
  const ctx = _ctx;
10408
10842
  if (!ctx) return;
10409
10843
  const path = ctx.path;
10410
- const trigger = getTriggerInfo(ctx, ctx.context.session?.user.id ?? "unknown");
10844
+ const maybeUserId = ctx.context.session?.user.id ?? "unknown";
10845
+ const trigger = getTriggerInfo(ctx, maybeUserId);
10411
10846
  const location = ctx.context.location;
10412
10847
  if (matchesAnyRoute(path, [routes.REQUEST_PASSWORD_RESET])) trackPasswordResetRequest(verification, trigger, ctx, location);
10413
10848
  } },
10414
10849
  delete: { async after(verification, ctx) {
10415
10850
  if (!ctx) return;
10416
10851
  const path = ctx.path;
10417
- const trigger = getTriggerInfo(ctx, ctx.context.session?.user.id ?? "unknown");
10852
+ const maybeUserId = ctx.context.session?.user.id ?? "unknown";
10853
+ const trigger = getTriggerInfo(ctx, maybeUserId);
10418
10854
  const location = ctx.context.location;
10419
10855
  if (matchesAnyRoute(path, [routes.RESET_PASSWORD])) trackPasswordResetRequestCompletion(verification, trigger, ctx, location);
10420
10856
  } }
@@ -10425,18 +10861,7 @@ const dash = (options) => {
10425
10861
  },
10426
10862
  hooks: {
10427
10863
  before: [{
10428
- matcher: (ctx) => {
10429
- if (ctx.request?.method !== "GET") return true;
10430
- return matchesAnyRoute(ctx.path, [
10431
- routes.SIGN_IN_SOCIAL_CALLBACK,
10432
- routes.SIGN_IN_OAUTH_CALLBACK,
10433
- routes.DASH_IMPERSONATE_USER,
10434
- routes.VERIFY_EMAIL,
10435
- routes.MAGIC_LINK_VERIFY,
10436
- routes.DASH_ACCEPT_INVITATION,
10437
- routes.DASH_COMPLETE_INVITATION_SOCIAL
10438
- ]);
10439
- },
10864
+ matcher: (ctx) => shouldRunIdentification(ctx, IDENTIFICATION_GET_ROUTES),
10440
10865
  handler: createIdentificationMiddleware($kv, {
10441
10866
  skipIdentification: (ctx) => isDashRoute(ctx.path),
10442
10867
  retry: opts.kvOptions.retry
@@ -10462,25 +10887,19 @@ const dash = (options) => {
10462
10887
  },
10463
10888
  handler: createAuthMiddleware(async (_ctx) => {
10464
10889
  const ctx = _ctx;
10465
- const trigger = getTriggerInfo(ctx, ctx.context.session?.user.id ?? "unknown");
10890
+ const maybeUserId = ctx.context.session?.user.id ?? "unknown";
10891
+ const trigger = getTriggerInfo(ctx, maybeUserId);
10466
10892
  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);
10467
10893
  const body = ctx.body;
10468
10894
  if (matchesAnyRoute(ctx.path, [routes.SIGN_IN_EMAIL, routes.SIGN_IN_EMAIL_OTP]) && ctx.context.returned instanceof Error && body?.email) trackEmailSignInAttempt(ctx, trigger, ctx.context.location);
10469
10895
  if (matchesAnyRoute(ctx.path, [routes.SIGN_IN_SOCIAL]) && ctx.context.returned instanceof Error && ctx.body.provider && ctx.body.idToken) trackSocialSignInAttempt(ctx, trigger, ctx.context.location);
10470
10896
  if (matchesAnyRoute(ctx.path, [routes.SIGN_IN_SOCIAL_CALLBACK, routes.SIGN_IN_OAUTH_CALLBACK]) && ctx.request?.method === "GET" && !ctx.context.newSession) trackSocialSignInRedirectionAttempt(ctx, trigger, ctx.context.location);
10471
- const headerRequestId = ctx.request?.headers.get("X-Request-Id");
10472
- if (headerRequestId) ctx.setCookie(IDENTIFICATION_COOKIE_NAME, headerRequestId, {
10473
- maxAge: 600,
10474
- sameSite: "lax",
10475
- httpOnly: true,
10476
- path: "/"
10477
- });
10478
- else if (ctx.context.requestId) ctx.setCookie(IDENTIFICATION_COOKIE_NAME, "", {
10479
- maxAge: 0,
10480
- path: "/"
10481
- });
10482
10897
  })
10483
10898
  },
10899
+ {
10900
+ matcher: (ctx) => shouldRunIdentification(ctx, IDENTIFICATION_GET_ROUTES),
10901
+ handler: createIdentificationCookieAfterMiddleware()
10902
+ },
10484
10903
  {
10485
10904
  handler: createAuthMiddleware(async (ctx) => {
10486
10905
  if (!opts.activityTracking?.enabled) return;