@voyant-travel/auth 0.133.3 → 0.133.5

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/edge.js CHANGED
@@ -18,10 +18,7 @@ function getAuthSecret(realm) {
18
18
  if (realm === "customer") {
19
19
  return process.env.BETTER_AUTH_CUSTOMER_SECRET || "";
20
20
  }
21
- return (process.env.BETTER_AUTH_ADMIN_SECRET ||
22
- process.env.BETTER_AUTH_SECRET ||
23
- process.env.SESSION_CLAIMS_SECRET ||
24
- "");
21
+ return process.env.BETTER_AUTH_ADMIN_SECRET || "";
25
22
  }
26
23
  /**
27
24
  * Unsign a Better Auth cookie value.
package/dist/edge.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"edge.js","sourceRoot":"","sources":["../src/edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EACL,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAQzC,SAAS,aAAa,CAAC,KAA2B;IAChD,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,EAAE,CAAA;IACtD,CAAC;IACD,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,wBAAwB;QACpC,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,OAAO,CAAC,GAAG,CAAC,qBAAqB;QACjC,EAAE,CACH,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,YAAY,CAAC,cAAsB,EAAE,MAAc;IAChE,MAAM,OAAO,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAElD,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAE5B,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;IAEhD,oEAAoE;IACpE,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEpE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAA;IACjC,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAEhF,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IACtF,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;AAC7B,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAgB,EAAE,WAA8B;IACzE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC1C,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAE9B,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,SAAQ;QAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;QAC3C,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAA;QAChD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAQD,MAAM,KAAK,GAAgB;IACzB,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,IAAI;CAChB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAgB,EAChB,UAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAA;IACtC,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU;QACpC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QACtB,CAAC,CAAC,KAAK,KAAK,UAAU;YACpB,CAAC,CAAC,CAAC,+BAA+B,CAAC;YACnC,CAAC,CAAC,CAAC,4BAA4B,EAAE,2BAA2B,CAAC,CAAA;IACjE,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IACzD,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IAE5B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,CAAA;IACrD,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEzB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IAExB,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;IAExB,MAAM,CAAC,GAAG,CAAC,GACT,KAAK,KAAK,UAAU;QAClB,CAAC,CAAC,MAAM,EAAE;aACL,MAAM,CAAC;YACN,SAAS,EAAE,mBAAmB,CAAC,EAAE;YACjC,MAAM,EAAE,mBAAmB,CAAC,MAAM;YAClC,KAAK,EAAE,gBAAgB,CAAC,KAAK;SAC9B,CAAC;aACD,IAAI,CAAC,mBAAmB,CAAC;aACzB,SAAS,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;aAChF,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,EACpC,EAAE,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,CAC9C,CACF;aACA,KAAK,CAAC,CAAC,CAAC;QACb,CAAC,CAAC,MAAM,EAAE;aACL,MAAM,CAAC;YACN,SAAS,EAAE,WAAW,CAAC,EAAE;YACzB,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CAAC;aACD,IAAI,CAAC,WAAW,CAAC;aACjB,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;aACxD,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;aAC/E,KAAK,CAAC,CAAC,CAAC,CAAA;IAEjB,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAA;IAEtB,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAA;AACH,CAAC","sourcesContent":["/**\n * Edge-compatible session check for Next.js middleware.\n *\n * Does NOT import better-auth (which uses eval / new Function via\n * createTelemetry, incompatible with Edge Runtime).\n *\n * Instead it reads the session cookie, unsigns it using the same\n * HMAC-SHA256 scheme that better-call uses, and queries better-auth's\n * `session` + `user` tables directly via the Neon HTTP drizzle adapter.\n *\n * With the identity table collapse, authUser.id IS the userId —\n * no extra identity lookup required.\n */\n\nimport { getDb } from \"@voyant-travel/db\"\nimport {\n authSession,\n authUser,\n customerAuthSession,\n customerAuthUser,\n} from \"@voyant-travel/db/schema/iam\"\nimport { and, eq, gt } from \"drizzle-orm\"\n\nexport interface EdgeAuthRealmOptions {\n realm?: \"admin\" | \"customer\"\n cookieName?: string\n secret?: string\n}\n\nfunction getAuthSecret(realm: \"admin\" | \"customer\"): string {\n if (realm === \"customer\") {\n return process.env.BETTER_AUTH_CUSTOMER_SECRET || \"\"\n }\n return (\n process.env.BETTER_AUTH_ADMIN_SECRET ||\n process.env.BETTER_AUTH_SECRET ||\n process.env.SESSION_CLAIMS_SECRET ||\n \"\"\n )\n}\n\n/**\n * Unsign a Better Auth cookie value.\n *\n * Better Auth (via better-call) signs cookies as:\n * encodeURIComponent(value + \".\" + base64(HMAC-SHA256(value, secret)))\n *\n * This function reverses that: URL-decode, split at last \".\",\n * verify the HMAC-SHA256 signature, and return the raw value.\n */\nasync function unsignCookie(rawCookieValue: string, secret: string): Promise<string | null> {\n const decoded = decodeURIComponent(rawCookieValue)\n\n const lastDot = decoded.lastIndexOf(\".\")\n if (lastDot < 1) return null\n\n const value = decoded.substring(0, lastDot)\n const signature = decoded.substring(lastDot + 1)\n\n // Better Auth signatures are 44-char base64 strings ending with \"=\"\n if (signature.length !== 44 || !signature.endsWith(\"=\")) return null\n\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"verify\"],\n )\n\n const sigBinStr = atob(signature)\n const sigBytes = new Uint8Array(sigBinStr.length)\n for (let i = 0; i < sigBinStr.length; i++) sigBytes[i] = sigBinStr.charCodeAt(i)\n\n const valid = await crypto.subtle.verify(\"HMAC\", key, sigBytes, encoder.encode(value))\n return valid ? value : null\n}\n\nfunction getRawCookieValue(headers: Headers, cookieNames: readonly string[]): string | null {\n const cookieHeader = headers.get(\"cookie\")\n if (!cookieHeader) return null\n\n for (const part of cookieHeader.split(\";\")) {\n const trimmed = part.trim()\n const eqIdx = trimmed.indexOf(\"=\")\n if (eqIdx === -1) continue\n const name = trimmed.slice(0, eqIdx).trim()\n if (cookieNames.includes(name)) {\n return trimmed.slice(eqIdx + 1).trim() || null\n }\n }\n return null\n}\n\ntype AuthContext = {\n userId: string | null\n email: string | null\n sessionId: string | null\n}\n\nconst EMPTY: AuthContext = {\n userId: null,\n email: null,\n sessionId: null,\n}\n\n/**\n * Lightweight edge-compatible session check.\n * Safe to call from Next.js middleware.\n *\n * Returns `userId` which is Better Auth's `user.id` — the single\n * canonical user identifier after the identity table collapse.\n */\nexport async function getAuthContextFromHeaders(\n headers: Headers,\n options: EdgeAuthRealmOptions = {},\n): Promise<AuthContext> {\n const realm = options.realm ?? \"admin\"\n const cookieNames = options.cookieName\n ? [options.cookieName]\n : realm === \"customer\"\n ? [\"voyant-customer.session_token\"]\n : [\"voyant-admin.session_token\", \"better-auth.session_token\"]\n const rawCookie = getRawCookieValue(headers, cookieNames)\n if (!rawCookie) return EMPTY\n\n const secret = options.secret ?? getAuthSecret(realm)\n if (!secret) return EMPTY\n\n const token = await unsignCookie(rawCookie, secret)\n if (!token) return EMPTY\n\n const db = getDb(\"edge\")\n\n const [row] =\n realm === \"customer\"\n ? await db\n .select({\n sessionId: customerAuthSession.id,\n userId: customerAuthSession.userId,\n email: customerAuthUser.email,\n })\n .from(customerAuthSession)\n .innerJoin(customerAuthUser, eq(customerAuthUser.id, customerAuthSession.userId))\n .where(\n and(\n eq(customerAuthSession.token, token),\n gt(customerAuthSession.expiresAt, new Date()),\n ),\n )\n .limit(1)\n : await db\n .select({\n sessionId: authSession.id,\n userId: authSession.userId,\n email: authUser.email,\n })\n .from(authSession)\n .innerJoin(authUser, eq(authUser.id, authSession.userId))\n .where(and(eq(authSession.token, token), gt(authSession.expiresAt, new Date())))\n .limit(1)\n\n if (!row) return EMPTY\n\n return {\n userId: row.userId,\n email: row.email,\n sessionId: row.sessionId,\n }\n}\n"]}
1
+ {"version":3,"file":"edge.js","sourceRoot":"","sources":["../src/edge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Edge-compatible session check for Next.js middleware.\n *\n * Does NOT import better-auth (which uses eval / new Function via\n * createTelemetry, incompatible with Edge Runtime).\n *\n * Instead it reads the session cookie, unsigns it using the same\n * HMAC-SHA256 scheme that better-call uses, and queries better-auth's\n * `session` + `user` tables directly via the Neon HTTP drizzle adapter.\n *\n * With the identity table collapse, authUser.id IS the userId —\n * no extra identity lookup required.\n */\n\nimport { getDb } from \"@voyant-travel/db\"\nimport {\n authSession,\n authUser,\n customerAuthSession,\n customerAuthUser,\n} from \"@voyant-travel/db/schema/iam\"\nimport { and, eq, gt } from \"drizzle-orm\"\n\nexport interface EdgeAuthRealmOptions {\n realm?: \"admin\" | \"customer\"\n cookieName?: string\n secret?: string\n}\n\nfunction getAuthSecret(realm: \"admin\" | \"customer\"): string {\n if (realm === \"customer\") {\n return process.env.BETTER_AUTH_CUSTOMER_SECRET || \"\"\n }\n return process.env.BETTER_AUTH_ADMIN_SECRET || \"\"\n}\n\n/**\n * Unsign a Better Auth cookie value.\n *\n * Better Auth (via better-call) signs cookies as:\n * encodeURIComponent(value + \".\" + base64(HMAC-SHA256(value, secret)))\n *\n * This function reverses that: URL-decode, split at last \".\",\n * verify the HMAC-SHA256 signature, and return the raw value.\n */\nasync function unsignCookie(rawCookieValue: string, secret: string): Promise<string | null> {\n const decoded = decodeURIComponent(rawCookieValue)\n\n const lastDot = decoded.lastIndexOf(\".\")\n if (lastDot < 1) return null\n\n const value = decoded.substring(0, lastDot)\n const signature = decoded.substring(lastDot + 1)\n\n // Better Auth signatures are 44-char base64 strings ending with \"=\"\n if (signature.length !== 44 || !signature.endsWith(\"=\")) return null\n\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"verify\"],\n )\n\n const sigBinStr = atob(signature)\n const sigBytes = new Uint8Array(sigBinStr.length)\n for (let i = 0; i < sigBinStr.length; i++) sigBytes[i] = sigBinStr.charCodeAt(i)\n\n const valid = await crypto.subtle.verify(\"HMAC\", key, sigBytes, encoder.encode(value))\n return valid ? value : null\n}\n\nfunction getRawCookieValue(headers: Headers, cookieNames: readonly string[]): string | null {\n const cookieHeader = headers.get(\"cookie\")\n if (!cookieHeader) return null\n\n for (const part of cookieHeader.split(\";\")) {\n const trimmed = part.trim()\n const eqIdx = trimmed.indexOf(\"=\")\n if (eqIdx === -1) continue\n const name = trimmed.slice(0, eqIdx).trim()\n if (cookieNames.includes(name)) {\n return trimmed.slice(eqIdx + 1).trim() || null\n }\n }\n return null\n}\n\ntype AuthContext = {\n userId: string | null\n email: string | null\n sessionId: string | null\n}\n\nconst EMPTY: AuthContext = {\n userId: null,\n email: null,\n sessionId: null,\n}\n\n/**\n * Lightweight edge-compatible session check.\n * Safe to call from Next.js middleware.\n *\n * Returns `userId` which is Better Auth's `user.id` — the single\n * canonical user identifier after the identity table collapse.\n */\nexport async function getAuthContextFromHeaders(\n headers: Headers,\n options: EdgeAuthRealmOptions = {},\n): Promise<AuthContext> {\n const realm = options.realm ?? \"admin\"\n const cookieNames = options.cookieName\n ? [options.cookieName]\n : realm === \"customer\"\n ? [\"voyant-customer.session_token\"]\n : [\"voyant-admin.session_token\", \"better-auth.session_token\"]\n const rawCookie = getRawCookieValue(headers, cookieNames)\n if (!rawCookie) return EMPTY\n\n const secret = options.secret ?? getAuthSecret(realm)\n if (!secret) return EMPTY\n\n const token = await unsignCookie(rawCookie, secret)\n if (!token) return EMPTY\n\n const db = getDb(\"edge\")\n\n const [row] =\n realm === \"customer\"\n ? await db\n .select({\n sessionId: customerAuthSession.id,\n userId: customerAuthSession.userId,\n email: customerAuthUser.email,\n })\n .from(customerAuthSession)\n .innerJoin(customerAuthUser, eq(customerAuthUser.id, customerAuthSession.userId))\n .where(\n and(\n eq(customerAuthSession.token, token),\n gt(customerAuthSession.expiresAt, new Date()),\n ),\n )\n .limit(1)\n : await db\n .select({\n sessionId: authSession.id,\n userId: authSession.userId,\n email: authUser.email,\n })\n .from(authSession)\n .innerJoin(authUser, eq(authUser.id, authSession.userId))\n .where(and(eq(authSession.token, token), gt(authSession.expiresAt, new Date())))\n .limit(1)\n\n if (!row) return EMPTY\n\n return {\n userId: row.userId,\n email: row.email,\n sessionId: row.sessionId,\n }\n}\n"]}
@@ -19,8 +19,6 @@ export interface OperatorAuthNodeEnv extends NodeDatabaseEnv {
19
19
  API_BASE_URL?: string;
20
20
  APP_URL?: string;
21
21
  AUTH_COOKIE_DOMAIN?: string;
22
- /** @deprecated Use BETTER_AUTH_ADMIN_SECRET. */
23
- BETTER_AUTH_SECRET?: string;
24
22
  BETTER_AUTH_ADMIN_SECRET?: string;
25
23
  BETTER_AUTH_CUSTOMER_SECRET?: string;
26
24
  CORS_ALLOWLIST?: string;
@@ -239,18 +239,16 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
239
239
  * pool. The Better Auth instance is not cached independently of that owner.
240
240
  */
241
241
  function requireAdminAuthSecret(env) {
242
- const secret = env.BETTER_AUTH_ADMIN_SECRET?.trim() || env.BETTER_AUTH_SECRET?.trim();
242
+ const secret = env.BETTER_AUTH_ADMIN_SECRET?.trim();
243
243
  if (!secret)
244
244
  throw new Error("Admin auth requires BETTER_AUTH_ADMIN_SECRET");
245
245
  return secret;
246
246
  }
247
247
  function requireCustomerAuthSecret(env) {
248
248
  const secret = env.BETTER_AUTH_CUSTOMER_SECRET?.trim();
249
- if (secret)
250
- return secret;
251
- // Compatibility bridge for deployments created before realm-specific
252
- // secrets. The suffix gives the customer cookie an independent signature.
253
- return `${requireAdminAuthSecret(env)}:voyant-customer-realm`;
249
+ if (!secret)
250
+ throw new Error("Customer auth requires BETTER_AUTH_CUSTOMER_SECRET");
251
+ return secret;
254
252
  }
255
253
  function envEnabled(value, fallback) {
256
254
  const normalized = value?.trim().toLowerCase();
@@ -505,9 +503,12 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
505
503
  return profile?.permissions ?? FULL_ACCESS_SCOPES;
506
504
  }
507
505
  async function resolveAuthRequest(request, env) {
506
+ const customerSurface = new URL(request.url).pathname.includes("/v1/public/");
507
+ if (customerSurface && env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === "disabled") {
508
+ return null;
509
+ }
508
510
  const { db, dispose } = openDatabase(env);
509
511
  try {
510
- const customerSurface = new URL(request.url).pathname.includes("/v1/public/");
511
512
  const auth = customerSurface
512
513
  ? buildCustomerBetterAuth(env, db, request)
513
514
  : buildAdminBetterAuth(env, db);
@@ -1 +1 @@
1
- {"version":3,"file":"node-runtime.js","sourceRoot":"","sources":["../src/node-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAwB,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAClF,OAAO,EACL,QAAQ,EACR,kBAAkB,EAElB,iBAAiB,GAClB,MAAM,8BAA8B,CAAA;AAErC,OAAO,EACL,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,+CAA+C,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAEhE,OAAO,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAChG,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAgB,IAAI,EAAE,MAAM,MAAM,CAAA;AACzC,OAAO,EACL,gCAAgC,EAChC,qCAAqC,EACrC,kCAAkC,GACnC,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,mCAAmC,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAClG,OAAO,EAGL,qBAAqB,EACrB,wBAAwB,EACxB,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAgEzD,mFAAmF;AACnF,MAAM,UAAU,oCAAoC,CAClD,GAAoD;IAIpD,MAAM,MAAM,GAAG,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAA;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAE7B,OAAO;QACL,qBAAqB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;QAChD,uBAAuB,EAAE,EAAE,MAAM,EAAE;KACpC,CAAA;AACH,CAAC;AAsDD;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,OAA4B,EAC5B,gBAAwB;IAExB,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,CAAA;IACzC,IAAI,CAAC,SAAS;QAAE,OAAO,OAAO,CAAA;IAE9B,MAAM,0BAA0B,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACvE,MAAM,QAAQ,GAAG,CAAC,QAAyC,EAAE,EAAE,CAC7D,GAAG,0BAA0B,2BAA2B,QAAQ,EAAE,CAAA;IACpE,MAAM,eAAe,GAAG,CACtB,QAA8B,EAC9B,WAAmB,EACG,EAAE;QACxB,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAC9D,MAAM,UAAU,GAAG,QAA+C,CAAA;QAClE,OAAO;YACL,GAAG,UAAU;YACb,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,WAAW;SAC3D,CAAA;IACH,CAAC,CAAA;IAED,OAAO;QACL,GAAG,OAAO;QACV,eAAe,EAAE;YACf,GAAG,SAAS;YACZ,GAAG,CAAC,SAAS,CAAC,MAAM;gBAClB,CAAC,CAAC;oBACE,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;iBAC9D;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,SAAS,CAAC,QAAQ;gBACpB,CAAC,CAAC;oBACE,QAAQ,EAAE,eAAe,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;iBACpE;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,SAAS,CAAC,KAAK;gBACjB,CAAC,CAAC;oBACE,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;iBAC3D;gBACH,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,cAAyD;IAIzD,MAAM,YAAY,GAChB,cAAc,CAAC,YAAY;QAC3B,CAAC,CAAC,GAAQ,EAAE,EAAE;YACZ,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;YACtC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAA;QACnE,CAAC,CAAC,CAAA;IAEJ,MAAM,IAAI,GAAG,IAAI,IAAI,EAAe,CAAA;IACpC,iEAAiE;IACjE,0EAA0E;IAC1E,+EAA+E;IAC/E,oEAAoE;IACpE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IACxB,oEAAoE;IACpE,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,wEAAwE;IACxE,8EAA8E;IAC9E,yEAAyE;IACzE,kEAAkE;IAClE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,IAAI,EAAE,CAAA;QACZ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACxB,eAAe,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC,EAAE;gBAC1C,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE;gBAC/B,GAAG,EAAE,cAAc,CAAC,OAAO;gBAC3B,KAAK,EAAE,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAC9D,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;aAC3F,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAC,CAAA;IACF,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CACtB,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,CAAC,CAC/F,CAAA;IAED,MAAM,eAAe,GAAG,uBAAuB,CAAA;IAC/C,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;QAC1C,mBAAmB;QACnB,YAAY;QACZ,eAAe;QACf,gBAAgB;QAChB,aAAa;KACd,CAAC,CAAA;IAEF,SAAS,uBAAuB,CAAC,IAAS;QACxC,OAAO,cAAc,CAAC,QAAQ,CAAA;IAChC,CAAC;IAED,SAAS,qBAAqB,CAAC,GAAQ;QACrC,OAAO,uBAAuB,CAAC,GAAG,CAAC,KAAK,cAAc,CAAA;IACxD,CAAC;IAED,SAAS,6BAA6B,CAAC,OAAgB;QACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAA;QACxF,OAAO,2BAA2B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClD,CAAC;IAED,SAAS,yBAAyB,CAAC,CAAuB;QACxD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0DAA0D,EAAE,EAAE,GAAG,CAAC,CAAA;IAC3F,CAAC;IAED,SAAS,8BAA8B,CAAC,CAAuB;QAC7D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gDAAgD,EAAE,EAAE,GAAG,CAAC,CAAA;IACjF,CAAC;IAED,SAAS,YAAY,CAAC,GAAW;QAC/B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACtC,CAAC;IAED,SAAS,SAAS,CAAC,GAAQ;QACzB,MAAM,UAAU,GAAG;YACjB,GAAG,CAAC,OAAO;YACX,GAAG,CAAC,aAAa;YACjB,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjC,eAAe;SAChB,CAAA;QAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjE,OAAO,YAAY,CAAC,SAAS,CAAC,CAAA;YAChC,CAAC;QACH,CAAC;QAED,OAAO,eAAe,CAAA;IACxB,CAAC;IAED,SAAS,iBAAiB,CAAC,GAAQ;QACjC,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,GAAG,CACL,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;aACvE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;aAC7B,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CACtD,CACF,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IACrB,CAAC;IAED,SAAS,cAAc,CAAC,GAAQ;QAC9B,yEAAyE;QACzE,0EAA0E;QAC1E,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;YAC9B,OAAO,GAAG,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,EAAE,CAAA;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAA;QACf,CAAC;IACH,CAAC;IAED,SAAS,mBAAmB,CAAC,GAAQ;QACnC,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAA;QAC5F,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;QAE1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAA;YAClC,IAAI,MAAM,CAAC,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;gBACtD,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAA;gBACxB,OAAO,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;YACxC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,UAAU,CAAA;QACnB,CAAC;QAED,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,SAAS,uBAAuB,CAAC,GAAQ;QACvC,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE,CAAA;QAC3D,MAAM,iBAAiB,GAAG,GAAG,CAAC,iCAAiC,EAAE,IAAI,EAAE,CAAA;QACvE,IAAI,CAAC,YAAY,IAAI,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAA;QAEpD,OAAO;YACL,iBAAiB;YACjB,YAAY;YACZ,gBAAgB,EAAE,GAAG,mBAAmB,CAAC,GAAG,CAAC,4BAA4B;YACzE,YAAY,EAAE,GAAG,CAAC,qBAAqB;YACvC,KAAK,EAAE,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,SAAS;YACnD,WAAW,EAAE,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,IAAI,SAAS;SAC/D,CAAA;IACH,CAAC;IAED,SAAS,0BAA0B,CAAC,GAAQ;QAC1C,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE,CAAA;QAC3D,MAAM,WAAW,GAAG,GAAG,CAAC,oCAAoC,EAAE,IAAI,EAAE,CAAA;QACpE,MAAM,gBAAgB,GAAG,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,CAAA;QACrE,MAAM,WAAW,GAAG,GAAG,CAAC,oCAAoC,EAAE,IAAI,EAAE,CAAA;QACpE,IAAI,CAAC,YAAY,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QAEnF,OAAO;YACL,WAAW;YACX,YAAY;YACZ,WAAW;YACX,gBAAgB;YAChB,iBAAiB,EAAE,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,IAAI,YAAY;SAChF,CAAA;IACH,CAAC;IAED,SAAS,4BAA4B,CAAC,GAAQ;QAC5C,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE,CAAA;QAC3D,MAAM,aAAa,GAAG,GAAG,CAAC,sCAAsC,EAAE,IAAI,EAAE,CAAA;QACxE,MAAM,WAAW,GAAG,GAAG,CAAC,oCAAoC,EAAE,IAAI,EAAE,CAAA;QACpE,IAAI,CAAC,YAAY,IAAI,CAAC,aAAa,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QAEhE,OAAO;YACL,aAAa;YACb,YAAY;YACZ,WAAW;SACZ,CAAA;IACH,CAAC;IAED,SAAS,cAAc,CAAC,OAAgB;QACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;QAC9C,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,WAAW,CAAA;IAC7D,CAAC;IAED,SAAS,oCAAoC,CAAC,GAAQ,EAAE,OAAgB;QACtE,OAAO,GAAG,CAAC,gCAAgC,KAAK,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAA;IAChF,CAAC;IAED,SAAS,sBAAsB,CAAC,GAAQ;QACtC,OAAO,GAAG,CAAC,gCAAgC,KAAK,GAAG,CAAA;IACrD,CAAC;IAED;;;;;;;;;OASG;IACH,SAAS,sBAAsB,CAAC,GAAQ;QACtC,MAAM,MAAM,GAAG,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAA;QACrF,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAC5E,OAAO,MAAM,CAAA;IACf,CAAC;IAED,SAAS,yBAAyB,CAAC,GAAQ;QACzC,MAAM,MAAM,GAAG,GAAG,CAAC,2BAA2B,EAAE,IAAI,EAAE,CAAA;QACtD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QACzB,qEAAqE;QACrE,0EAA0E;QAC1E,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,wBAAwB,CAAA;IAC/D,CAAC;IAED,SAAS,UAAU,CAAC,KAAyB,EAAE,QAAiB;QAC9D,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC9C,IAAI,CAAC,UAAU;YAAE,OAAO,QAAQ,CAAA;QAChC,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,CAAA;IAC5E,CAAC;IAED,SAAS,uBAAuB,CAAC,GAAQ;QACvC,MAAM,QAAQ,GAAG;YACf,OAAO,EAAE;gBACP,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,+BAA+B,EAAE,IAAI,CAAC;gBAChE,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,mCAAmC,EAAE,IAAI,CAAC;gBACxE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;gBAC/C,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;gBACjD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;aAC/C;SAC2B,CAAA;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,CAAA;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO,QAAQ,CAAA;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAE5B,CAAA;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;YACpC,MAAM,MAAM,GAAG,CAAC,KAAc,EAA4B,EAAE;gBAC1D,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBAChE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,CAAA;gBAChD,CAAC;gBACD,MAAM,MAAM,GAAG,KAAgC,CAAA;gBAC/C,OAAO;oBACL,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI;oBAChC,aAAa,EACX,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE;wBACrE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE;wBAC7B,CAAC,CAAC,IAAI;iBACX,CAAA;YACH,CAAC,CAAA;YACD,OAAO;gBACL,OAAO,EAAE;oBACP,SAAS,EACP,OAAO,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;oBACzF,aAAa,EACX,OAAO,OAAO,CAAC,aAAa,KAAK,SAAS;wBACxC,CAAC,CAAC,OAAO,CAAC,aAAa;wBACvB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa;oBACpC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;oBAC9B,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAClC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;iBAC7B;aACF,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CACX,sFAAsF,CACvF,CAAA;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC;IACH,CAAC;IAED,SAAS,0BAA0B,CACjC,GAAQ,EACR,MAA0B;QAE1B,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,CAAC,CAAA;QAChF,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,CAAC,8BAA8B,EAAE,IAAI,EAAE;YACxC,GAAG,CAAC,kCAAkC,EAAE,IAAI,EAAE;YAC9C,CAAC,CAAC,kBAAkB,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CACzD,CAAA;QACD,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE;YAC1C,GAAG,CAAC,oCAAoC,EAAE,IAAI,EAAE;YAChD,CAAC,CAAC,kBAAkB,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC3D,CAAA;QACD,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,CAAC,6BAA6B,EAAE,IAAI,EAAE;YACvC,GAAG,CAAC,iCAAiC,EAAE,IAAI,EAAE;YAC7C,CAAC,CAAC,kBAAkB,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CACxD,CAAA;QACD,OAAO;YACL,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC;YAC5B,cAAc,EAAE,iBAAiB,CAAC,GAAG,CAAC;YACtC,OAAO,EAAE;gBACP,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;gBACnC,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,aAAa;gBAC3C,eAAe,EAAE;oBACf,GAAG,CAAC,MAAM;wBACR,CAAC,CAAC;4BACE,MAAM,EAAE;gCACN,QAAQ,EAAE,GAAG,CAAC,8BAA+B,CAAC,IAAI,EAAE;gCACpD,YAAY,EAAE,GAAG,CAAC,kCAAmC,CAAC,IAAI,EAAE;6BAC7D;yBACF;wBACH,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,QAAQ;wBACV,CAAC,CAAC;4BACE,QAAQ,EAAE;gCACR,QAAQ,EAAE,GAAG,CAAC,gCAAiC,CAAC,IAAI,EAAE;gCACtD,YAAY,EAAE,GAAG,CAAC,oCAAqC,CAAC,IAAI,EAAE;6BAC/D;yBACF;wBACH,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,KAAK;wBACP,CAAC,CAAC;4BACE,KAAK,EAAE;gCACL,QAAQ,EAAE,GAAG,CAAC,6BAA8B,CAAC,IAAI,EAAE;gCACnD,YAAY,EAAE,GAAG,CAAC,iCAAkC,CAAC,IAAI,EAAE;6BAC5D;yBACF;wBACH,CAAC,CAAC,EAAE,CAAC;iBACR;aACF;SACF,CAAA;IACH,CAAC;IAED,SAAS,0BAA0B,CAAC,GAAQ,EAAE,OAAgB;QAC5D,MAAM,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAA;QAC3C,OAAO,CACL,cAAc,CAAC,0BAA0B,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC;YACjE,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,CACxC,CAAA;IACH,CAAC;IAED,SAAS,+BAA+B,CAAC,GAAQ,EAAE,OAAgB;QACjE,MAAM,OAAO,GAAG,0BAA0B,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,OAAO,CAAA;QAChE,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAA;QAC/C,OAAO;YACL,OAAO,EAAE;gBACP,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;gBACpC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI;gBAC5C,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC;gBACjC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC;gBACrC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;aAChC;SACF,CAAA;IACH,CAAC;IAED,SAAS,oBAAoB,CAAC,GAAQ,EAAE,EAAY;QAClD,MAAM,WAAW,GAAG,cAAc,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAA;QAC5D,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC7F,MAAM,MAAM,GAAG,EAAoE,CAAA;QACnF,MAAM,WAAW,GAAG,EAAkE,CAAA;QAEtF,OAAO,qBAAqB,CAAC;YAC3B,4DAA4D;YAC5D,+DAA+D;YAC/D,4DAA4D;YAC5D,gEAAgE;YAChE,+DAA+D;YAC/D,iDAAiD;YACjD,EAAE,EAAE,MAAM;YACV,MAAM,EAAE,sBAAsB,CAAC,GAAG,CAAC;YACnC,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC;YAC5B,QAAQ,EAAE,aAAa;YACvB,cAAc,EAAE,iBAAiB,CAAC,GAAG,CAAC;YACtC,QAAQ,EAAE,CAAC,cAAc,CAAC,cAAc,IAAI,oCAAoC,CAAC,CAAC,GAAG,CAAC;YACtF,OAAO,EAAE,iBAAiB;gBACxB,CAAC,CAAC;oBACE,gCAAgC,CAAC;wBAC/B,EAAE,EAAE,WAAW;wBACf,YAAY,EAAE,GAAG,CAAC,qBAAqB;wBACvC,QAAQ,EAAE,iBAAiB;qBAC5B,CAAC;iBACH;gBACH,CAAC,CAAC,SAAS;YACb,iBAAiB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;gBACzC,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,wEAAwE;oBACxE,iEAAiE;oBACjE,mEAAmE;oBACnE,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChC,OAAO,CAAC,IAAI,CAAC,6CAA6C,IAAI,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC,CAAA;wBAC/E,OAAM;oBACR,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;gBACpE,CAAC;gBACD,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YACpD,CAAC;YACD,mBAAmB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;gBAClD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,wEAAwE;oBACxE,gEAAgE;oBAChE,mEAAmE;oBACnE,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChC,OAAO,CAAC,IAAI,CAAC,6CAA6C,IAAI,QAAQ,KAAK,KAAK,GAAG,EAAE,CAAC,CAAA;wBACtF,OAAM;oBACR,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;gBACtE,CAAC;gBACD,MAAM,WAAW,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;YAC7D,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,uBAAuB,CAAC,GAAQ,EAAE,EAAY,EAAE,OAAgB;QACvE,MAAM,WAAW,GAAG,cAAc,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAA;QAC5D,MAAM,OAAO,GAAG,0BAA0B,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QACxD,MAAM,MAAM,GAAG,EAAuE,CAAA;QACtF,OAAO,wBAAwB,CAAC;YAC9B,EAAE,EAAE,MAAM;YACV,MAAM,EAAE,yBAAyB,CAAC,GAAG,CAAC;YACtC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,gBAAgB;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,OAAO,EAAE,8BAA8B,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAClF,iBAAiB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;gBACzC,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChC,OAAO,CAAC,IAAI,CAAC,sDAAsD,IAAI,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC,CAAA;wBACxF,OAAM;oBACR,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;gBACpE,CAAC;gBACD,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YACpD,CAAC;YACD,mBAAmB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;gBAClD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChC,OAAO,CAAC,IAAI,CACV,sDAAsD,IAAI,QAAQ,KAAK,KAAK,GAAG,EAAE,CAClF,CAAA;wBACD,OAAM;oBACR,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;gBACtE,CAAC;gBACD,MAAM,WAAW,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;YAC7D,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,6BAA6B,CAAC,OAAgB;QACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;QAC3D,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAClC,CAAC;IAED,MAAM,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAAA;IAEhC,SAAS,qBAAqB,CAAC,IAA+B;QAC5D,MAAM,IAAI,GAAG,0BAA0B,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,CAAA;QAC3E,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QACtB,MAAM,cAAc,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACxD,MAAM,QAAQ,GACZ,cAAc,KAAK,QAAQ;YACzB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,cAAc,KAAK,OAAO;gBAC1B,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,cAAc,CAAA;QACtB,MAAM,QAAQ,GAAG,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CACxD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,EAAE,KAAK,QAAQ,CAC9D,CAAA;QACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACpE,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,UAAU,mBAAmB,CAAC,EAAY,EAAE,GAAQ,EAAE,MAAc;QACvE,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE;iBACpB,MAAM,CAAC,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,CAAC;iBACpF,IAAI,CAAC,kBAAkB,CAAC;iBACxB,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;iBAC5C,KAAK,CAAC,CAAC,CAAC,CAAA;YACX,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,kBAAkB,CAAA;YAC7E,MAAM,UAAU,GAAG,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,gBAAgB,CAAA;YAC5E,OAAO,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,UAAU,CAAC,CAAA;QACrF,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE;aACvB,MAAM,CAAC,EAAE,WAAW,EAAE,iBAAiB,CAAC,WAAW,EAAE,CAAC;aACtD,IAAI,CAAC,iBAAiB,CAAC;aACvB,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;aACvC,KAAK,CAAC,CAAC,CAAC,CAAA;QACX,OAAO,OAAO,EAAE,WAAW,IAAI,kBAAkB,CAAA;IACnD,CAAC;IAED,KAAK,UAAU,kBAAkB,CAC/B,OAAgB,EAChB,GAAQ;QAER,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;YAC7E,MAAM,IAAI,GAAG,eAAe;gBAC1B,CAAC,CAAC,uBAAuB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC;gBAC3C,CAAC,CAAC,oBAAoB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YACjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YAEvE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,IAAI,CAAA;YACb,CAAC;YAED,IAAI,CAAC,eAAe,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,GAAG,CAAC,CAAA;gBAC1D,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAA;gBACb,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,qCAAqC,CAAC;wBAC/D,EAAE,EAAE,EAAuE;wBAC3E,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;wBAC7B,MAAM,EAAE,gBAAgB;qBACzB,CAAC,CAAA;oBAEF,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;wBACrB,OAAO,IAAI,CAAA;oBACb,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAA;oBACjE,OAAO,IAAI,CAAA;gBACb,CAAC;YACH,CAAC;YAED,IAAI,eAAe,EAAE,CAAC;gBACpB,OAAO;oBACL,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;oBACvB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC7B,cAAc,EAAE,IAAI;oBACpB,UAAU,EAAE,SAAS;oBACrB,KAAK,EAAE,UAAU;oBACjB,KAAK,EAAE,UAAU;oBACjB,MAAM,EAAE,EAAE;oBACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI;iBAClC,CAAA;YACH,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;gBACvB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;gBAC7B,cAAc,EAAE,IAAI;gBACpB,UAAU,EAAE,SAAS;gBACrB,KAAK,EAAE,OAAO;gBACd,KAAK,EAAE,OAAO;gBACd,yEAAyE;gBACzE,uEAAuE;gBACvE,gEAAgE;gBAChE,sEAAsE;gBACtE,MAAM,EAAE,MAAM,mBAAmB,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3D,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI;aAClC,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,gEAAgE;YAChE,kEAAkE;YAClE,0BAA0B;YAC1B,MAAM,OAAO,EAAE,CAAA;QACjB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,UAAU,iBAAiB,CAAC,OAAgB,EAAE,GAAQ;QACzD,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QACnD,OAAO,IAAI,KAAK,IAAI,CAAA;IACtB,CAAC;IAED,MAAM,wBAAyB,SAAQ,KAAK;QAC1C;YACE,KAAK,CAAC,gBAAgB,CAAC,CAAA;YACvB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;QACxC,CAAC;KACF;IAED,KAAK,UAAU,wBAAwB,CACrC,OAAgB,EAChB,GAAQ;QAER,IAAI,oCAAoC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;YACvD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAChD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YAC7E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,IAAI,CAAA;YACb,CAAC;YAED,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;iBACnB,MAAM,CAAC;gBACN,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,SAAS,EAAE,iBAAiB,CAAC,SAAS;gBACtC,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;gBACpC,MAAM,EAAE,iBAAiB,CAAC,MAAM;gBAChC,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;gBACpC,OAAO,EAAE,iBAAiB,CAAC,OAAO;gBAClC,SAAS,EAAE,iBAAiB,CAAC,SAAS;gBACtC,YAAY,EAAE,iBAAiB,CAAC,YAAY;gBAC5C,aAAa,EAAE,iBAAiB,CAAC,aAAa;aAC/C,CAAC;iBACD,IAAI,CAAC,QAAQ,CAAC;iBACd,QAAQ,CAAC,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;iBAClE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;iBACvC,KAAK,CAAC,CAAC,CAAC,CAAA;YAEX,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,wBAAwB,EAAE,CAAA;YACtC,CAAC;YAED,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAC5C,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI;gBAChC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;gBAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI;gBAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;gBAC9B,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;gBAC5B,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,KAAK;gBACvC,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,KAAK;gBACzC,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnE,iBAAiB,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI;aACzC,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,EAAE,CAAA;QACjB,CAAC;IACH,CAAC;IAED,KAAK,UAAU,4BAA4B,CACzC,OAAgB,EAChB,GAAQ;QAER,IAAI,oCAAoC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;QAC3B,CAAC;QAED,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAA;QACrD,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAQ,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACnF,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;QAC/D,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,EAAE,CAAA;QACjB,CAAC;IACH,CAAC;IAED,KAAK,UAAU,sBAAsB,CACnC,GAAQ,EACR,EAAY,EACZ,MAAoB;QAEpB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QAE5C,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,GAAG,CAAC,CAAA;QAC1D,IAAI,CAAC,gBAAgB;YAAE,OAAO,KAAK,CAAA;QAEnC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,kCAAkC,CAAC;gBAC5D,EAAE,EAAE,EAAoE;gBACxE,MAAM,EAAE,MAAM,CAAC,WAAW;gBAC1B,MAAM,EAAE,gBAAgB;aACzB,CAAC,CAAA;YACF,OAAO,YAAY,CAAC,EAAE,CAAA;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAA;YACnE,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;YACpE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAA;YAC/C,CAAC;YACD,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,wBAAwB,EAAE,CAAC;gBAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,CAAA;YACjD,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC,CAAC,CAAA;IAEF;;;;;OAKG;IACH,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnC,mEAAmE;QACnE,oCAAoC;QACpC,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAClD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YAC/E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAA;YAC5D,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;YAE9B,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAC3C,EAAoD,EACpD,MAAM,CACP,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC/C,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;gBACpD,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;YAC5B,CAAC;YAED,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF;;;;OAIG;IACH,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,4BAA4B,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACrE,CAAC,CAAC,CAAA;IAEF,KAAK,UAAU,qBAAqB,CAAC,CAAuB;QAC1D,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAClD,MAAM,WAAW,GAAG,EAAuE,CAAA;YAE3F,IAAI,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;gBAC5D,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,kEAAkE,EAAE,EAC7E,GAAG,CACJ,CAAA;gBACH,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC/E,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAA;gBAC/C,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,qCAAqC,CAAC;wBAC/D,EAAE,EAAE,WAAW;wBACf,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;wBAC7B,MAAM,EAAE,gBAAgB;qBACzB,CAAC,CAAA;oBAEF,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;wBACrB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,EAAE,GAAG,CAAC,CAAA;oBAC9D,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAA;oBACpE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,EAAE,GAAG,CAAC,CAAA;gBAC/E,CAAC;YACH,CAAC;YAED,OAAO,CACL,CAAC,MAAM,+BAA+B,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE;gBAC5D,EAAE;gBACF,aAAa,EAAE,cAAc,CAAC,aAAa;aAC5C,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAC3C,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,KAAK,UAAU,+BAA+B,CAAC,CAAuB;QACpE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAClD,MAAM,WAAW,GAAG,EAAuE,CAAA;YAE3F,IAAI,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;gBAC5D,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,wEAAwE,EAAE,EACnF,GAAG,CACJ,CAAA;gBACH,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC/E,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAA;gBAC/C,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,qCAAqC,CAAC;wBAC/D,EAAE,EAAE,WAAW;wBACf,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;wBAC7B,MAAM,EAAE,gBAAgB;qBACzB,CAAC,CAAA;oBAEF,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;wBACrB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,EAAE,GAAG,CAAC,CAAA;oBAC9D,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,wDAAwD,EAAE,KAAK,CAAC,CAAA;oBAC9E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,EAAE,GAAG,CAAC,CAAA;gBAC/E,CAAC;YACH,CAAC;YAED,MAAM,qBAAqB,GAAG,EAEpB,CAAA;YACV,OAAO,CACL,CAAC,MAAM,gCAAgC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE;gBAC7D,EAAE,EAAE,qBAAqB;aAC1B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAC3C,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,KAAK,UAAU,oBAAoB,CAAC,CAAuB;QACzD,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAA;QAC5C,CAAC;QAED,MAAM,MAAM,GAAG,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,8BAA8B,CAAC,CAAC,CAAC,CAAA;QAC1C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,yBAAyB,CAAC;gBAC5C,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG;gBACrB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;gBACzB,MAAM;aACP,CAAC,CAAA;YACF,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;gBACxB,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE;oBACP,QAAQ,EAAE,KAAK,CAAC,WAAW;oBAC3B,YAAY,EAAE,KAAK,CAAC,SAAS;iBAC9B;aACF,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAA;YACjD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2CAA2C,EAAE,EAAE,GAAG,CAAC,CAAA;QAC5E,CAAC;IACH,CAAC;IAED,KAAK,UAAU,uBAAuB,CAAC,CAAuB;QAC5D,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAA;QAC5C,CAAC;QAED,MAAM,cAAc,GAAG,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACxD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC9B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,EAAE,GAAG,EAAE;gBAChF,YAAY,EAAE,mCAAmC,CAC/C,GAAG,CAAC,QAAQ,KAAK,QAAQ,EACzB,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,aAAa,CACzD;aACF,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAClD,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC;gBACnD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG;gBACX,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC5C,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAA;YACpD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mCAAmC,EAAE,EAAE,GAAG,CAAC,CAAA;QACpE,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,oBAAoB,CAAC,CAAA;IACzD,IAAI,CAAC,GAAG,CAAC,4BAA4B,EAAE,uBAAuB,CAAC,CAAA;IAC/D,2CAA2C;IAC3C,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAA;IACnD,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,uBAAuB,CAAC,CAAA;IAEzD,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAA;IACnD,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,qBAAqB,CAAC,CAAA;IAC1D,IAAI,CAAC,GAAG,CAAC,gCAAgC,EAAE,qBAAqB,CAAC,CAAA;IACjE,IAAI,CAAC,GAAG,CAAC,iCAAiC,EAAE,+BAA+B,CAAC,CAAA;IAE5E,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5C,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAChE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YAC/E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpD,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;YAC3D,OAAO,CAAC,CAAC,IAAI,CAAC;gBACZ,OAAO,EAAE;oBACP,SAAS,EAAE,KAAK;oBAChB,aAAa,EAAE,KAAK;oBACpB,MAAM,EAAE,KAAK;oBACb,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,KAAK;iBACb;aACF,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvC,IAAI,CAAC,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;YAC3D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,GAAG,CAAC,CAAA;QAC5D,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAChE,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC5C,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACpC,IAAI,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9E,OAAO,yBAAyB,CAAC,CAAC,CAAC,CAAA;QACrC,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;YAClD,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC5C,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,mEAAmE;IACnE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,SAAS,GAAG,6BAA6B,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC1D,IAAI,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9E,OAAO,yBAAyB,CAAC,CAAC,CAAC,CAAA;QACrC,CAAC;QACD,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC;YACH,OAAO,MAAM,oBAAoB,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACjE,CAAC;gBAAS,CAAC;YACT,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,OAAO,EAAE,IAAI;QACb,4BAA4B;QAC5B,wBAAwB;QACxB,iBAAiB;QACjB,kBAAkB;QAClB,sBAAsB;KACvB,CAAA;AACH,CAAC","sourcesContent":["/**\n * Better Auth Node runtime for Hono.\n *\n * agent-quality: file-size exception -- Auth handler keeps local and Voyant Cloud auth flows co-located until the route surface is split by auth mode.\n *\n * Mounts Better Auth at /auth/* for authentication operations.\n * Same-origin — no CORS needed. Session cookies work naturally.\n *\n * Also provides /auth/status (user provisioning) and /auth/me (user info).\n */\n\nimport { type NodeDatabaseEnv, openNodeDatabase } from \"@voyant-travel/db/runtime\"\nimport {\n authUser,\n cloudAuthUserLinks,\n type SelectApikey,\n userProfilesTable,\n} from \"@voyant-travel/db/schema/iam\"\nimport type { Reporter, VoyantDb, VoyantRequestAuthContext } from \"@voyant-travel/hono\"\nimport {\n handleApiError,\n reportException,\n requestId,\n} from \"@voyant-travel/hono/middleware/error-boundary\"\nimport { getRequestId } from \"@voyant-travel/hono/observability\"\nimport type { AccessCatalog } from \"@voyant-travel/types/api-keys\"\nimport { accessCatalogScopesForRole, isFullAccessRole } from \"@voyant-travel/types/member-roles\"\nimport { eq, sql } from \"drizzle-orm\"\nimport { type Context, Hono } from \"hono\"\nimport {\n createVoyantCloudAdminAuthPlugin,\n revalidateVoyantCloudAdminAuthSession,\n revalidateVoyantCloudAdminAuthUser,\n} from \"./cloud-admin-session.js\"\nimport { buildClearCloudAdminAuthStateCookie, createCloudAdminAuthStart } from \"./cloud-broker.js\"\nimport {\n type CreateBetterAuthOptions,\n type CustomerAuthMethods,\n createAdminBetterAuth,\n createCustomerBetterAuth,\n handleApiTokenManagementRequest,\n handleOrganizationMembersRequest,\n} from \"./server.js\"\nimport { ensureCurrentUserProfile } from \"./workspace.js\"\n\n// Type ctx so that `c.get(\"db\")` resolves to the parent app's middleware-\n// set `VoyantDb` from the deployment's database lifecycle adapter. Without\n// this, the sub-app sees `unknown` for context vars.\ntype OperatorAuthMode = \"local\" | \"voyant-cloud\"\n\nexport interface OperatorAuthNodeEnv extends NodeDatabaseEnv {\n API_BASE_URL?: string\n APP_URL?: string\n AUTH_COOKIE_DOMAIN?: string\n /** @deprecated Use BETTER_AUTH_ADMIN_SECRET. */\n BETTER_AUTH_SECRET?: string\n BETTER_AUTH_ADMIN_SECRET?: string\n BETTER_AUTH_CUSTOMER_SECRET?: string\n CORS_ALLOWLIST?: string\n DASH_BASE_URL?: string\n EMAIL_FROM?: string\n SESSION_CLAIMS_SECRET: string\n VOYANT_ADMIN_AUTH_MODE?: string\n VOYANT_CUSTOMER_AUTH_MODE?: string\n VOYANT_CUSTOMER_AUTH_CONFIG_JSON?: string\n VOYANT_CUSTOMER_AUTH_EMAIL_CODE?: string\n VOYANT_CUSTOMER_AUTH_EMAIL_PASSWORD?: string\n CUSTOMER_AUTH_GOOGLE_CLIENT_ID?: string\n CUSTOMER_AUTH_GOOGLE_CLIENT_SECRET?: string\n CUSTOMER_AUTH_FACEBOOK_CLIENT_ID?: string\n CUSTOMER_AUTH_FACEBOOK_CLIENT_SECRET?: string\n CUSTOMER_AUTH_APPLE_CLIENT_ID?: string\n CUSTOMER_AUTH_APPLE_CLIENT_SECRET?: string\n VOYANT_AUTH_LOG_SECRET_FALLBACKS?: string\n VOYANT_CLOUD_ADMIN_AUTH_AUDIENCE?: string\n VOYANT_CLOUD_ADMIN_AUTH_CLIENT_TOKEN?: string\n VOYANT_CLOUD_ADMIN_AUTH_EXCHANGE_URL?: string\n VOYANT_CLOUD_ADMIN_AUTH_JWKS_URL?: string\n VOYANT_CLOUD_ADMIN_AUTH_REVALIDATE_URL?: string\n VOYANT_CLOUD_ADMIN_AUTH_START_URL?: string\n VOYANT_CLOUD_APP_ID?: string\n VOYANT_CLOUD_DEPLOYMENT_ID?: string\n VOYANT_CLOUD_ENVIRONMENT?: string\n VOYANT_OPERATOR_BROWSER_EVIDENCE?: string\n}\n\nexport interface OperatorCurrentUser {\n id: string\n email: string\n firstName: string | null\n lastName: string | null\n locale: string\n timezone: string | null\n uiPrefs: unknown\n isSuperAdmin: boolean\n isSupportUser: boolean\n createdAt: string\n profilePictureUrl: string | null\n}\n\nexport type OperatorAuthBootstrapStatus = {\n hasUsers: boolean\n authMode?: OperatorAuthMode\n}\n\ntype BetterAuthAdvancedOptions = NonNullable<CreateBetterAuthOptions[\"advanced\"]>\n\n/** Resolve Better Auth's standard cross-subdomain cookie policy for Node hosts. */\nexport function buildBetterAuthCookieAdvancedOptions(\n env: Pick<OperatorAuthNodeEnv, \"AUTH_COOKIE_DOMAIN\">,\n):\n | Pick<BetterAuthAdvancedOptions, \"crossSubDomainCookies\" | \"defaultCookieAttributes\">\n | undefined {\n const domain = env.AUTH_COOKIE_DOMAIN?.trim()\n if (!domain) return undefined\n\n return {\n crossSubDomainCookies: { enabled: true, domain },\n defaultCookieAttributes: { domain },\n }\n}\n\nexport interface OperatorAuthEmailSender {\n sendResetPassword: (input: {\n user: { email: string; name: string }\n url: string\n }) => Promise<void>\n sendVerificationOtp: (input: { email: string; otp: string; type: string }) => Promise<void>\n}\n\nexport interface CreateOperatorAuthNodeRuntimeOptions<Env extends OperatorAuthNodeEnv> {\n accessCatalog: AccessCatalog\n appName: string\n authMode: OperatorAuthMode\n reporter: Reporter\n openDatabase?: (env: Env) => { db: VoyantDb; dispose: () => Promise<void> }\n cookieAdvanced?: (\n env: Env,\n ) =>\n | Pick<BetterAuthAdvancedOptions, \"crossSubDomainCookies\" | \"defaultCookieAttributes\">\n | undefined\n resolveEmailSender?: (env: Env) => OperatorAuthEmailSender | null\n /**\n * Storefront/BFF seam for a canonical public auth origin and resolved\n * merchant credentials. Never derive these values from Host/X-Forwarded-Host.\n */\n resolveCustomerAuthContext?: (\n env: Env,\n policy: CustomerAuthPolicy,\n request: Request,\n ) => CustomerAuthRuntimeContext\n}\n\nexport interface CustomerAuthRuntimeContext {\n baseURL: string\n trustedOrigins: string[]\n methods: CustomerAuthMethods\n}\n\nexport interface CustomerAuthSocialPolicy {\n enabled: boolean\n credentialRef: string | null\n}\n\nexport interface CustomerAuthPolicy {\n methods: {\n emailCode: boolean\n emailPassword: boolean\n google: CustomerAuthSocialPolicy\n facebook: CustomerAuthSocialPolicy\n apple: CustomerAuthSocialPolicy\n }\n}\n\n/**\n * Better Auth is dispatched internally without the hosting `/api` prefix, but\n * OAuth providers must return to the browser-visible route. Keep explicit\n * merchant overrides and supply the canonical public callback otherwise.\n */\nexport function withCustomerSocialRedirectUris(\n methods: CustomerAuthMethods,\n publicApiBaseUrl: string,\n): CustomerAuthMethods {\n const providers = methods.socialProviders\n if (!providers) return methods\n\n const normalizedPublicApiBaseUrl = publicApiBaseUrl.replace(/\\/+$/, \"\")\n const callback = (provider: \"google\" | \"facebook\" | \"apple\") =>\n `${normalizedPublicApiBaseUrl}/auth/customer/callback/${provider}`\n const withRedirectUri = <Provider>(\n provider: Provider | undefined,\n redirectURI: string,\n ): Provider | undefined => {\n if (!provider || typeof provider !== \"object\") return provider\n const configured = provider as Provider & { redirectURI?: string }\n return {\n ...configured,\n redirectURI: configured.redirectURI?.trim() || redirectURI,\n }\n }\n\n return {\n ...methods,\n socialProviders: {\n ...providers,\n ...(providers.google\n ? {\n google: withRedirectUri(providers.google, callback(\"google\")),\n }\n : {}),\n ...(providers.facebook\n ? {\n facebook: withRedirectUri(providers.facebook, callback(\"facebook\")),\n }\n : {}),\n ...(providers.apple\n ? {\n apple: withRedirectUri(providers.apple, callback(\"apple\")),\n }\n : {}),\n },\n }\n}\n\nexport function createOperatorAuthNodeRuntime<Env extends OperatorAuthNodeEnv>(\n runtimeOptions: CreateOperatorAuthNodeRuntimeOptions<Env>,\n) {\n type AuthHonoEnv = { Bindings: Env; Variables: { db: VoyantDb } }\n\n const openDatabase =\n runtimeOptions.openDatabase ??\n ((env: Env) => {\n const resource = openNodeDatabase(env)\n return { db: resource.db as VoyantDb, dispose: resource.dispose }\n })\n\n const auth = new Hono<AuthHonoEnv>()\n // This lean auth app is dispatched around `createVoyantApp` (see\n // api-dispatch.ts), so it must mint/propagate the correlation id and wire\n // the reporter itself — otherwise auth 5xx are an observability blind spot and\n // the user-facing requestId wouldn't be findable (RFC voyant#1553).\n auth.use(\"*\", requestId)\n // `onError` only fires on THROWN exceptions. Several handlers (e.g.\n // /auth/status, the cloud token/revalidate/callback paths) instead RETURN a\n // 5xx via `c.json(..., 50x)`; those bypass `onError`, and this lean app is\n // dispatched around `createVoyantApp` so the framework's auth status-bridge\n // (`mountAuthForwarding`) never runs either. Bridge returned 5xx to the\n // reporter here so they aren't an observability blind spot (RFC voyant#1553).\n // Thrown errors skip this middleware's post-`next()` code (the rejection\n // propagates straight to `onError`), so there's no double report.\n auth.use(\"*\", async (c, next) => {\n await next()\n if (c.res.status >= 500) {\n reportException(runtimeOptions.reporter, c, {\n requestId: getRequestId() ?? \"\",\n app: runtimeOptions.appName,\n error: new Error(`auth handler returned HTTP ${c.res.status}`),\n context: { path: c.req.path, method: c.req.method, status: c.res.status, surface: \"auth\" },\n })\n }\n })\n auth.onError((err, c) =>\n handleApiError(err, c, { reporter: runtimeOptions.reporter, appName: runtimeOptions.appName }),\n )\n\n const DEFAULT_APP_URL = \"http://localhost:3300\"\n const CLOUD_BETTER_AUTH_ALLOWLIST = new Set([\n \"/auth/get-session\",\n \"/auth/jwks\",\n \"/auth/session\",\n \"/auth/sign-out\",\n \"/auth/token\",\n ])\n\n function resolveOperatorAuthMode(_env: Env): OperatorAuthMode {\n return runtimeOptions.authMode\n }\n\n function isVoyantCloudAuthMode(env: Env): boolean {\n return resolveOperatorAuthMode(env) === \"voyant-cloud\"\n }\n\n function isCloudAllowedBetterAuthRoute(request: Request): boolean {\n const url = new URL(request.url)\n const pathname = url.pathname.replace(\"/auth/admin\", \"/auth\").replace(/\\/+$/, \"\") || \"/\"\n return CLOUD_BETTER_AUTH_ALLOWLIST.has(pathname)\n }\n\n function localAuthDisabledResponse(c: Context<AuthHonoEnv>) {\n return c.json({ error: \"Local auth routes are disabled in Voyant Cloud auth mode\" }, 404)\n }\n\n function cloudAuthNotConfiguredResponse(c: Context<AuthHonoEnv>) {\n return c.json({ error: \"Voyant Cloud auth broker is not configured yet\" }, 501)\n }\n\n function normalizeUrl(url: string): string {\n return url.trim().replace(/\\/$/, \"\")\n }\n\n function getAppUrl(env: Env): string {\n const candidates = [\n env.APP_URL,\n env.DASH_BASE_URL,\n env.CORS_ALLOWLIST?.split(\",\")[0],\n DEFAULT_APP_URL,\n ]\n\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.trim().length > 0) {\n return normalizeUrl(candidate)\n }\n }\n\n return DEFAULT_APP_URL\n }\n\n function getTrustedOrigins(env: Env): string[] {\n return Array.from(\n new Set(\n [env.APP_URL, env.DASH_BASE_URL, ...(env.CORS_ALLOWLIST ?? \"\").split(\",\")]\n .map((value) => value?.trim())\n .filter((value): value is string => Boolean(value)),\n ),\n ).map(normalizeUrl)\n }\n\n function getAuthBaseUrl(env: Env): string {\n // entry.ts strips /api before delegating to the Hono app, so Better Auth\n // sees paths like /auth/*. Its baseURL must be the origin only (no /api).\n const appUrl = getAppUrl(env)\n try {\n const parsed = new URL(appUrl)\n return `${parsed.protocol}//${parsed.host}`\n } catch {\n return appUrl\n }\n }\n\n function getPublicApiBaseUrl(env: Env): string {\n const candidate = env.API_BASE_URL?.trim() || env.APP_URL?.trim() || `${getAppUrl(env)}/api`\n const normalized = normalizeUrl(candidate)\n\n try {\n const parsed = new URL(normalized)\n if (parsed.pathname === \"/\" || parsed.pathname === \"\") {\n parsed.pathname = \"/api\"\n return normalizeUrl(parsed.toString())\n }\n } catch {\n return normalized\n }\n\n return normalized\n }\n\n function getCloudAuthStartConfig(env: Env) {\n const deploymentId = env.VOYANT_CLOUD_DEPLOYMENT_ID?.trim()\n const cloudAuthStartUrl = env.VOYANT_CLOUD_ADMIN_AUTH_START_URL?.trim()\n if (!deploymentId || !cloudAuthStartUrl) return null\n\n return {\n cloudAuthStartUrl,\n deploymentId,\n adminCallbackUrl: `${getPublicApiBaseUrl(env)}/auth/admin/cloud/callback`,\n cookieSecret: env.SESSION_CLAIMS_SECRET,\n appId: env.VOYANT_CLOUD_APP_ID?.trim() || undefined,\n environment: env.VOYANT_CLOUD_ENVIRONMENT?.trim() || undefined,\n }\n }\n\n function getCloudAuthExchangeConfig(env: Env) {\n const deploymentId = env.VOYANT_CLOUD_DEPLOYMENT_ID?.trim()\n const exchangeUrl = env.VOYANT_CLOUD_ADMIN_AUTH_EXCHANGE_URL?.trim()\n const assertionJwksUrl = env.VOYANT_CLOUD_ADMIN_AUTH_JWKS_URL?.trim()\n const clientToken = env.VOYANT_CLOUD_ADMIN_AUTH_CLIENT_TOKEN?.trim()\n if (!deploymentId || !exchangeUrl || !assertionJwksUrl || !clientToken) return null\n\n return {\n exchangeUrl,\n deploymentId,\n clientToken,\n assertionJwksUrl,\n assertionAudience: env.VOYANT_CLOUD_ADMIN_AUTH_AUDIENCE?.trim() || deploymentId,\n }\n }\n\n function getCloudAuthRevalidateConfig(env: Env) {\n const deploymentId = env.VOYANT_CLOUD_DEPLOYMENT_ID?.trim()\n const revalidateUrl = env.VOYANT_CLOUD_ADMIN_AUTH_REVALIDATE_URL?.trim()\n const clientToken = env.VOYANT_CLOUD_ADMIN_AUTH_CLIENT_TOKEN?.trim()\n if (!deploymentId || !revalidateUrl || !clientToken) return null\n\n return {\n revalidateUrl,\n deploymentId,\n clientToken,\n }\n }\n\n function isLocalRequest(request: Request): boolean {\n const hostname = new URL(request.url).hostname\n return hostname === \"127.0.0.1\" || hostname === \"localhost\"\n }\n\n function shouldUseBrowserEvidenceAuthFallback(env: Env, request: Request): boolean {\n return env.VOYANT_OPERATOR_BROWSER_EVIDENCE === \"1\" && isLocalRequest(request)\n }\n\n function allowAuthSecretLogging(env: Env): boolean {\n return env.VOYANT_AUTH_LOG_SECRET_FALLBACKS === \"1\"\n }\n\n /**\n * Build a Better Auth instance backed by a caller-provided drizzle\n * client. The caller owns the Pool lifecycle (open before, dispose\n * after) so the same Pool can serve both the auth lookup and any\n * subsequent queries the route does — without spinning up a second\n * connection per request.\n *\n * The deployment decides whether this is a request-scoped or resident Node\n * pool. The Better Auth instance is not cached independently of that owner.\n */\n function requireAdminAuthSecret(env: Env): string {\n const secret = env.BETTER_AUTH_ADMIN_SECRET?.trim() || env.BETTER_AUTH_SECRET?.trim()\n if (!secret) throw new Error(\"Admin auth requires BETTER_AUTH_ADMIN_SECRET\")\n return secret\n }\n\n function requireCustomerAuthSecret(env: Env): string {\n const secret = env.BETTER_AUTH_CUSTOMER_SECRET?.trim()\n if (secret) return secret\n // Compatibility bridge for deployments created before realm-specific\n // secrets. The suffix gives the customer cookie an independent signature.\n return `${requireAdminAuthSecret(env)}:voyant-customer-realm`\n }\n\n function envEnabled(value: string | undefined, fallback: boolean): boolean {\n const normalized = value?.trim().toLowerCase()\n if (!normalized) return fallback\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\"\n }\n\n function parseCustomerAuthPolicy(env: Env): CustomerAuthPolicy {\n const fallback = {\n methods: {\n emailCode: envEnabled(env.VOYANT_CUSTOMER_AUTH_EMAIL_CODE, true),\n emailPassword: envEnabled(env.VOYANT_CUSTOMER_AUTH_EMAIL_PASSWORD, true),\n google: { enabled: false, credentialRef: null },\n facebook: { enabled: false, credentialRef: null },\n apple: { enabled: false, credentialRef: null },\n },\n } satisfies CustomerAuthPolicy\n const raw = env.VOYANT_CUSTOMER_AUTH_CONFIG_JSON?.trim()\n if (!raw) return fallback\n try {\n const parsed = JSON.parse(raw) as {\n methods?: Record<string, unknown>\n }\n const methods = parsed.methods ?? {}\n const social = (value: unknown): CustomerAuthSocialPolicy => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return { enabled: false, credentialRef: null }\n }\n const record = value as Record<string, unknown>\n return {\n enabled: record.enabled === true,\n credentialRef:\n typeof record.credentialRef === \"string\" && record.credentialRef.trim()\n ? record.credentialRef.trim()\n : null,\n }\n }\n return {\n methods: {\n emailCode:\n typeof methods.emailCode === \"boolean\" ? methods.emailCode : fallback.methods.emailCode,\n emailPassword:\n typeof methods.emailPassword === \"boolean\"\n ? methods.emailPassword\n : fallback.methods.emailPassword,\n google: social(methods.google),\n facebook: social(methods.facebook),\n apple: social(methods.apple),\n },\n }\n } catch {\n console.error(\n \"[auth/customer] Invalid VOYANT_CUSTOMER_AUTH_CONFIG_JSON; failing social auth closed\",\n )\n return fallback\n }\n }\n\n function defaultCustomerAuthContext(\n env: Env,\n policy: CustomerAuthPolicy,\n ): CustomerAuthRuntimeContext {\n const hasCanonicalPolicy = Boolean(env.VOYANT_CUSTOMER_AUTH_CONFIG_JSON?.trim())\n const google = Boolean(\n env.CUSTOMER_AUTH_GOOGLE_CLIENT_ID?.trim() &&\n env.CUSTOMER_AUTH_GOOGLE_CLIENT_SECRET?.trim() &&\n (!hasCanonicalPolicy || policy.methods.google.enabled),\n )\n const facebook = Boolean(\n env.CUSTOMER_AUTH_FACEBOOK_CLIENT_ID?.trim() &&\n env.CUSTOMER_AUTH_FACEBOOK_CLIENT_SECRET?.trim() &&\n (!hasCanonicalPolicy || policy.methods.facebook.enabled),\n )\n const apple = Boolean(\n env.CUSTOMER_AUTH_APPLE_CLIENT_ID?.trim() &&\n env.CUSTOMER_AUTH_APPLE_CLIENT_SECRET?.trim() &&\n (!hasCanonicalPolicy || policy.methods.apple.enabled),\n )\n return {\n baseURL: getAuthBaseUrl(env),\n trustedOrigins: getTrustedOrigins(env),\n methods: {\n emailCode: policy.methods.emailCode,\n emailPassword: policy.methods.emailPassword,\n socialProviders: {\n ...(google\n ? {\n google: {\n clientId: env.CUSTOMER_AUTH_GOOGLE_CLIENT_ID!.trim(),\n clientSecret: env.CUSTOMER_AUTH_GOOGLE_CLIENT_SECRET!.trim(),\n },\n }\n : {}),\n ...(facebook\n ? {\n facebook: {\n clientId: env.CUSTOMER_AUTH_FACEBOOK_CLIENT_ID!.trim(),\n clientSecret: env.CUSTOMER_AUTH_FACEBOOK_CLIENT_SECRET!.trim(),\n },\n }\n : {}),\n ...(apple\n ? {\n apple: {\n clientId: env.CUSTOMER_AUTH_APPLE_CLIENT_ID!.trim(),\n clientSecret: env.CUSTOMER_AUTH_APPLE_CLIENT_SECRET!.trim(),\n },\n }\n : {}),\n },\n },\n }\n }\n\n function resolveCustomerAuthContext(env: Env, request: Request): CustomerAuthRuntimeContext {\n const policy = parseCustomerAuthPolicy(env)\n return (\n runtimeOptions.resolveCustomerAuthContext?.(env, policy, request) ??\n defaultCustomerAuthContext(env, policy)\n )\n }\n\n function publicCustomerAuthConfiguration(env: Env, request: Request) {\n const methods = resolveCustomerAuthContext(env, request).methods\n const providers = methods.socialProviders ?? {}\n return {\n methods: {\n emailCode: methods.emailCode ?? true,\n emailPassword: methods.emailPassword ?? true,\n google: Boolean(providers.google),\n facebook: Boolean(providers.facebook),\n apple: Boolean(providers.apple),\n },\n }\n }\n\n function buildAdminBetterAuth(env: Env, db: VoyantDb) {\n const emailSender = runtimeOptions.resolveEmailSender?.(env)\n const cloudAuthExchange = isVoyantCloudAuthMode(env) ? getCloudAuthExchangeConfig(env) : null\n const authDb = db as NonNullable<Parameters<typeof createAdminBetterAuth>[0]>[\"db\"]\n const cloudAuthDb = db as Parameters<typeof createVoyantCloudAdminAuthPlugin>[0][\"db\"]\n\n return createAdminBetterAuth({\n // `db` is a `NeonDatabase` (neon-serverless WebSocket); the\n // `CreateBetterAuthOptions.db` type still references the older\n // `getDb` return union (postgres-js + neon-http). Drizzle's\n // PgDatabase surface is identical across flavors at runtime, so\n // the cast is structurally safe — better-auth's drizzleAdapter\n // works on any PgDatabase. See #500 for context.\n db: authDb,\n secret: requireAdminAuthSecret(env),\n baseURL: getAuthBaseUrl(env),\n basePath: \"/auth/admin\",\n trustedOrigins: getTrustedOrigins(env),\n advanced: (runtimeOptions.cookieAdvanced ?? buildBetterAuthCookieAdvancedOptions)(env),\n plugins: cloudAuthExchange\n ? [\n createVoyantCloudAdminAuthPlugin({\n db: cloudAuthDb,\n cookieSecret: env.SESSION_CLAIMS_SECRET,\n exchange: cloudAuthExchange,\n }),\n ]\n : undefined,\n sendResetPassword: async ({ user, url }) => {\n if (!emailSender) {\n // No email provider (e.g. local dev without a sending domain): with the\n // debug flag on, log the link to the console instead of sending;\n // otherwise fail loudly. Never bypasses a configured cloud sender.\n if (allowAuthSecretLogging(env)) {\n console.info(`[auth] reset-password (debug fallback) -> ${user.email}: ${url}`)\n return\n }\n throw new Error(\"Password reset email provider is not configured\")\n }\n await emailSender.sendResetPassword({ user, url })\n },\n sendVerificationOTP: async ({ email, otp, type }) => {\n if (!emailSender) {\n // No email provider (e.g. local dev without a sending domain): with the\n // debug flag on, log the OTP to the console instead of sending;\n // otherwise fail loudly. Never bypasses a configured cloud sender.\n if (allowAuthSecretLogging(env)) {\n console.info(`[auth] verification-otp (debug fallback) [${type}] -> ${email}: ${otp}`)\n return\n }\n throw new Error(\"Verification OTP email provider is not configured\")\n }\n await emailSender.sendVerificationOtp({ email, otp, type })\n },\n })\n }\n\n function buildCustomerBetterAuth(env: Env, db: VoyantDb, request: Request) {\n const emailSender = runtimeOptions.resolveEmailSender?.(env)\n const context = resolveCustomerAuthContext(env, request)\n const authDb = db as NonNullable<Parameters<typeof createCustomerBetterAuth>[0]>[\"db\"]\n return createCustomerBetterAuth({\n db: authDb,\n secret: requireCustomerAuthSecret(env),\n baseURL: context.baseURL,\n basePath: \"/auth/customer\",\n trustedOrigins: context.trustedOrigins,\n methods: withCustomerSocialRedirectUris(context.methods, getPublicApiBaseUrl(env)),\n sendResetPassword: async ({ user, url }) => {\n if (!emailSender) {\n if (allowAuthSecretLogging(env)) {\n console.info(`[auth/customer] reset-password (debug fallback) -> ${user.email}: ${url}`)\n return\n }\n throw new Error(\"Password reset email provider is not configured\")\n }\n await emailSender.sendResetPassword({ user, url })\n },\n sendVerificationOTP: async ({ email, otp, type }) => {\n if (!emailSender) {\n if (allowAuthSecretLogging(env)) {\n console.info(\n `[auth/customer] verification-otp (debug fallback) [${type}] -> ${email}: ${otp}`,\n )\n return\n }\n throw new Error(\"Verification OTP email provider is not configured\")\n }\n await emailSender.sendVerificationOtp({ email, otp, type })\n },\n })\n }\n\n function rewriteLegacyAdminAuthRequest(request: Request): Request {\n const url = new URL(request.url)\n url.pathname = url.pathname.replace(\"/auth\", \"/auth/admin\")\n return new Request(url, request)\n }\n\n const FULL_ACCESS_SCOPES = [\"*\"]\n\n function scopesForOperatorRole(role: string | null | undefined): string[] | null {\n const base = accessCatalogScopesForRole(role, runtimeOptions.accessCatalog)\n if (!base) return null\n const normalizedRole = (role ?? \"\").trim().toLowerCase()\n const presetId =\n normalizedRole === \"member\"\n ? \"editor\"\n : normalizedRole === \"guest\"\n ? \"viewer\"\n : normalizedRole\n const selected = runtimeOptions.accessCatalog.presets.find(\n (preset) => preset.kind === \"staff\" && preset.id === presetId,\n )\n return [...new Set([...base, ...(selected?.grants ?? [])])].sort()\n }\n\n /**\n * Resolve a member's RBAC scope set for the request (`resource:action` strings,\n * shared with API keys — see @voyant-travel/types/member-roles, RFC voyant#2085).\n *\n * Phase 1: storage + seam are wired but default to full access, so behavior is\n * unchanged until an admin assigns permissions (Phase 2) and routes gate on them\n * (Phase 3).\n * - voyant-cloud: assertion-mirrored `cloud_auth_user_links.scopes` if the\n * platform sent them, else the role bundle for `roleSlug`, else full access.\n * - local: the member's `user_profiles.permissions` if assigned, else full\n * access (no local role concept yet).\n */\n async function resolveMemberScopes(db: VoyantDb, env: Env, userId: string): Promise<string[]> {\n if (isVoyantCloudAuthMode(env)) {\n const [link] = await db\n .select({ scopes: cloudAuthUserLinks.scopes, roleSlug: cloudAuthUserLinks.roleSlug })\n .from(cloudAuthUserLinks)\n .where(eq(cloudAuthUserLinks.userId, userId))\n .limit(1)\n const fullAccessScopes = scopesForOperatorRole(\"admin\") ?? FULL_ACCESS_SCOPES\n const roleScopes = scopesForOperatorRole(link?.roleSlug) ?? fullAccessScopes\n return isFullAccessRole(link?.roleSlug) ? roleScopes : (link?.scopes ?? roleScopes)\n }\n\n const [profile] = await db\n .select({ permissions: userProfilesTable.permissions })\n .from(userProfilesTable)\n .where(eq(userProfilesTable.id, userId))\n .limit(1)\n return profile?.permissions ?? FULL_ACCESS_SCOPES\n }\n\n async function resolveAuthRequest(\n request: Request,\n env: Env,\n ): Promise<VoyantRequestAuthContext | null> {\n const { db, dispose } = openDatabase(env)\n try {\n const customerSurface = new URL(request.url).pathname.includes(\"/v1/public/\")\n const auth = customerSurface\n ? buildCustomerBetterAuth(env, db, request)\n : buildAdminBetterAuth(env, db)\n const session = await auth.api.getSession({ headers: request.headers })\n\n if (!session) {\n return null\n }\n\n if (!customerSurface && isVoyantCloudAuthMode(env)) {\n const revalidateConfig = getCloudAuthRevalidateConfig(env)\n if (!revalidateConfig) {\n return null\n }\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthSession({\n db: db as Parameters<typeof revalidateVoyantCloudAdminAuthSession>[0][\"db\"],\n sessionId: session.session.id,\n config: revalidateConfig,\n })\n\n if (!revalidation.ok) {\n return null\n }\n } catch (error) {\n console.error(\"[auth/session] Cloud revalidation failed:\", error)\n return null\n }\n }\n\n if (customerSurface) {\n return {\n userId: session.user.id,\n sessionId: session.session.id,\n organizationId: null,\n callerType: \"session\",\n actor: \"customer\",\n realm: \"customer\",\n scopes: [],\n email: session.user.email ?? null,\n }\n }\n\n return {\n userId: session.user.id,\n sessionId: session.session.id,\n organizationId: null,\n callerType: \"session\",\n actor: \"staff\",\n realm: \"admin\",\n // Member RBAC scope set (RFC voyant#2085). Defaults to full access until\n // an admin assigns permissions, so existing deployments are unchanged.\n // `actor: \"staff\"` is retained, so actor-gated paths (incl. the\n // bookings-pii reveal, which short-circuits on staff) are unaffected.\n scopes: await resolveMemberScopes(db, env, session.user.id),\n email: session.user.email ?? null,\n }\n } finally {\n // No `executionCtx` reachable here (called from middleware that\n // doesn't pass one through). Await inline so the WebSocket closes\n // before this fn returns.\n await dispose()\n }\n }\n\n /**\n * Single-tenant: every authenticated session is a staff user with full access.\n * When `resolveAuthRequest` has already granted a session, permissions are\n * implicitly allowed. If you need granular RBAC later, switch on\n * `user_profiles.isSuperAdmin` / `isSupportUser` here.\n */\n async function hasAuthPermission(request: Request, env: Env): Promise<boolean> {\n const auth = await resolveAuthRequest(request, env)\n return auth !== null\n }\n\n class CurrentUserNotFoundError extends Error {\n constructor() {\n super(\"User not found\")\n this.name = \"CurrentUserNotFoundError\"\n }\n }\n\n async function getCurrentUserForRequest(\n request: Request,\n env: Env,\n ): Promise<OperatorCurrentUser | null> {\n if (shouldUseBrowserEvidenceAuthFallback(env, request)) {\n return null\n }\n\n const { db, dispose } = openDatabase(env)\n try {\n const betterAuth = buildAdminBetterAuth(env, db)\n const session = await betterAuth.api.getSession({ headers: request.headers })\n if (!session) {\n return null\n }\n\n const [row] = await db\n .select({\n id: authUser.id,\n email: authUser.email,\n createdAt: authUser.createdAt,\n firstName: userProfilesTable.firstName,\n lastName: userProfilesTable.lastName,\n locale: userProfilesTable.locale,\n timezone: userProfilesTable.timezone,\n uiPrefs: userProfilesTable.uiPrefs,\n avatarUrl: userProfilesTable.avatarUrl,\n isSuperAdmin: userProfilesTable.isSuperAdmin,\n isSupportUser: userProfilesTable.isSupportUser,\n })\n .from(authUser)\n .leftJoin(userProfilesTable, eq(userProfilesTable.id, authUser.id))\n .where(eq(authUser.id, session.user.id))\n .limit(1)\n\n if (!row) {\n throw new CurrentUserNotFoundError()\n }\n\n return {\n id: row.id,\n email: row.email ?? session.user.email ?? \"\",\n firstName: row.firstName ?? null,\n lastName: row.lastName ?? null,\n locale: row.locale ?? \"en\",\n timezone: row.timezone ?? null,\n uiPrefs: row.uiPrefs ?? null,\n isSuperAdmin: row.isSuperAdmin ?? false,\n isSupportUser: row.isSupportUser ?? false,\n createdAt: row.createdAt?.toISOString() ?? new Date().toISOString(),\n profilePictureUrl: row.avatarUrl ?? null,\n }\n } finally {\n await dispose()\n }\n }\n\n async function getBootstrapStatusForRequest(\n request: Request,\n env: Env,\n ): Promise<OperatorAuthBootstrapStatus> {\n if (shouldUseBrowserEvidenceAuthFallback(env, request)) {\n return { hasUsers: true }\n }\n\n if (isVoyantCloudAuthMode(env)) {\n return { hasUsers: true, authMode: \"voyant-cloud\" }\n }\n\n const { db, dispose } = openDatabase(env)\n try {\n const [row] = await db.select({ count: sql<number>`count(*)::int` }).from(authUser)\n return { hasUsers: (row?.count ?? 0) > 0, authMode: \"local\" }\n } finally {\n await dispose()\n }\n }\n\n async function validateApiTokenAccess(\n env: Env,\n db: VoyantDb,\n apiKey: SelectApikey,\n ): Promise<boolean> {\n if (!isVoyantCloudAuthMode(env)) return true\n\n const revalidateConfig = getCloudAuthRevalidateConfig(env)\n if (!revalidateConfig) return false\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthUser({\n db: db as Parameters<typeof revalidateVoyantCloudAdminAuthUser>[0][\"db\"],\n userId: apiKey.referenceId,\n config: revalidateConfig,\n })\n return revalidation.ok\n } catch (error) {\n console.error(\"[auth/api-token] Cloud revalidation failed:\", error)\n return false\n }\n }\n\n /**\n * GET /auth/me\n * Returns the current authenticated user's profile.\n * Validates the session cookie directly (no Bearer token needed).\n */\n auth.get(\"/auth/me\", async (c) => {\n try {\n const currentUser = await getCurrentUserForRequest(c.req.raw, c.env)\n if (!currentUser) {\n return c.json({ error: \"Unauthorized\" }, 401)\n }\n return c.json(currentUser)\n } catch (error) {\n if (error instanceof CurrentUserNotFoundError) {\n return c.json({ error: \"User not found\" }, 404)\n }\n throw error\n }\n })\n\n /**\n * GET /auth/status\n * Ensures the authenticated user has a user_profiles row.\n * Profile is normally created by the BA databaseHook on sign-up,\n * but this route serves as an idempotent fallback.\n */\n auth.get(\"/auth/status\", async (c) => {\n // See `/auth/me` above — auth sub-app runs before the request `db`\n // middleware, so own the Pool here.\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n if (!session) {\n return c.json({ userExists: false, authenticated: false })\n }\n\n const userId = session.user.id\n\n const status = await ensureCurrentUserProfile(\n db as Parameters<typeof ensureCurrentUserProfile>[0],\n userId,\n )\n if (!status.userExists && status.authenticated) {\n console.error(\"[auth/status] Error:\", status.reason)\n return c.json(status, 500)\n }\n\n return c.json(status)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n /**\n * GET /auth/bootstrap-status\n * Public endpoint — reveals whether any user exists. Used by the sign-in /\n * sign-up route loaders to pick the right flow.\n */\n auth.get(\"/auth/bootstrap-status\", async (c) => {\n return c.json(await getBootstrapStatusForRequest(c.req.raw, c.env))\n })\n\n async function handleApiTokensFacade(c: Context<AuthHonoEnv>) {\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const cloudAuthDb = db as Parameters<typeof revalidateVoyantCloudAdminAuthSession>[0][\"db\"]\n\n if (isVoyantCloudAuthMode(c.env)) {\n const revalidateConfig = getCloudAuthRevalidateConfig(c.env)\n if (!revalidateConfig) {\n return c.json(\n { error: \"Cloud-mode API token management requires membership revalidation\" },\n 501,\n )\n }\n\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n if (!session) {\n return c.json({ error: \"Unauthorized\" }, 401)\n }\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthSession({\n db: cloudAuthDb,\n sessionId: session.session.id,\n config: revalidateConfig,\n })\n\n if (!revalidation.ok) {\n return c.json({ error: \"Voyant Cloud access revoked\" }, 403)\n }\n } catch (error) {\n console.error(\"[auth/api-tokens] Cloud revalidation failed:\", error)\n return c.json({ error: \"Voyant Cloud access could not be revalidated\" }, 503)\n }\n }\n\n return (\n (await handleApiTokenManagementRequest(c.req.raw, betterAuth, {\n db,\n accessCatalog: runtimeOptions.accessCatalog,\n })) ?? c.json({ error: \"Not found\" }, 404)\n )\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n }\n\n async function handleOrganizationMembersFacade(c: Context<AuthHonoEnv>) {\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const cloudAuthDb = db as Parameters<typeof revalidateVoyantCloudAdminAuthSession>[0][\"db\"]\n\n if (isVoyantCloudAuthMode(c.env)) {\n const revalidateConfig = getCloudAuthRevalidateConfig(c.env)\n if (!revalidateConfig) {\n return c.json(\n { error: \"Cloud-mode organization member lookup requires membership revalidation\" },\n 501,\n )\n }\n\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n if (!session) {\n return c.json({ error: \"Unauthorized\" }, 401)\n }\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthSession({\n db: cloudAuthDb,\n sessionId: session.session.id,\n config: revalidateConfig,\n })\n\n if (!revalidation.ok) {\n return c.json({ error: \"Voyant Cloud access revoked\" }, 403)\n }\n } catch (error) {\n console.error(\"[auth/organization-members] Cloud revalidation failed:\", error)\n return c.json({ error: \"Voyant Cloud access could not be revalidated\" }, 503)\n }\n }\n\n const organizationMembersDb = db as Parameters<\n typeof handleOrganizationMembersRequest\n >[2][\"db\"]\n return (\n (await handleOrganizationMembersRequest(c.req.raw, betterAuth, {\n db: organizationMembersDb,\n })) ?? c.json({ error: \"Not found\" }, 404)\n )\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n }\n\n async function handleCloudAuthStart(c: Context<AuthHonoEnv>) {\n if (!isVoyantCloudAuthMode(c.env)) {\n return c.json({ error: \"Not found\" }, 404)\n }\n\n const config = getCloudAuthStartConfig(c.env)\n if (!config) {\n return cloudAuthNotConfiguredResponse(c)\n }\n\n try {\n const start = await createCloudAdminAuthStart({\n requestUrl: c.req.url,\n next: c.req.query(\"next\"),\n config,\n })\n return new Response(null, {\n status: 302,\n headers: {\n Location: start.redirectUrl,\n \"Set-Cookie\": start.setCookie,\n },\n })\n } catch (error) {\n console.error(\"[auth/cloud/start] Error:\", error)\n return c.json({ error: \"Voyant Cloud auth broker is misconfigured\" }, 500)\n }\n }\n\n async function handleCloudAuthCallback(c: Context<AuthHonoEnv>) {\n if (!isVoyantCloudAuthMode(c.env)) {\n return c.json({ error: \"Not found\" }, 404)\n }\n\n const exchangeConfig = getCloudAuthExchangeConfig(c.env)\n if (!exchangeConfig) {\n const url = new URL(c.req.url)\n return c.json({ error: \"Voyant Cloud auth exchange is not configured yet\" }, 501, {\n \"Set-Cookie\": buildClearCloudAdminAuthStateCookie(\n url.protocol === \"https:\",\n url.pathname.replace(/\\/callback$/, \"\") || \"/auth/cloud\",\n ),\n })\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const request = c.req.path.startsWith(\"/auth/admin/\")\n ? c.req.raw\n : rewriteLegacyAdminAuthRequest(c.req.raw)\n return await betterAuth.handler(request)\n } catch (error) {\n console.error(\"[auth/cloud/callback] Error:\", error)\n return c.json({ error: \"Voyant Cloud auth callback failed\" }, 500)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n }\n\n auth.get(\"/auth/admin/cloud/start\", handleCloudAuthStart)\n auth.get(\"/auth/admin/cloud/callback\", handleCloudAuthCallback)\n /** @deprecated Use /auth/admin/cloud/*. */\n auth.get(\"/auth/cloud/start\", handleCloudAuthStart)\n auth.get(\"/auth/cloud/callback\", handleCloudAuthCallback)\n\n auth.all(\"/auth/api-tokens\", handleApiTokensFacade)\n auth.all(\"/auth/api-tokens/:keyId\", handleApiTokensFacade)\n auth.all(\"/auth/api-tokens/:keyId/rotate\", handleApiTokensFacade)\n auth.get(\"/auth/organization/list-members\", handleOrganizationMembersFacade)\n\n auth.get(\"/auth/customer/status\", async (c) => {\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildCustomerBetterAuth(c.env, db, c.req.raw)\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n return c.json({ authenticated: Boolean(session) })\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n auth.get(\"/auth/customer/config\", (c) => {\n if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return c.json({\n methods: {\n emailCode: false,\n emailPassword: false,\n google: false,\n facebook: false,\n apple: false,\n },\n })\n }\n return c.json(publicCustomerAuthConfiguration(c.env, c.req.raw))\n })\n\n auth.all(\"/auth/customer/*\", async (c) => {\n if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return c.json({ error: \"Customer auth is disabled\" }, 404)\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildCustomerBetterAuth(c.env, db, c.req.raw)\n return await betterAuth.handler(c.req.raw)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n /**\n * Catch-all: delegate to Better Auth handler.\n * Handles sign-in, sign-up, sign-out, password reset, OAuth callbacks, etc.\n *\n * Sign-up is gated by a `user.create.before` hook in @voyant-travel/auth — once a\n * user exists, the hook throws and BA returns an error to the client.\n */\n auth.all(\"/auth/admin/*\", async (c) => {\n if (isVoyantCloudAuthMode(c.env) && !isCloudAllowedBetterAuthRoute(c.req.raw)) {\n return localAuthDisabledResponse(c)\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n return await betterAuth.handler(c.req.raw)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n /** @deprecated Admin Better Auth routes moved to /auth/admin/*. */\n auth.all(\"/auth/*\", async (c) => {\n const rewritten = rewriteLegacyAdminAuthRequest(c.req.raw)\n if (isVoyantCloudAuthMode(c.env) && !isCloudAllowedBetterAuthRoute(rewritten)) {\n return localAuthDisabledResponse(c)\n }\n const { db, dispose } = openDatabase(c.env)\n try {\n return await buildAdminBetterAuth(c.env, db).handler(rewritten)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n return {\n handler: auth,\n getBootstrapStatusForRequest,\n getCurrentUserForRequest,\n hasAuthPermission,\n resolveAuthRequest,\n validateApiTokenAccess,\n }\n}\n"]}
1
+ {"version":3,"file":"node-runtime.js","sourceRoot":"","sources":["../src/node-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Better Auth Node runtime for Hono.\n *\n * agent-quality: file-size exception -- Auth handler keeps local and Voyant Cloud auth flows co-located until the route surface is split by auth mode.\n *\n * Mounts Better Auth at /auth/* for authentication operations.\n * Same-origin — no CORS needed. Session cookies work naturally.\n *\n * Also provides /auth/status (user provisioning) and /auth/me (user info).\n */\n\nimport { type NodeDatabaseEnv, openNodeDatabase } from \"@voyant-travel/db/runtime\"\nimport {\n authUser,\n cloudAuthUserLinks,\n type SelectApikey,\n userProfilesTable,\n} from \"@voyant-travel/db/schema/iam\"\nimport type { Reporter, VoyantDb, VoyantRequestAuthContext } from \"@voyant-travel/hono\"\nimport {\n handleApiError,\n reportException,\n requestId,\n} from \"@voyant-travel/hono/middleware/error-boundary\"\nimport { getRequestId } from \"@voyant-travel/hono/observability\"\nimport type { AccessCatalog } from \"@voyant-travel/types/api-keys\"\nimport { accessCatalogScopesForRole, isFullAccessRole } from \"@voyant-travel/types/member-roles\"\nimport { eq, sql } from \"drizzle-orm\"\nimport { type Context, Hono } from \"hono\"\nimport {\n createVoyantCloudAdminAuthPlugin,\n revalidateVoyantCloudAdminAuthSession,\n revalidateVoyantCloudAdminAuthUser,\n} from \"./cloud-admin-session.js\"\nimport { buildClearCloudAdminAuthStateCookie, createCloudAdminAuthStart } from \"./cloud-broker.js\"\nimport {\n type CreateBetterAuthOptions,\n type CustomerAuthMethods,\n createAdminBetterAuth,\n createCustomerBetterAuth,\n handleApiTokenManagementRequest,\n handleOrganizationMembersRequest,\n} from \"./server.js\"\nimport { ensureCurrentUserProfile } from \"./workspace.js\"\n\n// Type ctx so that `c.get(\"db\")` resolves to the parent app's middleware-\n// set `VoyantDb` from the deployment's database lifecycle adapter. Without\n// this, the sub-app sees `unknown` for context vars.\ntype OperatorAuthMode = \"local\" | \"voyant-cloud\"\n\nexport interface OperatorAuthNodeEnv extends NodeDatabaseEnv {\n API_BASE_URL?: string\n APP_URL?: string\n AUTH_COOKIE_DOMAIN?: string\n BETTER_AUTH_ADMIN_SECRET?: string\n BETTER_AUTH_CUSTOMER_SECRET?: string\n CORS_ALLOWLIST?: string\n DASH_BASE_URL?: string\n EMAIL_FROM?: string\n SESSION_CLAIMS_SECRET: string\n VOYANT_ADMIN_AUTH_MODE?: string\n VOYANT_CUSTOMER_AUTH_MODE?: string\n VOYANT_CUSTOMER_AUTH_CONFIG_JSON?: string\n VOYANT_CUSTOMER_AUTH_EMAIL_CODE?: string\n VOYANT_CUSTOMER_AUTH_EMAIL_PASSWORD?: string\n CUSTOMER_AUTH_GOOGLE_CLIENT_ID?: string\n CUSTOMER_AUTH_GOOGLE_CLIENT_SECRET?: string\n CUSTOMER_AUTH_FACEBOOK_CLIENT_ID?: string\n CUSTOMER_AUTH_FACEBOOK_CLIENT_SECRET?: string\n CUSTOMER_AUTH_APPLE_CLIENT_ID?: string\n CUSTOMER_AUTH_APPLE_CLIENT_SECRET?: string\n VOYANT_AUTH_LOG_SECRET_FALLBACKS?: string\n VOYANT_CLOUD_ADMIN_AUTH_AUDIENCE?: string\n VOYANT_CLOUD_ADMIN_AUTH_CLIENT_TOKEN?: string\n VOYANT_CLOUD_ADMIN_AUTH_EXCHANGE_URL?: string\n VOYANT_CLOUD_ADMIN_AUTH_JWKS_URL?: string\n VOYANT_CLOUD_ADMIN_AUTH_REVALIDATE_URL?: string\n VOYANT_CLOUD_ADMIN_AUTH_START_URL?: string\n VOYANT_CLOUD_APP_ID?: string\n VOYANT_CLOUD_DEPLOYMENT_ID?: string\n VOYANT_CLOUD_ENVIRONMENT?: string\n VOYANT_OPERATOR_BROWSER_EVIDENCE?: string\n}\n\nexport interface OperatorCurrentUser {\n id: string\n email: string\n firstName: string | null\n lastName: string | null\n locale: string\n timezone: string | null\n uiPrefs: unknown\n isSuperAdmin: boolean\n isSupportUser: boolean\n createdAt: string\n profilePictureUrl: string | null\n}\n\nexport type OperatorAuthBootstrapStatus = {\n hasUsers: boolean\n authMode?: OperatorAuthMode\n}\n\ntype BetterAuthAdvancedOptions = NonNullable<CreateBetterAuthOptions[\"advanced\"]>\n\n/** Resolve Better Auth's standard cross-subdomain cookie policy for Node hosts. */\nexport function buildBetterAuthCookieAdvancedOptions(\n env: Pick<OperatorAuthNodeEnv, \"AUTH_COOKIE_DOMAIN\">,\n):\n | Pick<BetterAuthAdvancedOptions, \"crossSubDomainCookies\" | \"defaultCookieAttributes\">\n | undefined {\n const domain = env.AUTH_COOKIE_DOMAIN?.trim()\n if (!domain) return undefined\n\n return {\n crossSubDomainCookies: { enabled: true, domain },\n defaultCookieAttributes: { domain },\n }\n}\n\nexport interface OperatorAuthEmailSender {\n sendResetPassword: (input: {\n user: { email: string; name: string }\n url: string\n }) => Promise<void>\n sendVerificationOtp: (input: { email: string; otp: string; type: string }) => Promise<void>\n}\n\nexport interface CreateOperatorAuthNodeRuntimeOptions<Env extends OperatorAuthNodeEnv> {\n accessCatalog: AccessCatalog\n appName: string\n authMode: OperatorAuthMode\n reporter: Reporter\n openDatabase?: (env: Env) => { db: VoyantDb; dispose: () => Promise<void> }\n cookieAdvanced?: (\n env: Env,\n ) =>\n | Pick<BetterAuthAdvancedOptions, \"crossSubDomainCookies\" | \"defaultCookieAttributes\">\n | undefined\n resolveEmailSender?: (env: Env) => OperatorAuthEmailSender | null\n /**\n * Storefront/BFF seam for a canonical public auth origin and resolved\n * merchant credentials. Never derive these values from Host/X-Forwarded-Host.\n */\n resolveCustomerAuthContext?: (\n env: Env,\n policy: CustomerAuthPolicy,\n request: Request,\n ) => CustomerAuthRuntimeContext\n}\n\nexport interface CustomerAuthRuntimeContext {\n baseURL: string\n trustedOrigins: string[]\n methods: CustomerAuthMethods\n}\n\nexport interface CustomerAuthSocialPolicy {\n enabled: boolean\n credentialRef: string | null\n}\n\nexport interface CustomerAuthPolicy {\n methods: {\n emailCode: boolean\n emailPassword: boolean\n google: CustomerAuthSocialPolicy\n facebook: CustomerAuthSocialPolicy\n apple: CustomerAuthSocialPolicy\n }\n}\n\n/**\n * Better Auth is dispatched internally without the hosting `/api` prefix, but\n * OAuth providers must return to the browser-visible route. Keep explicit\n * merchant overrides and supply the canonical public callback otherwise.\n */\nexport function withCustomerSocialRedirectUris(\n methods: CustomerAuthMethods,\n publicApiBaseUrl: string,\n): CustomerAuthMethods {\n const providers = methods.socialProviders\n if (!providers) return methods\n\n const normalizedPublicApiBaseUrl = publicApiBaseUrl.replace(/\\/+$/, \"\")\n const callback = (provider: \"google\" | \"facebook\" | \"apple\") =>\n `${normalizedPublicApiBaseUrl}/auth/customer/callback/${provider}`\n const withRedirectUri = <Provider>(\n provider: Provider | undefined,\n redirectURI: string,\n ): Provider | undefined => {\n if (!provider || typeof provider !== \"object\") return provider\n const configured = provider as Provider & { redirectURI?: string }\n return {\n ...configured,\n redirectURI: configured.redirectURI?.trim() || redirectURI,\n }\n }\n\n return {\n ...methods,\n socialProviders: {\n ...providers,\n ...(providers.google\n ? {\n google: withRedirectUri(providers.google, callback(\"google\")),\n }\n : {}),\n ...(providers.facebook\n ? {\n facebook: withRedirectUri(providers.facebook, callback(\"facebook\")),\n }\n : {}),\n ...(providers.apple\n ? {\n apple: withRedirectUri(providers.apple, callback(\"apple\")),\n }\n : {}),\n },\n }\n}\n\nexport function createOperatorAuthNodeRuntime<Env extends OperatorAuthNodeEnv>(\n runtimeOptions: CreateOperatorAuthNodeRuntimeOptions<Env>,\n) {\n type AuthHonoEnv = { Bindings: Env; Variables: { db: VoyantDb } }\n\n const openDatabase =\n runtimeOptions.openDatabase ??\n ((env: Env) => {\n const resource = openNodeDatabase(env)\n return { db: resource.db as VoyantDb, dispose: resource.dispose }\n })\n\n const auth = new Hono<AuthHonoEnv>()\n // This lean auth app is dispatched around `createVoyantApp` (see\n // api-dispatch.ts), so it must mint/propagate the correlation id and wire\n // the reporter itself — otherwise auth 5xx are an observability blind spot and\n // the user-facing requestId wouldn't be findable (RFC voyant#1553).\n auth.use(\"*\", requestId)\n // `onError` only fires on THROWN exceptions. Several handlers (e.g.\n // /auth/status, the cloud token/revalidate/callback paths) instead RETURN a\n // 5xx via `c.json(..., 50x)`; those bypass `onError`, and this lean app is\n // dispatched around `createVoyantApp` so the framework's auth status-bridge\n // (`mountAuthForwarding`) never runs either. Bridge returned 5xx to the\n // reporter here so they aren't an observability blind spot (RFC voyant#1553).\n // Thrown errors skip this middleware's post-`next()` code (the rejection\n // propagates straight to `onError`), so there's no double report.\n auth.use(\"*\", async (c, next) => {\n await next()\n if (c.res.status >= 500) {\n reportException(runtimeOptions.reporter, c, {\n requestId: getRequestId() ?? \"\",\n app: runtimeOptions.appName,\n error: new Error(`auth handler returned HTTP ${c.res.status}`),\n context: { path: c.req.path, method: c.req.method, status: c.res.status, surface: \"auth\" },\n })\n }\n })\n auth.onError((err, c) =>\n handleApiError(err, c, { reporter: runtimeOptions.reporter, appName: runtimeOptions.appName }),\n )\n\n const DEFAULT_APP_URL = \"http://localhost:3300\"\n const CLOUD_BETTER_AUTH_ALLOWLIST = new Set([\n \"/auth/get-session\",\n \"/auth/jwks\",\n \"/auth/session\",\n \"/auth/sign-out\",\n \"/auth/token\",\n ])\n\n function resolveOperatorAuthMode(_env: Env): OperatorAuthMode {\n return runtimeOptions.authMode\n }\n\n function isVoyantCloudAuthMode(env: Env): boolean {\n return resolveOperatorAuthMode(env) === \"voyant-cloud\"\n }\n\n function isCloudAllowedBetterAuthRoute(request: Request): boolean {\n const url = new URL(request.url)\n const pathname = url.pathname.replace(\"/auth/admin\", \"/auth\").replace(/\\/+$/, \"\") || \"/\"\n return CLOUD_BETTER_AUTH_ALLOWLIST.has(pathname)\n }\n\n function localAuthDisabledResponse(c: Context<AuthHonoEnv>) {\n return c.json({ error: \"Local auth routes are disabled in Voyant Cloud auth mode\" }, 404)\n }\n\n function cloudAuthNotConfiguredResponse(c: Context<AuthHonoEnv>) {\n return c.json({ error: \"Voyant Cloud auth broker is not configured yet\" }, 501)\n }\n\n function normalizeUrl(url: string): string {\n return url.trim().replace(/\\/$/, \"\")\n }\n\n function getAppUrl(env: Env): string {\n const candidates = [\n env.APP_URL,\n env.DASH_BASE_URL,\n env.CORS_ALLOWLIST?.split(\",\")[0],\n DEFAULT_APP_URL,\n ]\n\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.trim().length > 0) {\n return normalizeUrl(candidate)\n }\n }\n\n return DEFAULT_APP_URL\n }\n\n function getTrustedOrigins(env: Env): string[] {\n return Array.from(\n new Set(\n [env.APP_URL, env.DASH_BASE_URL, ...(env.CORS_ALLOWLIST ?? \"\").split(\",\")]\n .map((value) => value?.trim())\n .filter((value): value is string => Boolean(value)),\n ),\n ).map(normalizeUrl)\n }\n\n function getAuthBaseUrl(env: Env): string {\n // entry.ts strips /api before delegating to the Hono app, so Better Auth\n // sees paths like /auth/*. Its baseURL must be the origin only (no /api).\n const appUrl = getAppUrl(env)\n try {\n const parsed = new URL(appUrl)\n return `${parsed.protocol}//${parsed.host}`\n } catch {\n return appUrl\n }\n }\n\n function getPublicApiBaseUrl(env: Env): string {\n const candidate = env.API_BASE_URL?.trim() || env.APP_URL?.trim() || `${getAppUrl(env)}/api`\n const normalized = normalizeUrl(candidate)\n\n try {\n const parsed = new URL(normalized)\n if (parsed.pathname === \"/\" || parsed.pathname === \"\") {\n parsed.pathname = \"/api\"\n return normalizeUrl(parsed.toString())\n }\n } catch {\n return normalized\n }\n\n return normalized\n }\n\n function getCloudAuthStartConfig(env: Env) {\n const deploymentId = env.VOYANT_CLOUD_DEPLOYMENT_ID?.trim()\n const cloudAuthStartUrl = env.VOYANT_CLOUD_ADMIN_AUTH_START_URL?.trim()\n if (!deploymentId || !cloudAuthStartUrl) return null\n\n return {\n cloudAuthStartUrl,\n deploymentId,\n adminCallbackUrl: `${getPublicApiBaseUrl(env)}/auth/admin/cloud/callback`,\n cookieSecret: env.SESSION_CLAIMS_SECRET,\n appId: env.VOYANT_CLOUD_APP_ID?.trim() || undefined,\n environment: env.VOYANT_CLOUD_ENVIRONMENT?.trim() || undefined,\n }\n }\n\n function getCloudAuthExchangeConfig(env: Env) {\n const deploymentId = env.VOYANT_CLOUD_DEPLOYMENT_ID?.trim()\n const exchangeUrl = env.VOYANT_CLOUD_ADMIN_AUTH_EXCHANGE_URL?.trim()\n const assertionJwksUrl = env.VOYANT_CLOUD_ADMIN_AUTH_JWKS_URL?.trim()\n const clientToken = env.VOYANT_CLOUD_ADMIN_AUTH_CLIENT_TOKEN?.trim()\n if (!deploymentId || !exchangeUrl || !assertionJwksUrl || !clientToken) return null\n\n return {\n exchangeUrl,\n deploymentId,\n clientToken,\n assertionJwksUrl,\n assertionAudience: env.VOYANT_CLOUD_ADMIN_AUTH_AUDIENCE?.trim() || deploymentId,\n }\n }\n\n function getCloudAuthRevalidateConfig(env: Env) {\n const deploymentId = env.VOYANT_CLOUD_DEPLOYMENT_ID?.trim()\n const revalidateUrl = env.VOYANT_CLOUD_ADMIN_AUTH_REVALIDATE_URL?.trim()\n const clientToken = env.VOYANT_CLOUD_ADMIN_AUTH_CLIENT_TOKEN?.trim()\n if (!deploymentId || !revalidateUrl || !clientToken) return null\n\n return {\n revalidateUrl,\n deploymentId,\n clientToken,\n }\n }\n\n function isLocalRequest(request: Request): boolean {\n const hostname = new URL(request.url).hostname\n return hostname === \"127.0.0.1\" || hostname === \"localhost\"\n }\n\n function shouldUseBrowserEvidenceAuthFallback(env: Env, request: Request): boolean {\n return env.VOYANT_OPERATOR_BROWSER_EVIDENCE === \"1\" && isLocalRequest(request)\n }\n\n function allowAuthSecretLogging(env: Env): boolean {\n return env.VOYANT_AUTH_LOG_SECRET_FALLBACKS === \"1\"\n }\n\n /**\n * Build a Better Auth instance backed by a caller-provided drizzle\n * client. The caller owns the Pool lifecycle (open before, dispose\n * after) so the same Pool can serve both the auth lookup and any\n * subsequent queries the route does — without spinning up a second\n * connection per request.\n *\n * The deployment decides whether this is a request-scoped or resident Node\n * pool. The Better Auth instance is not cached independently of that owner.\n */\n function requireAdminAuthSecret(env: Env): string {\n const secret = env.BETTER_AUTH_ADMIN_SECRET?.trim()\n if (!secret) throw new Error(\"Admin auth requires BETTER_AUTH_ADMIN_SECRET\")\n return secret\n }\n\n function requireCustomerAuthSecret(env: Env): string {\n const secret = env.BETTER_AUTH_CUSTOMER_SECRET?.trim()\n if (!secret) throw new Error(\"Customer auth requires BETTER_AUTH_CUSTOMER_SECRET\")\n return secret\n }\n\n function envEnabled(value: string | undefined, fallback: boolean): boolean {\n const normalized = value?.trim().toLowerCase()\n if (!normalized) return fallback\n return normalized === \"1\" || normalized === \"true\" || normalized === \"yes\"\n }\n\n function parseCustomerAuthPolicy(env: Env): CustomerAuthPolicy {\n const fallback = {\n methods: {\n emailCode: envEnabled(env.VOYANT_CUSTOMER_AUTH_EMAIL_CODE, true),\n emailPassword: envEnabled(env.VOYANT_CUSTOMER_AUTH_EMAIL_PASSWORD, true),\n google: { enabled: false, credentialRef: null },\n facebook: { enabled: false, credentialRef: null },\n apple: { enabled: false, credentialRef: null },\n },\n } satisfies CustomerAuthPolicy\n const raw = env.VOYANT_CUSTOMER_AUTH_CONFIG_JSON?.trim()\n if (!raw) return fallback\n try {\n const parsed = JSON.parse(raw) as {\n methods?: Record<string, unknown>\n }\n const methods = parsed.methods ?? {}\n const social = (value: unknown): CustomerAuthSocialPolicy => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return { enabled: false, credentialRef: null }\n }\n const record = value as Record<string, unknown>\n return {\n enabled: record.enabled === true,\n credentialRef:\n typeof record.credentialRef === \"string\" && record.credentialRef.trim()\n ? record.credentialRef.trim()\n : null,\n }\n }\n return {\n methods: {\n emailCode:\n typeof methods.emailCode === \"boolean\" ? methods.emailCode : fallback.methods.emailCode,\n emailPassword:\n typeof methods.emailPassword === \"boolean\"\n ? methods.emailPassword\n : fallback.methods.emailPassword,\n google: social(methods.google),\n facebook: social(methods.facebook),\n apple: social(methods.apple),\n },\n }\n } catch {\n console.error(\n \"[auth/customer] Invalid VOYANT_CUSTOMER_AUTH_CONFIG_JSON; failing social auth closed\",\n )\n return fallback\n }\n }\n\n function defaultCustomerAuthContext(\n env: Env,\n policy: CustomerAuthPolicy,\n ): CustomerAuthRuntimeContext {\n const hasCanonicalPolicy = Boolean(env.VOYANT_CUSTOMER_AUTH_CONFIG_JSON?.trim())\n const google = Boolean(\n env.CUSTOMER_AUTH_GOOGLE_CLIENT_ID?.trim() &&\n env.CUSTOMER_AUTH_GOOGLE_CLIENT_SECRET?.trim() &&\n (!hasCanonicalPolicy || policy.methods.google.enabled),\n )\n const facebook = Boolean(\n env.CUSTOMER_AUTH_FACEBOOK_CLIENT_ID?.trim() &&\n env.CUSTOMER_AUTH_FACEBOOK_CLIENT_SECRET?.trim() &&\n (!hasCanonicalPolicy || policy.methods.facebook.enabled),\n )\n const apple = Boolean(\n env.CUSTOMER_AUTH_APPLE_CLIENT_ID?.trim() &&\n env.CUSTOMER_AUTH_APPLE_CLIENT_SECRET?.trim() &&\n (!hasCanonicalPolicy || policy.methods.apple.enabled),\n )\n return {\n baseURL: getAuthBaseUrl(env),\n trustedOrigins: getTrustedOrigins(env),\n methods: {\n emailCode: policy.methods.emailCode,\n emailPassword: policy.methods.emailPassword,\n socialProviders: {\n ...(google\n ? {\n google: {\n clientId: env.CUSTOMER_AUTH_GOOGLE_CLIENT_ID!.trim(),\n clientSecret: env.CUSTOMER_AUTH_GOOGLE_CLIENT_SECRET!.trim(),\n },\n }\n : {}),\n ...(facebook\n ? {\n facebook: {\n clientId: env.CUSTOMER_AUTH_FACEBOOK_CLIENT_ID!.trim(),\n clientSecret: env.CUSTOMER_AUTH_FACEBOOK_CLIENT_SECRET!.trim(),\n },\n }\n : {}),\n ...(apple\n ? {\n apple: {\n clientId: env.CUSTOMER_AUTH_APPLE_CLIENT_ID!.trim(),\n clientSecret: env.CUSTOMER_AUTH_APPLE_CLIENT_SECRET!.trim(),\n },\n }\n : {}),\n },\n },\n }\n }\n\n function resolveCustomerAuthContext(env: Env, request: Request): CustomerAuthRuntimeContext {\n const policy = parseCustomerAuthPolicy(env)\n return (\n runtimeOptions.resolveCustomerAuthContext?.(env, policy, request) ??\n defaultCustomerAuthContext(env, policy)\n )\n }\n\n function publicCustomerAuthConfiguration(env: Env, request: Request) {\n const methods = resolveCustomerAuthContext(env, request).methods\n const providers = methods.socialProviders ?? {}\n return {\n methods: {\n emailCode: methods.emailCode ?? true,\n emailPassword: methods.emailPassword ?? true,\n google: Boolean(providers.google),\n facebook: Boolean(providers.facebook),\n apple: Boolean(providers.apple),\n },\n }\n }\n\n function buildAdminBetterAuth(env: Env, db: VoyantDb) {\n const emailSender = runtimeOptions.resolveEmailSender?.(env)\n const cloudAuthExchange = isVoyantCloudAuthMode(env) ? getCloudAuthExchangeConfig(env) : null\n const authDb = db as NonNullable<Parameters<typeof createAdminBetterAuth>[0]>[\"db\"]\n const cloudAuthDb = db as Parameters<typeof createVoyantCloudAdminAuthPlugin>[0][\"db\"]\n\n return createAdminBetterAuth({\n // `db` is a `NeonDatabase` (neon-serverless WebSocket); the\n // `CreateBetterAuthOptions.db` type still references the older\n // `getDb` return union (postgres-js + neon-http). Drizzle's\n // PgDatabase surface is identical across flavors at runtime, so\n // the cast is structurally safe — better-auth's drizzleAdapter\n // works on any PgDatabase. See #500 for context.\n db: authDb,\n secret: requireAdminAuthSecret(env),\n baseURL: getAuthBaseUrl(env),\n basePath: \"/auth/admin\",\n trustedOrigins: getTrustedOrigins(env),\n advanced: (runtimeOptions.cookieAdvanced ?? buildBetterAuthCookieAdvancedOptions)(env),\n plugins: cloudAuthExchange\n ? [\n createVoyantCloudAdminAuthPlugin({\n db: cloudAuthDb,\n cookieSecret: env.SESSION_CLAIMS_SECRET,\n exchange: cloudAuthExchange,\n }),\n ]\n : undefined,\n sendResetPassword: async ({ user, url }) => {\n if (!emailSender) {\n // No email provider (e.g. local dev without a sending domain): with the\n // debug flag on, log the link to the console instead of sending;\n // otherwise fail loudly. Never bypasses a configured cloud sender.\n if (allowAuthSecretLogging(env)) {\n console.info(`[auth] reset-password (debug fallback) -> ${user.email}: ${url}`)\n return\n }\n throw new Error(\"Password reset email provider is not configured\")\n }\n await emailSender.sendResetPassword({ user, url })\n },\n sendVerificationOTP: async ({ email, otp, type }) => {\n if (!emailSender) {\n // No email provider (e.g. local dev without a sending domain): with the\n // debug flag on, log the OTP to the console instead of sending;\n // otherwise fail loudly. Never bypasses a configured cloud sender.\n if (allowAuthSecretLogging(env)) {\n console.info(`[auth] verification-otp (debug fallback) [${type}] -> ${email}: ${otp}`)\n return\n }\n throw new Error(\"Verification OTP email provider is not configured\")\n }\n await emailSender.sendVerificationOtp({ email, otp, type })\n },\n })\n }\n\n function buildCustomerBetterAuth(env: Env, db: VoyantDb, request: Request) {\n const emailSender = runtimeOptions.resolveEmailSender?.(env)\n const context = resolveCustomerAuthContext(env, request)\n const authDb = db as NonNullable<Parameters<typeof createCustomerBetterAuth>[0]>[\"db\"]\n return createCustomerBetterAuth({\n db: authDb,\n secret: requireCustomerAuthSecret(env),\n baseURL: context.baseURL,\n basePath: \"/auth/customer\",\n trustedOrigins: context.trustedOrigins,\n methods: withCustomerSocialRedirectUris(context.methods, getPublicApiBaseUrl(env)),\n sendResetPassword: async ({ user, url }) => {\n if (!emailSender) {\n if (allowAuthSecretLogging(env)) {\n console.info(`[auth/customer] reset-password (debug fallback) -> ${user.email}: ${url}`)\n return\n }\n throw new Error(\"Password reset email provider is not configured\")\n }\n await emailSender.sendResetPassword({ user, url })\n },\n sendVerificationOTP: async ({ email, otp, type }) => {\n if (!emailSender) {\n if (allowAuthSecretLogging(env)) {\n console.info(\n `[auth/customer] verification-otp (debug fallback) [${type}] -> ${email}: ${otp}`,\n )\n return\n }\n throw new Error(\"Verification OTP email provider is not configured\")\n }\n await emailSender.sendVerificationOtp({ email, otp, type })\n },\n })\n }\n\n function rewriteLegacyAdminAuthRequest(request: Request): Request {\n const url = new URL(request.url)\n url.pathname = url.pathname.replace(\"/auth\", \"/auth/admin\")\n return new Request(url, request)\n }\n\n const FULL_ACCESS_SCOPES = [\"*\"]\n\n function scopesForOperatorRole(role: string | null | undefined): string[] | null {\n const base = accessCatalogScopesForRole(role, runtimeOptions.accessCatalog)\n if (!base) return null\n const normalizedRole = (role ?? \"\").trim().toLowerCase()\n const presetId =\n normalizedRole === \"member\"\n ? \"editor\"\n : normalizedRole === \"guest\"\n ? \"viewer\"\n : normalizedRole\n const selected = runtimeOptions.accessCatalog.presets.find(\n (preset) => preset.kind === \"staff\" && preset.id === presetId,\n )\n return [...new Set([...base, ...(selected?.grants ?? [])])].sort()\n }\n\n /**\n * Resolve a member's RBAC scope set for the request (`resource:action` strings,\n * shared with API keys — see @voyant-travel/types/member-roles, RFC voyant#2085).\n *\n * Phase 1: storage + seam are wired but default to full access, so behavior is\n * unchanged until an admin assigns permissions (Phase 2) and routes gate on them\n * (Phase 3).\n * - voyant-cloud: assertion-mirrored `cloud_auth_user_links.scopes` if the\n * platform sent them, else the role bundle for `roleSlug`, else full access.\n * - local: the member's `user_profiles.permissions` if assigned, else full\n * access (no local role concept yet).\n */\n async function resolveMemberScopes(db: VoyantDb, env: Env, userId: string): Promise<string[]> {\n if (isVoyantCloudAuthMode(env)) {\n const [link] = await db\n .select({ scopes: cloudAuthUserLinks.scopes, roleSlug: cloudAuthUserLinks.roleSlug })\n .from(cloudAuthUserLinks)\n .where(eq(cloudAuthUserLinks.userId, userId))\n .limit(1)\n const fullAccessScopes = scopesForOperatorRole(\"admin\") ?? FULL_ACCESS_SCOPES\n const roleScopes = scopesForOperatorRole(link?.roleSlug) ?? fullAccessScopes\n return isFullAccessRole(link?.roleSlug) ? roleScopes : (link?.scopes ?? roleScopes)\n }\n\n const [profile] = await db\n .select({ permissions: userProfilesTable.permissions })\n .from(userProfilesTable)\n .where(eq(userProfilesTable.id, userId))\n .limit(1)\n return profile?.permissions ?? FULL_ACCESS_SCOPES\n }\n\n async function resolveAuthRequest(\n request: Request,\n env: Env,\n ): Promise<VoyantRequestAuthContext | null> {\n const customerSurface = new URL(request.url).pathname.includes(\"/v1/public/\")\n if (customerSurface && env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return null\n }\n\n const { db, dispose } = openDatabase(env)\n try {\n const auth = customerSurface\n ? buildCustomerBetterAuth(env, db, request)\n : buildAdminBetterAuth(env, db)\n const session = await auth.api.getSession({ headers: request.headers })\n\n if (!session) {\n return null\n }\n\n if (!customerSurface && isVoyantCloudAuthMode(env)) {\n const revalidateConfig = getCloudAuthRevalidateConfig(env)\n if (!revalidateConfig) {\n return null\n }\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthSession({\n db: db as Parameters<typeof revalidateVoyantCloudAdminAuthSession>[0][\"db\"],\n sessionId: session.session.id,\n config: revalidateConfig,\n })\n\n if (!revalidation.ok) {\n return null\n }\n } catch (error) {\n console.error(\"[auth/session] Cloud revalidation failed:\", error)\n return null\n }\n }\n\n if (customerSurface) {\n return {\n userId: session.user.id,\n sessionId: session.session.id,\n organizationId: null,\n callerType: \"session\",\n actor: \"customer\",\n realm: \"customer\",\n scopes: [],\n email: session.user.email ?? null,\n }\n }\n\n return {\n userId: session.user.id,\n sessionId: session.session.id,\n organizationId: null,\n callerType: \"session\",\n actor: \"staff\",\n realm: \"admin\",\n // Member RBAC scope set (RFC voyant#2085). Defaults to full access until\n // an admin assigns permissions, so existing deployments are unchanged.\n // `actor: \"staff\"` is retained, so actor-gated paths (incl. the\n // bookings-pii reveal, which short-circuits on staff) are unaffected.\n scopes: await resolveMemberScopes(db, env, session.user.id),\n email: session.user.email ?? null,\n }\n } finally {\n // No `executionCtx` reachable here (called from middleware that\n // doesn't pass one through). Await inline so the WebSocket closes\n // before this fn returns.\n await dispose()\n }\n }\n\n /**\n * Single-tenant: every authenticated session is a staff user with full access.\n * When `resolveAuthRequest` has already granted a session, permissions are\n * implicitly allowed. If you need granular RBAC later, switch on\n * `user_profiles.isSuperAdmin` / `isSupportUser` here.\n */\n async function hasAuthPermission(request: Request, env: Env): Promise<boolean> {\n const auth = await resolveAuthRequest(request, env)\n return auth !== null\n }\n\n class CurrentUserNotFoundError extends Error {\n constructor() {\n super(\"User not found\")\n this.name = \"CurrentUserNotFoundError\"\n }\n }\n\n async function getCurrentUserForRequest(\n request: Request,\n env: Env,\n ): Promise<OperatorCurrentUser | null> {\n if (shouldUseBrowserEvidenceAuthFallback(env, request)) {\n return null\n }\n\n const { db, dispose } = openDatabase(env)\n try {\n const betterAuth = buildAdminBetterAuth(env, db)\n const session = await betterAuth.api.getSession({ headers: request.headers })\n if (!session) {\n return null\n }\n\n const [row] = await db\n .select({\n id: authUser.id,\n email: authUser.email,\n createdAt: authUser.createdAt,\n firstName: userProfilesTable.firstName,\n lastName: userProfilesTable.lastName,\n locale: userProfilesTable.locale,\n timezone: userProfilesTable.timezone,\n uiPrefs: userProfilesTable.uiPrefs,\n avatarUrl: userProfilesTable.avatarUrl,\n isSuperAdmin: userProfilesTable.isSuperAdmin,\n isSupportUser: userProfilesTable.isSupportUser,\n })\n .from(authUser)\n .leftJoin(userProfilesTable, eq(userProfilesTable.id, authUser.id))\n .where(eq(authUser.id, session.user.id))\n .limit(1)\n\n if (!row) {\n throw new CurrentUserNotFoundError()\n }\n\n return {\n id: row.id,\n email: row.email ?? session.user.email ?? \"\",\n firstName: row.firstName ?? null,\n lastName: row.lastName ?? null,\n locale: row.locale ?? \"en\",\n timezone: row.timezone ?? null,\n uiPrefs: row.uiPrefs ?? null,\n isSuperAdmin: row.isSuperAdmin ?? false,\n isSupportUser: row.isSupportUser ?? false,\n createdAt: row.createdAt?.toISOString() ?? new Date().toISOString(),\n profilePictureUrl: row.avatarUrl ?? null,\n }\n } finally {\n await dispose()\n }\n }\n\n async function getBootstrapStatusForRequest(\n request: Request,\n env: Env,\n ): Promise<OperatorAuthBootstrapStatus> {\n if (shouldUseBrowserEvidenceAuthFallback(env, request)) {\n return { hasUsers: true }\n }\n\n if (isVoyantCloudAuthMode(env)) {\n return { hasUsers: true, authMode: \"voyant-cloud\" }\n }\n\n const { db, dispose } = openDatabase(env)\n try {\n const [row] = await db.select({ count: sql<number>`count(*)::int` }).from(authUser)\n return { hasUsers: (row?.count ?? 0) > 0, authMode: \"local\" }\n } finally {\n await dispose()\n }\n }\n\n async function validateApiTokenAccess(\n env: Env,\n db: VoyantDb,\n apiKey: SelectApikey,\n ): Promise<boolean> {\n if (!isVoyantCloudAuthMode(env)) return true\n\n const revalidateConfig = getCloudAuthRevalidateConfig(env)\n if (!revalidateConfig) return false\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthUser({\n db: db as Parameters<typeof revalidateVoyantCloudAdminAuthUser>[0][\"db\"],\n userId: apiKey.referenceId,\n config: revalidateConfig,\n })\n return revalidation.ok\n } catch (error) {\n console.error(\"[auth/api-token] Cloud revalidation failed:\", error)\n return false\n }\n }\n\n /**\n * GET /auth/me\n * Returns the current authenticated user's profile.\n * Validates the session cookie directly (no Bearer token needed).\n */\n auth.get(\"/auth/me\", async (c) => {\n try {\n const currentUser = await getCurrentUserForRequest(c.req.raw, c.env)\n if (!currentUser) {\n return c.json({ error: \"Unauthorized\" }, 401)\n }\n return c.json(currentUser)\n } catch (error) {\n if (error instanceof CurrentUserNotFoundError) {\n return c.json({ error: \"User not found\" }, 404)\n }\n throw error\n }\n })\n\n /**\n * GET /auth/status\n * Ensures the authenticated user has a user_profiles row.\n * Profile is normally created by the BA databaseHook on sign-up,\n * but this route serves as an idempotent fallback.\n */\n auth.get(\"/auth/status\", async (c) => {\n // See `/auth/me` above — auth sub-app runs before the request `db`\n // middleware, so own the Pool here.\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n if (!session) {\n return c.json({ userExists: false, authenticated: false })\n }\n\n const userId = session.user.id\n\n const status = await ensureCurrentUserProfile(\n db as Parameters<typeof ensureCurrentUserProfile>[0],\n userId,\n )\n if (!status.userExists && status.authenticated) {\n console.error(\"[auth/status] Error:\", status.reason)\n return c.json(status, 500)\n }\n\n return c.json(status)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n /**\n * GET /auth/bootstrap-status\n * Public endpoint — reveals whether any user exists. Used by the sign-in /\n * sign-up route loaders to pick the right flow.\n */\n auth.get(\"/auth/bootstrap-status\", async (c) => {\n return c.json(await getBootstrapStatusForRequest(c.req.raw, c.env))\n })\n\n async function handleApiTokensFacade(c: Context<AuthHonoEnv>) {\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const cloudAuthDb = db as Parameters<typeof revalidateVoyantCloudAdminAuthSession>[0][\"db\"]\n\n if (isVoyantCloudAuthMode(c.env)) {\n const revalidateConfig = getCloudAuthRevalidateConfig(c.env)\n if (!revalidateConfig) {\n return c.json(\n { error: \"Cloud-mode API token management requires membership revalidation\" },\n 501,\n )\n }\n\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n if (!session) {\n return c.json({ error: \"Unauthorized\" }, 401)\n }\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthSession({\n db: cloudAuthDb,\n sessionId: session.session.id,\n config: revalidateConfig,\n })\n\n if (!revalidation.ok) {\n return c.json({ error: \"Voyant Cloud access revoked\" }, 403)\n }\n } catch (error) {\n console.error(\"[auth/api-tokens] Cloud revalidation failed:\", error)\n return c.json({ error: \"Voyant Cloud access could not be revalidated\" }, 503)\n }\n }\n\n return (\n (await handleApiTokenManagementRequest(c.req.raw, betterAuth, {\n db,\n accessCatalog: runtimeOptions.accessCatalog,\n })) ?? c.json({ error: \"Not found\" }, 404)\n )\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n }\n\n async function handleOrganizationMembersFacade(c: Context<AuthHonoEnv>) {\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const cloudAuthDb = db as Parameters<typeof revalidateVoyantCloudAdminAuthSession>[0][\"db\"]\n\n if (isVoyantCloudAuthMode(c.env)) {\n const revalidateConfig = getCloudAuthRevalidateConfig(c.env)\n if (!revalidateConfig) {\n return c.json(\n { error: \"Cloud-mode organization member lookup requires membership revalidation\" },\n 501,\n )\n }\n\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n if (!session) {\n return c.json({ error: \"Unauthorized\" }, 401)\n }\n\n try {\n const revalidation = await revalidateVoyantCloudAdminAuthSession({\n db: cloudAuthDb,\n sessionId: session.session.id,\n config: revalidateConfig,\n })\n\n if (!revalidation.ok) {\n return c.json({ error: \"Voyant Cloud access revoked\" }, 403)\n }\n } catch (error) {\n console.error(\"[auth/organization-members] Cloud revalidation failed:\", error)\n return c.json({ error: \"Voyant Cloud access could not be revalidated\" }, 503)\n }\n }\n\n const organizationMembersDb = db as Parameters<\n typeof handleOrganizationMembersRequest\n >[2][\"db\"]\n return (\n (await handleOrganizationMembersRequest(c.req.raw, betterAuth, {\n db: organizationMembersDb,\n })) ?? c.json({ error: \"Not found\" }, 404)\n )\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n }\n\n async function handleCloudAuthStart(c: Context<AuthHonoEnv>) {\n if (!isVoyantCloudAuthMode(c.env)) {\n return c.json({ error: \"Not found\" }, 404)\n }\n\n const config = getCloudAuthStartConfig(c.env)\n if (!config) {\n return cloudAuthNotConfiguredResponse(c)\n }\n\n try {\n const start = await createCloudAdminAuthStart({\n requestUrl: c.req.url,\n next: c.req.query(\"next\"),\n config,\n })\n return new Response(null, {\n status: 302,\n headers: {\n Location: start.redirectUrl,\n \"Set-Cookie\": start.setCookie,\n },\n })\n } catch (error) {\n console.error(\"[auth/cloud/start] Error:\", error)\n return c.json({ error: \"Voyant Cloud auth broker is misconfigured\" }, 500)\n }\n }\n\n async function handleCloudAuthCallback(c: Context<AuthHonoEnv>) {\n if (!isVoyantCloudAuthMode(c.env)) {\n return c.json({ error: \"Not found\" }, 404)\n }\n\n const exchangeConfig = getCloudAuthExchangeConfig(c.env)\n if (!exchangeConfig) {\n const url = new URL(c.req.url)\n return c.json({ error: \"Voyant Cloud auth exchange is not configured yet\" }, 501, {\n \"Set-Cookie\": buildClearCloudAdminAuthStateCookie(\n url.protocol === \"https:\",\n url.pathname.replace(/\\/callback$/, \"\") || \"/auth/cloud\",\n ),\n })\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n const request = c.req.path.startsWith(\"/auth/admin/\")\n ? c.req.raw\n : rewriteLegacyAdminAuthRequest(c.req.raw)\n return await betterAuth.handler(request)\n } catch (error) {\n console.error(\"[auth/cloud/callback] Error:\", error)\n return c.json({ error: \"Voyant Cloud auth callback failed\" }, 500)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n }\n\n auth.get(\"/auth/admin/cloud/start\", handleCloudAuthStart)\n auth.get(\"/auth/admin/cloud/callback\", handleCloudAuthCallback)\n /** @deprecated Use /auth/admin/cloud/*. */\n auth.get(\"/auth/cloud/start\", handleCloudAuthStart)\n auth.get(\"/auth/cloud/callback\", handleCloudAuthCallback)\n\n auth.all(\"/auth/api-tokens\", handleApiTokensFacade)\n auth.all(\"/auth/api-tokens/:keyId\", handleApiTokensFacade)\n auth.all(\"/auth/api-tokens/:keyId/rotate\", handleApiTokensFacade)\n auth.get(\"/auth/organization/list-members\", handleOrganizationMembersFacade)\n\n auth.get(\"/auth/customer/status\", async (c) => {\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildCustomerBetterAuth(c.env, db, c.req.raw)\n const session = await betterAuth.api.getSession({ headers: c.req.raw.headers })\n return c.json({ authenticated: Boolean(session) })\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n auth.get(\"/auth/customer/config\", (c) => {\n if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return c.json({\n methods: {\n emailCode: false,\n emailPassword: false,\n google: false,\n facebook: false,\n apple: false,\n },\n })\n }\n return c.json(publicCustomerAuthConfiguration(c.env, c.req.raw))\n })\n\n auth.all(\"/auth/customer/*\", async (c) => {\n if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return c.json({ error: \"Customer auth is disabled\" }, 404)\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildCustomerBetterAuth(c.env, db, c.req.raw)\n return await betterAuth.handler(c.req.raw)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n /**\n * Catch-all: delegate to Better Auth handler.\n * Handles sign-in, sign-up, sign-out, password reset, OAuth callbacks, etc.\n *\n * Sign-up is gated by a `user.create.before` hook in @voyant-travel/auth — once a\n * user exists, the hook throws and BA returns an error to the client.\n */\n auth.all(\"/auth/admin/*\", async (c) => {\n if (isVoyantCloudAuthMode(c.env) && !isCloudAllowedBetterAuthRoute(c.req.raw)) {\n return localAuthDisabledResponse(c)\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = buildAdminBetterAuth(c.env, db)\n return await betterAuth.handler(c.req.raw)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n /** @deprecated Admin Better Auth routes moved to /auth/admin/*. */\n auth.all(\"/auth/*\", async (c) => {\n const rewritten = rewriteLegacyAdminAuthRequest(c.req.raw)\n if (isVoyantCloudAuthMode(c.env) && !isCloudAllowedBetterAuthRoute(rewritten)) {\n return localAuthDisabledResponse(c)\n }\n const { db, dispose } = openDatabase(c.env)\n try {\n return await buildAdminBetterAuth(c.env, db).handler(rewritten)\n } finally {\n c.executionCtx.waitUntil(dispose())\n }\n })\n\n return {\n handler: auth,\n getBootstrapStatusForRequest,\n getCurrentUserForRequest,\n hasAuthPermission,\n resolveAuthRequest,\n validateApiTokenAccess,\n }\n}\n"]}
package/dist/server.js CHANGED
@@ -9,9 +9,9 @@ import { createLocalMemberAccessPlugin, isLocalMemberDeactivated, isLocalMemberE
9
9
  import { expandTrustedOrigins, getTrustedOrigins } from "./trusted-origins.js";
10
10
  import { isFirstAuthUser, provisionCurrentUserProfile } from "./workspace.js";
11
11
  export function getAuthSecret() {
12
- const secret = process.env.BETTER_AUTH_SECRET || "";
12
+ const secret = process.env.BETTER_AUTH_ADMIN_SECRET || "";
13
13
  if (!secret || secret.length < 32) {
14
- throw new Error("Missing BETTER_AUTH_SECRET with at least 32 characters");
14
+ throw new Error("Missing BETTER_AUTH_ADMIN_SECRET with at least 32 characters");
15
15
  }
16
16
  return secret;
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAA0B,UAAU,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE9C,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGjC,OAAO,EACL,6BAA6B,EAC7B,wBAAwB,EACxB,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAA;AAE7E,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAA;IAEnD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAA;IAC3E,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAaD,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,mBAAmB,CAAA;AA6B1B,MAAM,6BAA6B,GAAG,CAAC,OAAO,CAAU,CAAA;AACxD,MAAM,iCAAiC,GAAG;IACxC,gBAAgB;IAChB,sBAAsB;IACtB,oBAAoB;CACZ,CAAA;AAmCV,SAAS,4BAA4B,CACnC,OAAuD;IAEvD,OAAO,OAAO,EAAE,QAAQ,IAAI,6BAA6B,CAAA;AAC3D,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAuD;IACnF,OAAO,OAAO,EAAE,OAAO,KAAK,KAAK,CAAA;AACnC,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAuC;IACnE,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAA;IAExB,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IACpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QAC9B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;AAC/B,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAwC,EACxC,eAAkC;IAElC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAE9C,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAA;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CACtC,CAAC,OAAO,EAAqB,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CACzF,CAAA;QACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACrF,CAAC;IACH,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/D,OAAO,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAiD;IAC/E,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,CAAA;IAC1B,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IAEvB,OAAO,iCAAiC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;AAClF,CAAC;AAED,SAAS,2BAA2B,CAClC,IAAwC,EACxC,OAAiD,EACjD,QAA2B;IAE3B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO;QACL,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QACf,QAAQ;KACT,CAAA;AACH,CAAC;AAsBD,MAAM,iBAAiB,GAA0B;IAC/C,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,WAAW;IACpB,OAAO,EAAE,WAAW;IACpB,YAAY,EAAE,gBAAgB;IAC9B,MAAM,EAAE,WAAW;CACpB,CAAA;AAED,MAAM,oBAAoB,GAA0B;IAClD,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,mBAAmB;IAC5B,YAAY,EAAE,wBAAwB;CACvC,CAAA;AA+DD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAG9B,UAAyD,EAAE;IAC3D,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,EAAE,CAAA;IAChD,MAAM,OAAO,GACX,OAAO,CAAC,OAAO;QACf,OAAO,CAAC,GAAG,CAAC,eAAe;QAC3B,OAAO,CAAC,GAAG,CAAC,OAAO;QACnB,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC/B,uBAAuB,CAAA;IACzB,MAAM,cAAc,GAAG,oBAAoB,CACzC,OAAO,CAAC,cAAc,IAAI,iBAAiB,EAAE,EAC7C,OAAO,CACR,CAAA;IACD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAA;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAA;IACtC,MAAM,WAAW,GACf,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAA;IAC1F,MAAM,mBAAmB,GAAG,4BAA4B,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;IAC7F,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;IACpF,MAAM,sBAAsB,GAAG,oBAAoB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnF,MAAM,MAAM,GAAG;QACb,GAAG,WAAW;QACd,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;KACG,CAAA;IACnC,MAAM,SAAS,GACb,OAAO,CAAC,SAAS;QACjB,CAAC,OAAO,CAAC,gBAAgB;YACvB,CAAC,CAAE;gBACC,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,EAAE;gBACV,GAAG,EAAE,GAAG;gBACR,OAAO,EAAE,mBAAmB;aACM;YACtC,CAAC,CAAC,SAAS,CAAC,CAAA;IAEhB,MAAM,WAAW,GAAG;QAClB,OAAO,EAAE,QAAQ;QACjB,OAAO;QACP,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM;QACN,QAAQ,EAAE,cAAc,CAAC,EAAE,EAAE;YAC3B,QAAQ,EAAE,IAAI;YACd,MAAM;SACP,CAAC;QACF,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,KAAK;YACtC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,OAAO,EAAE;oBACP,WAAW,EAAE;wBACX,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,OAAO,CAAC,kBAAkB,EAAE,MAAM,IAAI,GAAG;qBAClD;iBACF;aACF,CAAC;QACN,gBAAgB,EAAE;YAChB,OAAO,EAAE,OAAO,CAAC,oBAAoB,KAAK,KAAK;YAC/C,iBAAiB,EAAE,CAAC;YACpB,iBAAiB,EAAE,GAAG;YACtB,wBAAwB,EAAE,IAAI;YAC9B,6BAA6B,EAAE,IAAI;YACnC,uIAAuI;YACvI,iBAAiB,EACf,OAAO,CAAC,iBAAiB;gBACzB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;oBACvB,OAAO,CAAC,IAAI,CACV,4DAA4D,IAAI,CAAC,KAAK,KAAK,GAAG,EAAE,CACjF,CAAA;gBACH,CAAC,CAAC;SACL;QACD,iBAAiB,EAAE;YACjB,YAAY,EAAE,KAAK,EAAE,0BAA0B;YAC/C,2BAA2B,EAAE,IAAI;SAClC;QACD,IAAI,EAAE;YACJ,GAAG,OAAO,CAAC,IAAI;YACf,WAAW,EAAE;gBACX,OAAO,EAAE,IAAI;gBACb,GAAG,OAAO,CAAC,IAAI,EAAE,WAAW;aAC7B;SAC4C;QAC/C,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,EAAE;QAC9C,cAAc;QACd,OAAO,EAAE;YACP,GAAG,CAAC,KAAK,KAAK,OAAO;gBACnB,CAAC,CAAC;oBACE,MAAM,CAAC;wBACL,aAAa,EAAE,MAAM;wBACrB,aAAa,EAAE,CAAC,eAAe,CAAC;wBAChC,WAAW,EAAE,IAAI;wBACjB,aAAa,EAAE;4BACb,gBAAgB,EAAE,IAAI;yBACvB;qBACF,CAAC;iBACH;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK;gBACpC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,QAAQ,CAAC;wBACP,uIAAuI;wBACvI,mBAAmB,EACjB,OAAO,CAAC,mBAAmB;4BAC3B,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;gCAC9B,OAAO,CAAC,IAAI,CAAC,kBAAkB,KAAK,KAAK,GAAG,KAAK,IAAI,GAAG,CAAC,CAAA;4BAC3D,CAAC,CAAC;wBACJ,SAAS,EAAE,CAAC;wBACZ,SAAS,EAAE,GAAG;wBACd,wBAAwB,EAAE,IAAI;wBAC9B,WAAW,EAAE;4BACX,OAAO,EAAE,IAAI;yBACd;qBACF,CAAC;iBACH,CAAC;YACN,GAAG,CAAC,KAAK,KAAK,OAAO;gBACnB,CAAC,CAAC;oBACE,6BAA6B,CAAC;wBAC5B,kBAAkB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,6BAA6B,CAAC,EAAE,EAAE,KAAK,CAAC;wBACvE,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CACrC,0BAA0B,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC;wBACnD,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,wBAAwB,CAAC,EAAE,EAAE,MAAM,CAAC;qBACpE,CAAC;iBACH;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,YAAY;SACsB;QACvC,GAAG,CAAC,KAAK,KAAK,OAAO;YACnB,CAAC,CAAC;gBACE,aAAa,EAAE;oBACb,IAAI,EAAE;wBACJ,MAAM,EAAE;4BACN,mEAAmE;4BACnE,iEAAiE;4BACjE,kEAAkE;4BAClE,qEAAqE;4BACrE,kEAAkE;4BAClE,wBAAwB;4BACxB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAyC,EAAE;gCACrE,MAAM,cAAc,GAAG,2BAA2B,CAChD,IAA8B,EAC9B,OAAuC,EACvC,sBAAsB,CACvB,CAAA;gCAED,IACE,CAAC,kBAAkB;oCACnB,CAAC,wBAAwB,CAAC,cAAc,EAAE,mBAAmB,CAAC,EAC9D,CAAC;oCACD,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;wCAC5B,OAAM;oCACR,CAAC;oCACD,OAAO,EAAE,IAAI,EAAE,cAAyC,EAAE,CAAA;gCAC5D,CAAC;gCAED,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;qCACnB,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAQ,eAAe,EAAE,CAAC;qCAC7C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gCACzB,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;oCAC1B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;gCACrE,CAAC;gCAED,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;oCAC5B,OAAO,EAAE,IAAI,EAAE,cAAyC,EAAE,CAAA;gCAC5D,CAAC;4BACH,CAAC;4BACD,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;gCAC7B,IACE,sBAAsB,CAAC,MAAM,GAAG,CAAC;oCACjC,sBAAsB,CAAC,OAAuC,CAAC,EAC/D,CAAC;oCACD,OAAM;gCACR,CAAC;gCAED,mEAAmE;gCACnE,2DAA2D;gCAC3D,4DAA4D;gCAC5D,MAAM,2BAA2B,CAAC,EAAE,EAAE;oCACpC,MAAM,EAAE,IAAI,CAAC,EAAE;oCACf,IAAI,EAAE,IAAI,CAAC,IAAI;oCACf,KAAK,EAAE,IAAI,CAAC,KAAK;oCACjB,YAAY,EAAE,MAAM,eAAe,CAAC,EAAE,CAAC;iCACxC,CAAC,CAAA;4BACJ,CAAC;yBACF;qBACF;iBACF;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,QAAQ,EAAE;YACR,GAAG,OAAO,CAAC,QAAQ;YACnB,YAAY,EACV,OAAO,CAAC,QAAQ,EAAE,YAAY;gBAC9B,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC;YAC7D,gBAAgB,EACd,OAAO,CAAC,QAAQ,EAAE,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;SAC/E;KACuD,CAAA;IAE1D,OAAO,UAAU,CAAwD,WAAW,CAAC,CAAA;AACvF,CAAC;AAOD,MAAM,UAAU,qBAAqB,CAGnC,UAA8D,EAAE;IAChE,OAAO,gBAAgB,CAAC;QACtB,GAAG,OAAO;QACV,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,iBAAiB;QAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,aAAa;KAC5C,CAAC,CAAA;AACJ,CAAC;AAuBD,kFAAkF;AAClF,MAAM,UAAU,wBAAwB,CAGtC,UAAiE,EAAE;IACnE,OAAO,gBAAgB,CAAC;QACtB,GAAG,OAAO;QACV,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,oBAAoB;QACjC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,gBAAgB;QAC9C,2BAA2B,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;QAC/C,gBAAgB,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,IAAI,IAAI;QACpD,oBAAoB,EAAE,OAAO,CAAC,OAAO,EAAE,aAAa,IAAI,IAAI;QAC5D,eAAe,EAAE,OAAO,CAAC,OAAO,EAAE,eAAe;KAClD,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { apiKey } from \"@better-auth/api-key\"\nimport { getDb } from \"@voyant-travel/db\"\nimport {\n apikeyTable,\n authAccount,\n authSession,\n authUser,\n authVerification,\n customerAuthAccount,\n customerAuthSession,\n customerAuthUser,\n customerAuthVerification,\n} from \"@voyant-travel/db/schema/iam\"\nimport { type BetterAuthOptions, betterAuth } from \"better-auth\"\nimport { drizzleAdapter } from \"better-auth/adapters/drizzle\"\nimport { emailOTP } from \"better-auth/plugins\"\nimport type { BetterAuthPlugin } from \"better-auth/types\"\nimport { sql } from \"drizzle-orm\"\nimport type { AnyPgTable } from \"drizzle-orm/pg-core\"\n\nimport {\n createLocalMemberAccessPlugin,\n isLocalMemberDeactivated,\n isLocalMemberEmailDeactivated,\n isLocalMemberSessionActive,\n} from \"./local-member-access.js\"\nimport { expandTrustedOrigins, getTrustedOrigins } from \"./trusted-origins.js\"\nimport { isFirstAuthUser, provisionCurrentUserProfile } from \"./workspace.js\"\n\nexport function getAuthSecret(): string {\n const secret = process.env.BETTER_AUTH_SECRET || \"\"\n\n if (!secret || secret.length < 32) {\n throw new Error(\"Missing BETTER_AUTH_SECRET with at least 32 characters\")\n }\n\n return secret\n}\n\nexport type {\n AccountProfileUpdateHandler,\n ApiTokenRotationStore,\n BetterAuthApiTokenManagement,\n HandleAccountProfileRequestOptions,\n HandleApiTokenManagementRequestOptions,\n HandleOrganizationMembersRequestOptions,\n OrganizationMemberRecord,\n OrganizationMembersListHandler,\n OrganizationMembersListInput,\n} from \"./auth-facades.js\"\nexport {\n handleAccountProfileRequest,\n handleApiTokenManagementRequest,\n handleOrganizationMembersRequest,\n} from \"./auth-facades.js\"\n\ntype DefinedBetterAuthUserOptions<UserOptions extends BetterAuthOptions[\"user\"]> =\n UserOptions extends undefined ? Record<PropertyKey, never> : NonNullable<UserOptions>\n\ntype ResolvedBetterAuthChangeEmail<UserOptions extends BetterAuthOptions[\"user\"]> =\n DefinedBetterAuthUserOptions<UserOptions> extends { changeEmail?: infer ChangeEmail }\n ? ChangeEmail extends { enabled: infer Enabled }\n ? Omit<ChangeEmail, \"enabled\"> & { enabled: Enabled }\n : NonNullable<ChangeEmail> & { enabled: true }\n : { enabled: true }\n\ntype ResolvedBetterAuthUserOptions<UserOptions extends BetterAuthOptions[\"user\"]> = Omit<\n DefinedBetterAuthUserOptions<UserOptions>,\n \"changeEmail\"\n> & {\n changeEmail: ResolvedBetterAuthChangeEmail<UserOptions>\n}\n\ntype VoyantBetterAuthPlugins = [\n ReturnType<typeof apiKey>,\n ReturnType<typeof emailOTP>,\n ReturnType<typeof createLocalMemberAccessPlugin>,\n]\n\ntype ResolvedBetterAuthPlugins<_Plugins extends BetterAuthPlugin[] | undefined> =\n | VoyantBetterAuthPlugins\n | BetterAuthPlugin[]\n\nconst DEFAULT_SIGNUP_BLOCK_SURFACES = [\"admin\"] as const\nconst CUSTOMER_SIGNUP_ENDPOINT_SUFFIXES = [\n \"/sign-up/email\",\n \"/phone-number/verify\",\n \"/sign-in/email-otp\",\n] as const\n\nexport interface DisableSignupWhenUsersExistOptions {\n /**\n * Set to false when the consuming app owns all signup admission checks.\n *\n * Defaults to true.\n */\n enabled?: boolean\n /**\n * User surfaces that should keep the single-tenant signup guard. New users\n * with only other explicit surfaces can still be created by customer-facing\n * auth plugins such as phone OTP.\n *\n * Defaults to [\"admin\"]. Users without an explicit surfaces array are\n * treated as admin users for backward compatibility.\n */\n surfaces?: readonly string[]\n}\n\ntype BetterAuthCreateBeforeResult =\n | boolean\n | undefined\n | {\n data: Record<string, unknown>\n }\n\ntype SignupBlockUserPayload = {\n surfaces?: unknown\n}\n\ntype BetterAuthHookContext = {\n path?: string\n}\n\nfunction normalizeSignupBlockSurfaces(\n options: DisableSignupWhenUsersExistOptions | undefined,\n): readonly string[] {\n return options?.surfaces ?? DEFAULT_SIGNUP_BLOCK_SURFACES\n}\n\nfunction isSignupBlockEnabled(options: DisableSignupWhenUsersExistOptions | undefined): boolean {\n return options?.enabled !== false\n}\n\nfunction normalizeSurfaceList(surfaces: readonly string[] | undefined): readonly string[] {\n if (!surfaces) return []\n\n const normalized = new Set<string>()\n for (const surface of surfaces) {\n const trimmed = surface.trim()\n if (trimmed.length > 0) {\n normalized.add(trimmed)\n }\n }\n return Array.from(normalized)\n}\n\nfunction signupBlockAppliesToUser(\n user: SignupBlockUserPayload | undefined,\n blockedSurfaces: readonly string[],\n): boolean {\n if (blockedSurfaces.length === 0) return false\n\n const surfaces = user?.surfaces\n if (Array.isArray(surfaces)) {\n const explicitSurfaces = surfaces.filter(\n (surface): surface is string => typeof surface === \"string\" && surface.trim().length > 0,\n )\n if (explicitSurfaces.length > 0) {\n return explicitSurfaces.some((surface) => blockedSurfaces.includes(surface.trim()))\n }\n }\n\n if (typeof surfaces === \"string\" && surfaces.trim().length > 0) {\n return blockedSurfaces.includes(surfaces.trim())\n }\n\n return blockedSurfaces.includes(\"admin\")\n}\n\nfunction isCustomerSignupCreate(context: BetterAuthHookContext | null | undefined): boolean {\n const path = context?.path\n if (!path) return false\n\n return CUSTOMER_SIGNUP_ENDPOINT_SUFFIXES.some((suffix) => path.endsWith(suffix))\n}\n\nfunction stampCustomerSignupSurfaces(\n user: SignupBlockUserPayload | undefined,\n context: BetterAuthHookContext | null | undefined,\n surfaces: readonly string[],\n): SignupBlockUserPayload | undefined {\n if (surfaces.length === 0 || !isCustomerSignupCreate(context)) {\n return user\n }\n\n return {\n ...(user ?? {}),\n surfaces,\n }\n}\n\ntype ResolvedCreateBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined,\n> = Omit<BetterAuthOptions, \"plugins\" | \"user\"> & {\n plugins: ResolvedBetterAuthPlugins<Plugins>\n user: ResolvedBetterAuthUserOptions<UserOptions>\n}\n\nexport type BetterAuthDrizzleSchema = Record<string, AnyPgTable>\n\nexport type VoyantAuthRealm = \"admin\" | \"customer\"\n\nexport interface BetterAuthRealmTables {\n user: AnyPgTable\n session: AnyPgTable\n account: AnyPgTable\n verification: AnyPgTable\n apikey?: AnyPgTable\n}\n\nconst ADMIN_AUTH_TABLES: BetterAuthRealmTables = {\n user: authUser,\n session: authSession,\n account: authAccount,\n verification: authVerification,\n apikey: apikeyTable,\n}\n\nconst CUSTOMER_AUTH_TABLES: BetterAuthRealmTables = {\n user: customerAuthUser,\n session: customerAuthSession,\n account: customerAuthAccount,\n verification: customerAuthVerification,\n}\n\nexport interface CreateBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined = BetterAuthPlugin[] | undefined,\n> {\n db?: ReturnType<typeof getDb>\n secret?: string\n baseURL?: string\n basePath?: string\n trustedOrigins?: string[]\n /** Security realm. Existing callers default to the isolated admin realm. */\n realm?: VoyantAuthRealm\n /** Override only when an adapter owns a compatible Better Auth schema. */\n realmTables?: BetterAuthRealmTables\n /**\n * Additional Drizzle tables for Better Auth plugins. The consuming app owns\n * matching migrations for every table passed here.\n */\n extraSchema?: BetterAuthDrizzleSchema\n plugins?: Plugins\n user?: UserOptions\n /** Resolved credentials; the auth package never persists provider secrets. */\n socialProviders?: BetterAuthOptions[\"socialProviders\"]\n emailCodeEnabled?: boolean\n emailPasswordEnabled?: boolean\n /**\n * Surfaces stamped on Better Auth customer self-signups before the bundled\n * single-tenant signup guard evaluates the new user. Applies to Better\n * Auth OTP signup endpoints that create a user as part of verification.\n *\n * Leave undefined to preserve Better Auth's raw user payload.\n */\n customerSignupSurfaces?: readonly string[]\n disableSignupWhenUsersExist?: DisableSignupWhenUsersExistOptions\n /** Called when a user requests a password reset. If not provided, logs to console. */\n sendResetPassword?: (data: {\n user: { email: string; name: string }\n url: string\n token: string\n }) => Promise<void>\n /** Called to send a verification OTP. If not provided, logs to console. */\n sendVerificationOTP?: (data: { email: string; otp: string; type: string }) => Promise<void>\n /**\n * Better Auth session cookie cache: session data rides in a short-lived\n * signed cookie. Enabled by default with a 5-minute TTL. Voyant still\n * validates local membership and session existence against Postgres so a\n * deleted session cannot be revived from the cookie cache. Pass `false` to\n * disable payload caching, or tune `maxAge` (seconds).\n */\n sessionCookieCache?: false | { maxAge?: number }\n /** Better Auth secondary storage, typically Redis/KV, used for distributed rate limits. */\n secondaryStorage?: BetterAuthOptions[\"secondaryStorage\"]\n /** Better Auth rate-limit config. Defaults to secondary storage when present. */\n rateLimit?: BetterAuthOptions[\"rateLimit\"]\n /**\n * Additional Better Auth advanced options. Voyant supplies secure cookies\n * by default except in explicit local development. Set\n * `advanced.useSecureCookies` to override that default.\n */\n advanced?: BetterAuthOptions[\"advanced\"]\n}\n\n/**\n * Framework-agnostic Better Auth factory.\n *\n * Accepts optional overrides for db, secret, baseURL, trustedOrigins.\n * Does NOT depend on Next.js — safe to use in Hono workers, TanStack Start, etc.\n */\nexport function createBetterAuth<\n const UserOptions extends BetterAuthOptions[\"user\"] = undefined,\n const Plugins extends BetterAuthPlugin[] | undefined = undefined,\n>(options: CreateBetterAuthOptions<UserOptions, Plugins> = {}) {\n const db = options.db ?? getDb(\"edge\")\n const secret = options.secret ?? getAuthSecret()\n const baseURL =\n options.baseURL ??\n process.env.BETTER_AUTH_URL ??\n process.env.APP_URL ??\n process.env.NEXT_PUBLIC_APP_URL ??\n \"http://localhost:3000\"\n const trustedOrigins = expandTrustedOrigins(\n options.trustedOrigins ?? getTrustedOrigins(),\n baseURL,\n )\n const extraPlugins = options.plugins ?? []\n const realm = options.realm ?? \"admin\"\n const realmTables =\n options.realmTables ?? (realm === \"customer\" ? CUSTOMER_AUTH_TABLES : ADMIN_AUTH_TABLES)\n const signupBlockSurfaces = normalizeSignupBlockSurfaces(options.disableSignupWhenUsersExist)\n const signupBlockEnabled = isSignupBlockEnabled(options.disableSignupWhenUsersExist)\n const customerSignupSurfaces = normalizeSurfaceList(options.customerSignupSurfaces)\n const schema = {\n ...realmTables,\n ...(options.extraSchema ?? {}),\n } satisfies BetterAuthDrizzleSchema\n const rateLimit =\n options.rateLimit ??\n (options.secondaryStorage\n ? ({\n enabled: true,\n window: 60,\n max: 100,\n storage: \"secondary-storage\",\n } as BetterAuthOptions[\"rateLimit\"])\n : undefined)\n\n const authOptions = {\n appName: \"Voyant\",\n baseURL,\n ...(options.basePath ? { basePath: options.basePath } : {}),\n secret,\n database: drizzleAdapter(db, {\n provider: \"pg\",\n schema,\n }),\n ...(options.secondaryStorage ? { secondaryStorage: options.secondaryStorage } : {}),\n ...(rateLimit ? { rateLimit } : {}),\n ...(options.sessionCookieCache === false\n ? {}\n : {\n session: {\n cookieCache: {\n enabled: true,\n maxAge: options.sessionCookieCache?.maxAge ?? 300,\n },\n },\n }),\n emailAndPassword: {\n enabled: options.emailPasswordEnabled !== false,\n minPasswordLength: 8,\n maxPasswordLength: 128,\n requireEmailVerification: true,\n revokeSessionsOnPasswordReset: true,\n // eslint-disable-next-line @typescript-eslint/require-await -- owner: auth; existing suppression is intentional pending typed cleanup.\n sendResetPassword:\n options.sendResetPassword ??\n (async ({ user, url }) => {\n console.warn(\n `[Auth] No email provider configured — password reset for ${user.email}: ${url}`,\n )\n }),\n },\n emailVerification: {\n sendOnSignUp: false, // OTP plugin handles this\n autoSignInAfterVerification: true,\n },\n user: {\n ...options.user,\n changeEmail: {\n enabled: true,\n ...options.user?.changeEmail,\n },\n } as ResolvedBetterAuthUserOptions<UserOptions>,\n socialProviders: options.socialProviders ?? {},\n trustedOrigins,\n plugins: [\n ...(realm === \"admin\"\n ? [\n apiKey({\n defaultPrefix: \"voy_\",\n apiKeyHeaders: [\"authorization\"],\n requireName: true,\n keyExpiration: {\n defaultExpiresIn: null,\n },\n }),\n ]\n : []),\n ...(options.emailCodeEnabled === false\n ? []\n : [\n emailOTP({\n // eslint-disable-next-line @typescript-eslint/require-await -- owner: auth; existing suppression is intentional pending typed cleanup.\n sendVerificationOTP:\n options.sendVerificationOTP ??\n (async ({ email, otp, type }) => {\n console.warn(`[Auth] OTP for ${email}: ${otp} (${type})`)\n }),\n otpLength: 6,\n expiresIn: 600,\n sendVerificationOnSignUp: true,\n changeEmail: {\n enabled: true,\n },\n }),\n ]),\n ...(realm === \"admin\"\n ? [\n createLocalMemberAccessPlugin({\n isEmailDeactivated: (email) => isLocalMemberEmailDeactivated(db, email),\n isSessionActive: (sessionId, userId) =>\n isLocalMemberSessionActive(db, sessionId, userId),\n isUserDeactivated: (userId) => isLocalMemberDeactivated(db, userId),\n }),\n ]\n : []),\n ...extraPlugins,\n ] as ResolvedBetterAuthPlugins<Plugins>,\n ...(realm === \"admin\"\n ? {\n databaseHooks: {\n user: {\n create: {\n // Single-tenant: once a user exists, reject any new-user creation.\n // Covers email sign-up AND social-provider sign-up (Google would\n // otherwise auto-create a user on first OAuth callback). Existing\n // social sign-ins still work because this hook only fires on CREATE.\n // Seed scripts do raw drizzle inserts, so they bypass this hook —\n // which is intentional.\n before: async (user, context): Promise<BetterAuthCreateBeforeResult> => {\n const normalizedUser = stampCustomerSignupSurfaces(\n user as SignupBlockUserPayload,\n context as BetterAuthHookContext | null,\n customerSignupSurfaces,\n )\n\n if (\n !signupBlockEnabled ||\n !signupBlockAppliesToUser(normalizedUser, signupBlockSurfaces)\n ) {\n if (normalizedUser === user) {\n return\n }\n return { data: normalizedUser as Record<string, unknown> }\n }\n\n const [row] = await db\n .select({ count: sql<number>`count(*)::int` })\n .from(realmTables.user)\n if ((row?.count ?? 0) > 0) {\n throw new Error(\"Sign-up is disabled. Ask an admin to invite you.\")\n }\n\n if (normalizedUser !== user) {\n return { data: normalizedUser as Record<string, unknown> }\n }\n },\n after: async (user, context) => {\n if (\n customerSignupSurfaces.length > 0 &&\n isCustomerSignupCreate(context as BetterAuthHookContext | null)\n ) {\n return\n }\n\n // Single-tenant bootstrap: the very first user to register becomes\n // the super-admin. Runs atomically after the `user` row is\n // inserted, so a simple COUNT(*) = 1 check identifies them.\n await provisionCurrentUserProfile(db, {\n userId: user.id,\n name: user.name,\n image: user.image,\n isSuperAdmin: await isFirstAuthUser(db),\n })\n },\n },\n },\n },\n }\n : {}),\n advanced: {\n ...options.advanced,\n cookiePrefix:\n options.advanced?.cookiePrefix ??\n (realm === \"customer\" ? \"voyant-customer\" : \"voyant-admin\"),\n useSecureCookies:\n options.advanced?.useSecureCookies ?? process.env.NODE_ENV !== \"development\",\n },\n } as ResolvedCreateBetterAuthOptions<UserOptions, Plugins>\n\n return betterAuth<ResolvedCreateBetterAuthOptions<UserOptions, Plugins>>(authOptions)\n}\n\nexport type CreateAdminBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined = BetterAuthPlugin[] | undefined,\n> = Omit<CreateBetterAuthOptions<UserOptions, Plugins>, \"realm\" | \"realmTables\">\n\nexport function createAdminBetterAuth<\n const UserOptions extends BetterAuthOptions[\"user\"] = undefined,\n const Plugins extends BetterAuthPlugin[] | undefined = undefined,\n>(options: CreateAdminBetterAuthOptions<UserOptions, Plugins> = {}) {\n return createBetterAuth({\n ...options,\n realm: \"admin\",\n realmTables: ADMIN_AUTH_TABLES,\n basePath: options.basePath ?? \"/auth/admin\",\n })\n}\n\nexport interface CustomerAuthMethods {\n emailCode?: boolean\n emailPassword?: boolean\n /** Better Auth provider configs such as google, facebook, and apple. */\n socialProviders?: BetterAuthOptions[\"socialProviders\"]\n}\n\nexport type CreateCustomerBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined = BetterAuthPlugin[] | undefined,\n> = Omit<\n CreateBetterAuthOptions<UserOptions, Plugins>,\n | \"realm\"\n | \"realmTables\"\n | \"customerSignupSurfaces\"\n | \"disableSignupWhenUsersExist\"\n | \"socialProviders\"\n | \"emailCodeEnabled\"\n | \"emailPasswordEnabled\"\n> & { methods?: CustomerAuthMethods }\n\n/** Storefront realm factory with isolated tables, cookies, secret, and routes. */\nexport function createCustomerBetterAuth<\n const UserOptions extends BetterAuthOptions[\"user\"] = undefined,\n const Plugins extends BetterAuthPlugin[] | undefined = undefined,\n>(options: CreateCustomerBetterAuthOptions<UserOptions, Plugins> = {}) {\n return createBetterAuth({\n ...options,\n realm: \"customer\",\n realmTables: CUSTOMER_AUTH_TABLES,\n basePath: options.basePath ?? \"/auth/customer\",\n disableSignupWhenUsersExist: { enabled: false },\n emailCodeEnabled: options.methods?.emailCode ?? true,\n emailPasswordEnabled: options.methods?.emailPassword ?? true,\n socialProviders: options.methods?.socialProviders,\n })\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { apiKey } from \"@better-auth/api-key\"\nimport { getDb } from \"@voyant-travel/db\"\nimport {\n apikeyTable,\n authAccount,\n authSession,\n authUser,\n authVerification,\n customerAuthAccount,\n customerAuthSession,\n customerAuthUser,\n customerAuthVerification,\n} from \"@voyant-travel/db/schema/iam\"\nimport { type BetterAuthOptions, betterAuth } from \"better-auth\"\nimport { drizzleAdapter } from \"better-auth/adapters/drizzle\"\nimport { emailOTP } from \"better-auth/plugins\"\nimport type { BetterAuthPlugin } from \"better-auth/types\"\nimport { sql } from \"drizzle-orm\"\nimport type { AnyPgTable } from \"drizzle-orm/pg-core\"\n\nimport {\n createLocalMemberAccessPlugin,\n isLocalMemberDeactivated,\n isLocalMemberEmailDeactivated,\n isLocalMemberSessionActive,\n} from \"./local-member-access.js\"\nimport { expandTrustedOrigins, getTrustedOrigins } from \"./trusted-origins.js\"\nimport { isFirstAuthUser, provisionCurrentUserProfile } from \"./workspace.js\"\n\nexport function getAuthSecret(): string {\n const secret = process.env.BETTER_AUTH_ADMIN_SECRET || \"\"\n\n if (!secret || secret.length < 32) {\n throw new Error(\"Missing BETTER_AUTH_ADMIN_SECRET with at least 32 characters\")\n }\n\n return secret\n}\n\nexport type {\n AccountProfileUpdateHandler,\n ApiTokenRotationStore,\n BetterAuthApiTokenManagement,\n HandleAccountProfileRequestOptions,\n HandleApiTokenManagementRequestOptions,\n HandleOrganizationMembersRequestOptions,\n OrganizationMemberRecord,\n OrganizationMembersListHandler,\n OrganizationMembersListInput,\n} from \"./auth-facades.js\"\nexport {\n handleAccountProfileRequest,\n handleApiTokenManagementRequest,\n handleOrganizationMembersRequest,\n} from \"./auth-facades.js\"\n\ntype DefinedBetterAuthUserOptions<UserOptions extends BetterAuthOptions[\"user\"]> =\n UserOptions extends undefined ? Record<PropertyKey, never> : NonNullable<UserOptions>\n\ntype ResolvedBetterAuthChangeEmail<UserOptions extends BetterAuthOptions[\"user\"]> =\n DefinedBetterAuthUserOptions<UserOptions> extends { changeEmail?: infer ChangeEmail }\n ? ChangeEmail extends { enabled: infer Enabled }\n ? Omit<ChangeEmail, \"enabled\"> & { enabled: Enabled }\n : NonNullable<ChangeEmail> & { enabled: true }\n : { enabled: true }\n\ntype ResolvedBetterAuthUserOptions<UserOptions extends BetterAuthOptions[\"user\"]> = Omit<\n DefinedBetterAuthUserOptions<UserOptions>,\n \"changeEmail\"\n> & {\n changeEmail: ResolvedBetterAuthChangeEmail<UserOptions>\n}\n\ntype VoyantBetterAuthPlugins = [\n ReturnType<typeof apiKey>,\n ReturnType<typeof emailOTP>,\n ReturnType<typeof createLocalMemberAccessPlugin>,\n]\n\ntype ResolvedBetterAuthPlugins<_Plugins extends BetterAuthPlugin[] | undefined> =\n | VoyantBetterAuthPlugins\n | BetterAuthPlugin[]\n\nconst DEFAULT_SIGNUP_BLOCK_SURFACES = [\"admin\"] as const\nconst CUSTOMER_SIGNUP_ENDPOINT_SUFFIXES = [\n \"/sign-up/email\",\n \"/phone-number/verify\",\n \"/sign-in/email-otp\",\n] as const\n\nexport interface DisableSignupWhenUsersExistOptions {\n /**\n * Set to false when the consuming app owns all signup admission checks.\n *\n * Defaults to true.\n */\n enabled?: boolean\n /**\n * User surfaces that should keep the single-tenant signup guard. New users\n * with only other explicit surfaces can still be created by customer-facing\n * auth plugins such as phone OTP.\n *\n * Defaults to [\"admin\"]. Users without an explicit surfaces array are\n * treated as admin users for backward compatibility.\n */\n surfaces?: readonly string[]\n}\n\ntype BetterAuthCreateBeforeResult =\n | boolean\n | undefined\n | {\n data: Record<string, unknown>\n }\n\ntype SignupBlockUserPayload = {\n surfaces?: unknown\n}\n\ntype BetterAuthHookContext = {\n path?: string\n}\n\nfunction normalizeSignupBlockSurfaces(\n options: DisableSignupWhenUsersExistOptions | undefined,\n): readonly string[] {\n return options?.surfaces ?? DEFAULT_SIGNUP_BLOCK_SURFACES\n}\n\nfunction isSignupBlockEnabled(options: DisableSignupWhenUsersExistOptions | undefined): boolean {\n return options?.enabled !== false\n}\n\nfunction normalizeSurfaceList(surfaces: readonly string[] | undefined): readonly string[] {\n if (!surfaces) return []\n\n const normalized = new Set<string>()\n for (const surface of surfaces) {\n const trimmed = surface.trim()\n if (trimmed.length > 0) {\n normalized.add(trimmed)\n }\n }\n return Array.from(normalized)\n}\n\nfunction signupBlockAppliesToUser(\n user: SignupBlockUserPayload | undefined,\n blockedSurfaces: readonly string[],\n): boolean {\n if (blockedSurfaces.length === 0) return false\n\n const surfaces = user?.surfaces\n if (Array.isArray(surfaces)) {\n const explicitSurfaces = surfaces.filter(\n (surface): surface is string => typeof surface === \"string\" && surface.trim().length > 0,\n )\n if (explicitSurfaces.length > 0) {\n return explicitSurfaces.some((surface) => blockedSurfaces.includes(surface.trim()))\n }\n }\n\n if (typeof surfaces === \"string\" && surfaces.trim().length > 0) {\n return blockedSurfaces.includes(surfaces.trim())\n }\n\n return blockedSurfaces.includes(\"admin\")\n}\n\nfunction isCustomerSignupCreate(context: BetterAuthHookContext | null | undefined): boolean {\n const path = context?.path\n if (!path) return false\n\n return CUSTOMER_SIGNUP_ENDPOINT_SUFFIXES.some((suffix) => path.endsWith(suffix))\n}\n\nfunction stampCustomerSignupSurfaces(\n user: SignupBlockUserPayload | undefined,\n context: BetterAuthHookContext | null | undefined,\n surfaces: readonly string[],\n): SignupBlockUserPayload | undefined {\n if (surfaces.length === 0 || !isCustomerSignupCreate(context)) {\n return user\n }\n\n return {\n ...(user ?? {}),\n surfaces,\n }\n}\n\ntype ResolvedCreateBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined,\n> = Omit<BetterAuthOptions, \"plugins\" | \"user\"> & {\n plugins: ResolvedBetterAuthPlugins<Plugins>\n user: ResolvedBetterAuthUserOptions<UserOptions>\n}\n\nexport type BetterAuthDrizzleSchema = Record<string, AnyPgTable>\n\nexport type VoyantAuthRealm = \"admin\" | \"customer\"\n\nexport interface BetterAuthRealmTables {\n user: AnyPgTable\n session: AnyPgTable\n account: AnyPgTable\n verification: AnyPgTable\n apikey?: AnyPgTable\n}\n\nconst ADMIN_AUTH_TABLES: BetterAuthRealmTables = {\n user: authUser,\n session: authSession,\n account: authAccount,\n verification: authVerification,\n apikey: apikeyTable,\n}\n\nconst CUSTOMER_AUTH_TABLES: BetterAuthRealmTables = {\n user: customerAuthUser,\n session: customerAuthSession,\n account: customerAuthAccount,\n verification: customerAuthVerification,\n}\n\nexport interface CreateBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined = BetterAuthPlugin[] | undefined,\n> {\n db?: ReturnType<typeof getDb>\n secret?: string\n baseURL?: string\n basePath?: string\n trustedOrigins?: string[]\n /** Security realm. Existing callers default to the isolated admin realm. */\n realm?: VoyantAuthRealm\n /** Override only when an adapter owns a compatible Better Auth schema. */\n realmTables?: BetterAuthRealmTables\n /**\n * Additional Drizzle tables for Better Auth plugins. The consuming app owns\n * matching migrations for every table passed here.\n */\n extraSchema?: BetterAuthDrizzleSchema\n plugins?: Plugins\n user?: UserOptions\n /** Resolved credentials; the auth package never persists provider secrets. */\n socialProviders?: BetterAuthOptions[\"socialProviders\"]\n emailCodeEnabled?: boolean\n emailPasswordEnabled?: boolean\n /**\n * Surfaces stamped on Better Auth customer self-signups before the bundled\n * single-tenant signup guard evaluates the new user. Applies to Better\n * Auth OTP signup endpoints that create a user as part of verification.\n *\n * Leave undefined to preserve Better Auth's raw user payload.\n */\n customerSignupSurfaces?: readonly string[]\n disableSignupWhenUsersExist?: DisableSignupWhenUsersExistOptions\n /** Called when a user requests a password reset. If not provided, logs to console. */\n sendResetPassword?: (data: {\n user: { email: string; name: string }\n url: string\n token: string\n }) => Promise<void>\n /** Called to send a verification OTP. If not provided, logs to console. */\n sendVerificationOTP?: (data: { email: string; otp: string; type: string }) => Promise<void>\n /**\n * Better Auth session cookie cache: session data rides in a short-lived\n * signed cookie. Enabled by default with a 5-minute TTL. Voyant still\n * validates local membership and session existence against Postgres so a\n * deleted session cannot be revived from the cookie cache. Pass `false` to\n * disable payload caching, or tune `maxAge` (seconds).\n */\n sessionCookieCache?: false | { maxAge?: number }\n /** Better Auth secondary storage, typically Redis/KV, used for distributed rate limits. */\n secondaryStorage?: BetterAuthOptions[\"secondaryStorage\"]\n /** Better Auth rate-limit config. Defaults to secondary storage when present. */\n rateLimit?: BetterAuthOptions[\"rateLimit\"]\n /**\n * Additional Better Auth advanced options. Voyant supplies secure cookies\n * by default except in explicit local development. Set\n * `advanced.useSecureCookies` to override that default.\n */\n advanced?: BetterAuthOptions[\"advanced\"]\n}\n\n/**\n * Framework-agnostic Better Auth factory.\n *\n * Accepts optional overrides for db, secret, baseURL, trustedOrigins.\n * Does NOT depend on Next.js — safe to use in Hono workers, TanStack Start, etc.\n */\nexport function createBetterAuth<\n const UserOptions extends BetterAuthOptions[\"user\"] = undefined,\n const Plugins extends BetterAuthPlugin[] | undefined = undefined,\n>(options: CreateBetterAuthOptions<UserOptions, Plugins> = {}) {\n const db = options.db ?? getDb(\"edge\")\n const secret = options.secret ?? getAuthSecret()\n const baseURL =\n options.baseURL ??\n process.env.BETTER_AUTH_URL ??\n process.env.APP_URL ??\n process.env.NEXT_PUBLIC_APP_URL ??\n \"http://localhost:3000\"\n const trustedOrigins = expandTrustedOrigins(\n options.trustedOrigins ?? getTrustedOrigins(),\n baseURL,\n )\n const extraPlugins = options.plugins ?? []\n const realm = options.realm ?? \"admin\"\n const realmTables =\n options.realmTables ?? (realm === \"customer\" ? CUSTOMER_AUTH_TABLES : ADMIN_AUTH_TABLES)\n const signupBlockSurfaces = normalizeSignupBlockSurfaces(options.disableSignupWhenUsersExist)\n const signupBlockEnabled = isSignupBlockEnabled(options.disableSignupWhenUsersExist)\n const customerSignupSurfaces = normalizeSurfaceList(options.customerSignupSurfaces)\n const schema = {\n ...realmTables,\n ...(options.extraSchema ?? {}),\n } satisfies BetterAuthDrizzleSchema\n const rateLimit =\n options.rateLimit ??\n (options.secondaryStorage\n ? ({\n enabled: true,\n window: 60,\n max: 100,\n storage: \"secondary-storage\",\n } as BetterAuthOptions[\"rateLimit\"])\n : undefined)\n\n const authOptions = {\n appName: \"Voyant\",\n baseURL,\n ...(options.basePath ? { basePath: options.basePath } : {}),\n secret,\n database: drizzleAdapter(db, {\n provider: \"pg\",\n schema,\n }),\n ...(options.secondaryStorage ? { secondaryStorage: options.secondaryStorage } : {}),\n ...(rateLimit ? { rateLimit } : {}),\n ...(options.sessionCookieCache === false\n ? {}\n : {\n session: {\n cookieCache: {\n enabled: true,\n maxAge: options.sessionCookieCache?.maxAge ?? 300,\n },\n },\n }),\n emailAndPassword: {\n enabled: options.emailPasswordEnabled !== false,\n minPasswordLength: 8,\n maxPasswordLength: 128,\n requireEmailVerification: true,\n revokeSessionsOnPasswordReset: true,\n // eslint-disable-next-line @typescript-eslint/require-await -- owner: auth; existing suppression is intentional pending typed cleanup.\n sendResetPassword:\n options.sendResetPassword ??\n (async ({ user, url }) => {\n console.warn(\n `[Auth] No email provider configured — password reset for ${user.email}: ${url}`,\n )\n }),\n },\n emailVerification: {\n sendOnSignUp: false, // OTP plugin handles this\n autoSignInAfterVerification: true,\n },\n user: {\n ...options.user,\n changeEmail: {\n enabled: true,\n ...options.user?.changeEmail,\n },\n } as ResolvedBetterAuthUserOptions<UserOptions>,\n socialProviders: options.socialProviders ?? {},\n trustedOrigins,\n plugins: [\n ...(realm === \"admin\"\n ? [\n apiKey({\n defaultPrefix: \"voy_\",\n apiKeyHeaders: [\"authorization\"],\n requireName: true,\n keyExpiration: {\n defaultExpiresIn: null,\n },\n }),\n ]\n : []),\n ...(options.emailCodeEnabled === false\n ? []\n : [\n emailOTP({\n // eslint-disable-next-line @typescript-eslint/require-await -- owner: auth; existing suppression is intentional pending typed cleanup.\n sendVerificationOTP:\n options.sendVerificationOTP ??\n (async ({ email, otp, type }) => {\n console.warn(`[Auth] OTP for ${email}: ${otp} (${type})`)\n }),\n otpLength: 6,\n expiresIn: 600,\n sendVerificationOnSignUp: true,\n changeEmail: {\n enabled: true,\n },\n }),\n ]),\n ...(realm === \"admin\"\n ? [\n createLocalMemberAccessPlugin({\n isEmailDeactivated: (email) => isLocalMemberEmailDeactivated(db, email),\n isSessionActive: (sessionId, userId) =>\n isLocalMemberSessionActive(db, sessionId, userId),\n isUserDeactivated: (userId) => isLocalMemberDeactivated(db, userId),\n }),\n ]\n : []),\n ...extraPlugins,\n ] as ResolvedBetterAuthPlugins<Plugins>,\n ...(realm === \"admin\"\n ? {\n databaseHooks: {\n user: {\n create: {\n // Single-tenant: once a user exists, reject any new-user creation.\n // Covers email sign-up AND social-provider sign-up (Google would\n // otherwise auto-create a user on first OAuth callback). Existing\n // social sign-ins still work because this hook only fires on CREATE.\n // Seed scripts do raw drizzle inserts, so they bypass this hook —\n // which is intentional.\n before: async (user, context): Promise<BetterAuthCreateBeforeResult> => {\n const normalizedUser = stampCustomerSignupSurfaces(\n user as SignupBlockUserPayload,\n context as BetterAuthHookContext | null,\n customerSignupSurfaces,\n )\n\n if (\n !signupBlockEnabled ||\n !signupBlockAppliesToUser(normalizedUser, signupBlockSurfaces)\n ) {\n if (normalizedUser === user) {\n return\n }\n return { data: normalizedUser as Record<string, unknown> }\n }\n\n const [row] = await db\n .select({ count: sql<number>`count(*)::int` })\n .from(realmTables.user)\n if ((row?.count ?? 0) > 0) {\n throw new Error(\"Sign-up is disabled. Ask an admin to invite you.\")\n }\n\n if (normalizedUser !== user) {\n return { data: normalizedUser as Record<string, unknown> }\n }\n },\n after: async (user, context) => {\n if (\n customerSignupSurfaces.length > 0 &&\n isCustomerSignupCreate(context as BetterAuthHookContext | null)\n ) {\n return\n }\n\n // Single-tenant bootstrap: the very first user to register becomes\n // the super-admin. Runs atomically after the `user` row is\n // inserted, so a simple COUNT(*) = 1 check identifies them.\n await provisionCurrentUserProfile(db, {\n userId: user.id,\n name: user.name,\n image: user.image,\n isSuperAdmin: await isFirstAuthUser(db),\n })\n },\n },\n },\n },\n }\n : {}),\n advanced: {\n ...options.advanced,\n cookiePrefix:\n options.advanced?.cookiePrefix ??\n (realm === \"customer\" ? \"voyant-customer\" : \"voyant-admin\"),\n useSecureCookies:\n options.advanced?.useSecureCookies ?? process.env.NODE_ENV !== \"development\",\n },\n } as ResolvedCreateBetterAuthOptions<UserOptions, Plugins>\n\n return betterAuth<ResolvedCreateBetterAuthOptions<UserOptions, Plugins>>(authOptions)\n}\n\nexport type CreateAdminBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined = BetterAuthPlugin[] | undefined,\n> = Omit<CreateBetterAuthOptions<UserOptions, Plugins>, \"realm\" | \"realmTables\">\n\nexport function createAdminBetterAuth<\n const UserOptions extends BetterAuthOptions[\"user\"] = undefined,\n const Plugins extends BetterAuthPlugin[] | undefined = undefined,\n>(options: CreateAdminBetterAuthOptions<UserOptions, Plugins> = {}) {\n return createBetterAuth({\n ...options,\n realm: \"admin\",\n realmTables: ADMIN_AUTH_TABLES,\n basePath: options.basePath ?? \"/auth/admin\",\n })\n}\n\nexport interface CustomerAuthMethods {\n emailCode?: boolean\n emailPassword?: boolean\n /** Better Auth provider configs such as google, facebook, and apple. */\n socialProviders?: BetterAuthOptions[\"socialProviders\"]\n}\n\nexport type CreateCustomerBetterAuthOptions<\n UserOptions extends BetterAuthOptions[\"user\"] = BetterAuthOptions[\"user\"],\n Plugins extends BetterAuthPlugin[] | undefined = BetterAuthPlugin[] | undefined,\n> = Omit<\n CreateBetterAuthOptions<UserOptions, Plugins>,\n | \"realm\"\n | \"realmTables\"\n | \"customerSignupSurfaces\"\n | \"disableSignupWhenUsersExist\"\n | \"socialProviders\"\n | \"emailCodeEnabled\"\n | \"emailPasswordEnabled\"\n> & { methods?: CustomerAuthMethods }\n\n/** Storefront realm factory with isolated tables, cookies, secret, and routes. */\nexport function createCustomerBetterAuth<\n const UserOptions extends BetterAuthOptions[\"user\"] = undefined,\n const Plugins extends BetterAuthPlugin[] | undefined = undefined,\n>(options: CreateCustomerBetterAuthOptions<UserOptions, Plugins> = {}) {\n return createBetterAuth({\n ...options,\n realm: \"customer\",\n realmTables: CUSTOMER_AUTH_TABLES,\n basePath: options.basePath ?? \"/auth/customer\",\n disableSignupWhenUsersExist: { enabled: false },\n emailCodeEnabled: options.methods?.emailCode ?? true,\n emailPasswordEnabled: options.methods?.emailPassword ?? true,\n socialProviders: options.methods?.socialProviders,\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/auth",
3
- "version": "0.133.3",
3
+ "version": "0.133.5",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -112,7 +112,7 @@
112
112
  "zod": "^4.4.3",
113
113
  "@voyant-travel/core": "^0.127.0",
114
114
  "@voyant-travel/db": "^0.114.13",
115
- "@voyant-travel/hono": "^0.128.6",
115
+ "@voyant-travel/hono": "^0.129.1",
116
116
  "@voyant-travel/tools": "^0.3.0",
117
117
  "@voyant-travel/types": "^0.109.4",
118
118
  "@voyant-travel/utils": "^0.107.1"