@voyant-travel/auth 0.134.0 → 0.135.0
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/node-runtime.d.ts +13 -1
- package/dist/node-runtime.js +85 -19
- package/dist/node-runtime.js.map +1 -1
- package/package.json +1 -1
package/dist/node-runtime.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ export interface OperatorCurrentUser {
|
|
|
65
65
|
export type OperatorAuthBootstrapStatus = {
|
|
66
66
|
hasUsers: boolean;
|
|
67
67
|
authMode?: OperatorAuthMode;
|
|
68
|
+
/** Active deployment modules used by source-free managed admin composition. */
|
|
69
|
+
modules?: string[];
|
|
68
70
|
};
|
|
69
71
|
type BetterAuthAdvancedOptions = NonNullable<CreateBetterAuthOptions["advanced"]>;
|
|
70
72
|
/** Resolve Better Auth's standard cross-subdomain cookie policy for Node hosts. */
|
|
@@ -85,6 +87,8 @@ export interface OperatorAuthEmailSender {
|
|
|
85
87
|
}
|
|
86
88
|
export interface CreateOperatorAuthNodeRuntimeOptions<Env extends OperatorAuthNodeEnv> {
|
|
87
89
|
accessCatalog: AccessCatalog;
|
|
90
|
+
/** Active deployment modules surfaced by `/auth/bootstrap-status`. */
|
|
91
|
+
activeModules?: readonly string[];
|
|
88
92
|
appName: string;
|
|
89
93
|
authMode: OperatorAuthMode;
|
|
90
94
|
reporter: Reporter;
|
|
@@ -98,9 +102,12 @@ export interface CreateOperatorAuthNodeRuntimeOptions<Env extends OperatorAuthNo
|
|
|
98
102
|
* Storefront/BFF seam for a canonical public auth origin and resolved
|
|
99
103
|
* merchant credentials. Never derive these values from Host/X-Forwarded-Host.
|
|
100
104
|
*/
|
|
101
|
-
resolveCustomerAuthContext?: (env: Env,
|
|
105
|
+
resolveCustomerAuthContext?: (env: Env, request: Request) => CustomerAuthRuntimeContext | Promise<CustomerAuthRuntimeContext>;
|
|
102
106
|
}
|
|
103
107
|
export interface CustomerAuthRuntimeContext {
|
|
108
|
+
/** Browser-visible proxy base used by storefront/BFF auth callbacks. */
|
|
109
|
+
publicApiBaseURL?: string;
|
|
110
|
+
/** Canonical origin used internally by Better Auth. */
|
|
104
111
|
baseURL: string;
|
|
105
112
|
trustedOrigins: string[];
|
|
106
113
|
methods: CustomerAuthMethods;
|
|
@@ -124,6 +131,11 @@ export interface CustomerAuthPolicy {
|
|
|
124
131
|
* merchant overrides and supply the canonical public callback otherwise.
|
|
125
132
|
*/
|
|
126
133
|
export declare function withCustomerSocialRedirectUris(methods: CustomerAuthMethods, publicApiBaseUrl: string): CustomerAuthMethods;
|
|
134
|
+
/**
|
|
135
|
+
* Rewrite Better Auth's internally generated customer password-reset URL to
|
|
136
|
+
* the browser-visible storefront/BFF API base.
|
|
137
|
+
*/
|
|
138
|
+
export declare function withCustomerPublicResetPasswordUrl(generatedUrl: string, publicApiBaseURL: string): string;
|
|
127
139
|
export declare function createOperatorAuthNodeRuntime<Env extends OperatorAuthNodeEnv>(runtimeOptions: CreateOperatorAuthNodeRuntimeOptions<Env>): {
|
|
128
140
|
handler: Hono<{
|
|
129
141
|
Bindings: Env;
|
package/dist/node-runtime.js
CHANGED
|
@@ -80,6 +80,24 @@ export function withCustomerSocialRedirectUris(methods, publicApiBaseUrl) {
|
|
|
80
80
|
},
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Rewrite Better Auth's internally generated customer password-reset URL to
|
|
85
|
+
* the browser-visible storefront/BFF API base.
|
|
86
|
+
*/
|
|
87
|
+
export function withCustomerPublicResetPasswordUrl(generatedUrl, publicApiBaseURL) {
|
|
88
|
+
try {
|
|
89
|
+
const generated = new URL(generatedUrl);
|
|
90
|
+
const publicApi = new URL(publicApiBaseURL);
|
|
91
|
+
const apiPath = publicApi.pathname.replace(/\/+$/, "");
|
|
92
|
+
publicApi.pathname = `${apiPath}${generated.pathname}`;
|
|
93
|
+
publicApi.search = generated.search;
|
|
94
|
+
publicApi.hash = generated.hash;
|
|
95
|
+
return publicApi.toString();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return generatedUrl;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
83
101
|
export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
84
102
|
const openDatabase = runtimeOptions.openDatabase ??
|
|
85
103
|
((env) => {
|
|
@@ -322,6 +340,7 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
322
340
|
env.CUSTOMER_AUTH_APPLE_CLIENT_SECRET?.trim() &&
|
|
323
341
|
(!hasCanonicalPolicy || policy.methods.apple.enabled));
|
|
324
342
|
return {
|
|
343
|
+
publicApiBaseURL: getPublicApiBaseUrl(env),
|
|
325
344
|
baseURL: getAuthBaseUrl(env),
|
|
326
345
|
trustedOrigins: getTrustedOrigins(env),
|
|
327
346
|
methods: {
|
|
@@ -356,13 +375,55 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
356
375
|
},
|
|
357
376
|
};
|
|
358
377
|
}
|
|
359
|
-
function resolveCustomerAuthContext(env, request) {
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
defaultCustomerAuthContext(env,
|
|
378
|
+
async function resolveCustomerAuthContext(env, request) {
|
|
379
|
+
const context = runtimeOptions.resolveCustomerAuthContext
|
|
380
|
+
? await runtimeOptions.resolveCustomerAuthContext(env, request)
|
|
381
|
+
: defaultCustomerAuthContext(env, parseCustomerAuthPolicy(env));
|
|
382
|
+
const baseURL = requireCanonicalOrigin(context.baseURL, "customer auth baseURL");
|
|
383
|
+
const publicApiBaseURL = requirePublicApiBaseUrl(context.publicApiBaseURL ?? `${baseURL}/api`, baseURL);
|
|
384
|
+
const trustedOrigins = context.trustedOrigins.map((origin) => requireCanonicalOrigin(origin, "customer auth trusted origin"));
|
|
385
|
+
return { ...context, baseURL, publicApiBaseURL, trustedOrigins };
|
|
386
|
+
}
|
|
387
|
+
function requireCanonicalOrigin(value, label) {
|
|
388
|
+
let parsed;
|
|
389
|
+
try {
|
|
390
|
+
parsed = new URL(value);
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
throw new Error(`${label} must be an absolute HTTP(S) origin`);
|
|
394
|
+
}
|
|
395
|
+
if (!["http:", "https:"].includes(parsed.protocol) ||
|
|
396
|
+
parsed.username ||
|
|
397
|
+
parsed.password ||
|
|
398
|
+
(parsed.pathname !== "/" && parsed.pathname !== "") ||
|
|
399
|
+
parsed.search ||
|
|
400
|
+
parsed.hash) {
|
|
401
|
+
throw new Error(`${label} must be an absolute HTTP(S) origin`);
|
|
402
|
+
}
|
|
403
|
+
return parsed.origin;
|
|
363
404
|
}
|
|
364
|
-
function
|
|
365
|
-
|
|
405
|
+
function requirePublicApiBaseUrl(value, baseURL) {
|
|
406
|
+
let parsed;
|
|
407
|
+
try {
|
|
408
|
+
parsed = new URL(value);
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
throw new Error("customer auth publicApiBaseURL must be an absolute HTTP(S) URL");
|
|
412
|
+
}
|
|
413
|
+
if (!["http:", "https:"].includes(parsed.protocol) ||
|
|
414
|
+
parsed.username ||
|
|
415
|
+
parsed.password ||
|
|
416
|
+
parsed.search ||
|
|
417
|
+
parsed.hash ||
|
|
418
|
+
parsed.origin !== baseURL ||
|
|
419
|
+
parsed.pathname === "/") {
|
|
420
|
+
throw new Error("customer auth publicApiBaseURL must be an absolute HTTP(S) URL with a path");
|
|
421
|
+
}
|
|
422
|
+
parsed.pathname = parsed.pathname.replace(/\/+$/, "");
|
|
423
|
+
return parsed.toString().replace(/\/$/, "");
|
|
424
|
+
}
|
|
425
|
+
async function publicCustomerAuthConfiguration(env, request) {
|
|
426
|
+
const methods = (await resolveCustomerAuthContext(env, request)).methods;
|
|
366
427
|
const providers = methods.socialProviders ?? {};
|
|
367
428
|
return {
|
|
368
429
|
methods: {
|
|
@@ -431,9 +492,10 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
431
492
|
},
|
|
432
493
|
});
|
|
433
494
|
}
|
|
434
|
-
function buildCustomerBetterAuth(env, db, request) {
|
|
495
|
+
async function buildCustomerBetterAuth(env, db, request) {
|
|
435
496
|
const emailSender = runtimeOptions.resolveEmailSender?.(env);
|
|
436
|
-
const context = resolveCustomerAuthContext(env, request);
|
|
497
|
+
const context = await resolveCustomerAuthContext(env, request);
|
|
498
|
+
const publicApiBaseURL = context.publicApiBaseURL ?? getPublicApiBaseUrl(env);
|
|
437
499
|
const authDb = db;
|
|
438
500
|
return createCustomerBetterAuth({
|
|
439
501
|
db: authDb,
|
|
@@ -441,16 +503,17 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
441
503
|
baseURL: context.baseURL,
|
|
442
504
|
basePath: "/auth/customer",
|
|
443
505
|
trustedOrigins: context.trustedOrigins,
|
|
444
|
-
methods: withCustomerSocialRedirectUris(context.methods,
|
|
506
|
+
methods: withCustomerSocialRedirectUris(context.methods, publicApiBaseURL),
|
|
445
507
|
sendResetPassword: async ({ user, url }) => {
|
|
508
|
+
const publicUrl = withCustomerPublicResetPasswordUrl(url, publicApiBaseURL);
|
|
446
509
|
if (!emailSender) {
|
|
447
510
|
if (allowAuthSecretLogging(env)) {
|
|
448
|
-
console.info(`[auth/customer] reset-password (debug fallback) -> ${user.email}: ${
|
|
511
|
+
console.info(`[auth/customer] reset-password (debug fallback) -> ${user.email}: ${publicUrl}`);
|
|
449
512
|
return;
|
|
450
513
|
}
|
|
451
514
|
throw new Error("Password reset email provider is not configured");
|
|
452
515
|
}
|
|
453
|
-
await emailSender.sendResetPassword({ user, url });
|
|
516
|
+
await emailSender.sendResetPassword({ user, url: publicUrl });
|
|
454
517
|
},
|
|
455
518
|
sendVerificationOTP: async ({ email, otp, type }) => {
|
|
456
519
|
if (!emailSender) {
|
|
@@ -519,7 +582,7 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
519
582
|
const { db, dispose } = openDatabase(env);
|
|
520
583
|
try {
|
|
521
584
|
const auth = customerSurface
|
|
522
|
-
? buildCustomerBetterAuth(env, db, request)
|
|
585
|
+
? await buildCustomerBetterAuth(env, db, request)
|
|
523
586
|
: buildAdminBetterAuth(env, db);
|
|
524
587
|
const session = await auth.api.getSession({ headers: request.headers });
|
|
525
588
|
if (!session) {
|
|
@@ -646,16 +709,19 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
646
709
|
}
|
|
647
710
|
}
|
|
648
711
|
async function getBootstrapStatusForRequest(request, env) {
|
|
712
|
+
const modules = runtimeOptions.activeModules
|
|
713
|
+
? { modules: [...runtimeOptions.activeModules] }
|
|
714
|
+
: {};
|
|
649
715
|
if (shouldUseBrowserEvidenceAuthFallback(env, request)) {
|
|
650
|
-
return { hasUsers: true };
|
|
716
|
+
return { hasUsers: true, ...modules };
|
|
651
717
|
}
|
|
652
718
|
if (isVoyantCloudAuthMode(env)) {
|
|
653
|
-
return { hasUsers: true, authMode: "voyant-cloud" };
|
|
719
|
+
return { hasUsers: true, authMode: "voyant-cloud", ...modules };
|
|
654
720
|
}
|
|
655
721
|
const { db, dispose } = openDatabase(env);
|
|
656
722
|
try {
|
|
657
723
|
const [row] = await db.select({ count: sql `count(*)::int` }).from(authUser);
|
|
658
|
-
return { hasUsers: (row?.count ?? 0) > 0, authMode: "local" };
|
|
724
|
+
return { hasUsers: (row?.count ?? 0) > 0, authMode: "local", ...modules };
|
|
659
725
|
}
|
|
660
726
|
finally {
|
|
661
727
|
await dispose();
|
|
@@ -876,7 +942,7 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
876
942
|
}
|
|
877
943
|
const { db, dispose } = openDatabase(c.env);
|
|
878
944
|
try {
|
|
879
|
-
const betterAuth = buildCustomerBetterAuth(c.env, db, c.req.raw);
|
|
945
|
+
const betterAuth = await buildCustomerBetterAuth(c.env, db, c.req.raw);
|
|
880
946
|
const session = await betterAuth.api.getSession({ headers: c.req.raw.headers });
|
|
881
947
|
return c.json({ authenticated: Boolean(session) });
|
|
882
948
|
}
|
|
@@ -884,7 +950,7 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
884
950
|
c.executionCtx.waitUntil(dispose());
|
|
885
951
|
}
|
|
886
952
|
});
|
|
887
|
-
auth.get("/auth/customer/config", (c) => {
|
|
953
|
+
auth.get("/auth/customer/config", async (c) => {
|
|
888
954
|
if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === "disabled") {
|
|
889
955
|
return c.json({
|
|
890
956
|
methods: {
|
|
@@ -896,7 +962,7 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
896
962
|
},
|
|
897
963
|
});
|
|
898
964
|
}
|
|
899
|
-
return c.json(publicCustomerAuthConfiguration(c.env, c.req.raw));
|
|
965
|
+
return c.json(await publicCustomerAuthConfiguration(c.env, c.req.raw));
|
|
900
966
|
});
|
|
901
967
|
auth.all("/auth/customer/*", async (c) => {
|
|
902
968
|
if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === "disabled") {
|
|
@@ -904,7 +970,7 @@ export function createOperatorAuthNodeRuntime(runtimeOptions) {
|
|
|
904
970
|
}
|
|
905
971
|
const { db, dispose } = openDatabase(c.env);
|
|
906
972
|
try {
|
|
907
|
-
const betterAuth = buildCustomerBetterAuth(c.env, db, c.req.raw);
|
|
973
|
+
const betterAuth = await buildCustomerBetterAuth(c.env, db, c.req.raw);
|
|
908
974
|
return await betterAuth.handler(c.req.raw);
|
|
909
975
|
}
|
|
910
976
|
finally {
|
package/dist/node-runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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/admin/* and /auth/customer/*.\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, VoyantResolvedSessionAuthContext } 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\"\ntype OperatorApiAuthSurface = \"admin\" | \"customer\"\n\nfunction classifyOperatorApiAuthSurface(requestUrl: string): OperatorApiAuthSurface | null {\n const pathname = new URL(requestUrl).pathname.replace(/\\/+$/, \"\") || \"/\"\n const normalized = pathname.startsWith(\"/api/\") ? pathname.slice(4) : pathname\n if (normalized === \"/v1/admin\" || normalized.startsWith(\"/v1/admin/\")) return \"admin\"\n if (normalized === \"/v1/public\" || normalized.startsWith(\"/v1/public/\")) return \"customer\"\n return null\n}\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_ADMIN_SECRET: string\n SESSION_CLAIMS_CUSTOMER_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_ADMIN_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_ADMIN_SECRET,\n secureStateCookie:\n new URL(`${getPublicApiBaseUrl(env)}/auth/admin/cloud/callback`).protocol ===\n \"https:\",\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 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<VoyantResolvedSessionAuthContext | null> {\n const surface = classifyOperatorApiAuthSurface(request.url)\n if (!surface) return null\n const customerSurface = surface === \"customer\"\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 const callbackUrl = getCloudAuthStartConfig(c.env)?.adminCallbackUrl\n return c.json({ error: \"Voyant Cloud auth exchange is not configured yet\" }, 501, {\n \"Set-Cookie\": buildClearCloudAdminAuthStateCookie(\n callbackUrl ? new URL(callbackUrl).protocol === \"https:\" : url.protocol === \"https:\",\n url.pathname.replace(/\\/callback$/, \"\") || \"/auth/admin/cloud\",\n ),\n })\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 } 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\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 if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return c.json({ authenticated: false, disabled: true })\n }\n\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 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/admin/* and /auth/customer/*.\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, VoyantResolvedSessionAuthContext } 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\"\ntype OperatorApiAuthSurface = \"admin\" | \"customer\"\n\nfunction classifyOperatorApiAuthSurface(requestUrl: string): OperatorApiAuthSurface | null {\n const pathname = new URL(requestUrl).pathname.replace(/\\/+$/, \"\") || \"/\"\n const normalized = pathname.startsWith(\"/api/\") ? pathname.slice(4) : pathname\n if (normalized === \"/v1/admin\" || normalized.startsWith(\"/v1/admin/\")) return \"admin\"\n if (normalized === \"/v1/public\" || normalized.startsWith(\"/v1/public/\")) return \"customer\"\n return null\n}\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_ADMIN_SECRET: string\n SESSION_CLAIMS_CUSTOMER_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 /** Active deployment modules used by source-free managed admin composition. */\n modules?: string[]\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 /** Active deployment modules surfaced by `/auth/bootstrap-status`. */\n activeModules?: readonly string[]\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 request: Request,\n ) => CustomerAuthRuntimeContext | Promise<CustomerAuthRuntimeContext>\n}\n\nexport interface CustomerAuthRuntimeContext {\n /** Browser-visible proxy base used by storefront/BFF auth callbacks. */\n publicApiBaseURL?: string\n /** Canonical origin used internally by Better Auth. */\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\n/**\n * Rewrite Better Auth's internally generated customer password-reset URL to\n * the browser-visible storefront/BFF API base.\n */\nexport function withCustomerPublicResetPasswordUrl(\n generatedUrl: string,\n publicApiBaseURL: string,\n): string {\n try {\n const generated = new URL(generatedUrl)\n const publicApi = new URL(publicApiBaseURL)\n const apiPath = publicApi.pathname.replace(/\\/+$/, \"\")\n publicApi.pathname = `${apiPath}${generated.pathname}`\n publicApi.search = generated.search\n publicApi.hash = generated.hash\n return publicApi.toString()\n } catch {\n return generatedUrl\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_ADMIN_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 publicApiBaseURL: getPublicApiBaseUrl(env),\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 async function resolveCustomerAuthContext(\n env: Env,\n request: Request,\n ): Promise<CustomerAuthRuntimeContext> {\n const context = runtimeOptions.resolveCustomerAuthContext\n ? await runtimeOptions.resolveCustomerAuthContext(env, request)\n : defaultCustomerAuthContext(env, parseCustomerAuthPolicy(env))\n const baseURL = requireCanonicalOrigin(context.baseURL, \"customer auth baseURL\")\n const publicApiBaseURL = requirePublicApiBaseUrl(\n context.publicApiBaseURL ?? `${baseURL}/api`,\n baseURL,\n )\n const trustedOrigins = context.trustedOrigins.map((origin) =>\n requireCanonicalOrigin(origin, \"customer auth trusted origin\"),\n )\n return { ...context, baseURL, publicApiBaseURL, trustedOrigins }\n }\n\n function requireCanonicalOrigin(value: string, label: string): string {\n let parsed: URL\n try {\n parsed = new URL(value)\n } catch {\n throw new Error(`${label} must be an absolute HTTP(S) origin`)\n }\n if (\n ![\"http:\", \"https:\"].includes(parsed.protocol) ||\n parsed.username ||\n parsed.password ||\n (parsed.pathname !== \"/\" && parsed.pathname !== \"\") ||\n parsed.search ||\n parsed.hash\n ) {\n throw new Error(`${label} must be an absolute HTTP(S) origin`)\n }\n return parsed.origin\n }\n\n function requirePublicApiBaseUrl(value: string, baseURL: string): string {\n let parsed: URL\n try {\n parsed = new URL(value)\n } catch {\n throw new Error(\"customer auth publicApiBaseURL must be an absolute HTTP(S) URL\")\n }\n if (\n ![\"http:\", \"https:\"].includes(parsed.protocol) ||\n parsed.username ||\n parsed.password ||\n parsed.search ||\n parsed.hash ||\n parsed.origin !== baseURL ||\n parsed.pathname === \"/\"\n ) {\n throw new Error(\"customer auth publicApiBaseURL must be an absolute HTTP(S) URL with a path\")\n }\n parsed.pathname = parsed.pathname.replace(/\\/+$/, \"\")\n return parsed.toString().replace(/\\/$/, \"\")\n }\n\n async function publicCustomerAuthConfiguration(env: Env, request: Request) {\n const methods = (await 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_ADMIN_SECRET,\n secureStateCookie:\n new URL(`${getPublicApiBaseUrl(env)}/auth/admin/cloud/callback`).protocol ===\n \"https:\",\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 async function buildCustomerBetterAuth(env: Env, db: VoyantDb, request: Request) {\n const emailSender = runtimeOptions.resolveEmailSender?.(env)\n const context = await resolveCustomerAuthContext(env, request)\n const publicApiBaseURL = context.publicApiBaseURL ?? getPublicApiBaseUrl(env)\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, publicApiBaseURL),\n sendResetPassword: async ({ user, url }) => {\n const publicUrl = withCustomerPublicResetPasswordUrl(url, publicApiBaseURL)\n if (!emailSender) {\n if (allowAuthSecretLogging(env)) {\n console.info(\n `[auth/customer] reset-password (debug fallback) -> ${user.email}: ${publicUrl}`,\n )\n return\n }\n throw new Error(\"Password reset email provider is not configured\")\n }\n await emailSender.sendResetPassword({ user, url: publicUrl })\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 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<VoyantResolvedSessionAuthContext | null> {\n const surface = classifyOperatorApiAuthSurface(request.url)\n if (!surface) return null\n const customerSurface = surface === \"customer\"\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 ? await 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 const modules = runtimeOptions.activeModules\n ? { modules: [...runtimeOptions.activeModules] }\n : {}\n if (shouldUseBrowserEvidenceAuthFallback(env, request)) {\n return { hasUsers: true, ...modules }\n }\n\n if (isVoyantCloudAuthMode(env)) {\n return { hasUsers: true, authMode: \"voyant-cloud\", ...modules }\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\", ...modules }\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 const callbackUrl = getCloudAuthStartConfig(c.env)?.adminCallbackUrl\n return c.json({ error: \"Voyant Cloud auth exchange is not configured yet\" }, 501, {\n \"Set-Cookie\": buildClearCloudAdminAuthStateCookie(\n callbackUrl ? new URL(callbackUrl).protocol === \"https:\" : url.protocol === \"https:\",\n url.pathname.replace(/\\/callback$/, \"\") || \"/auth/admin/cloud\",\n ),\n })\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 } 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\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 if (c.env.VOYANT_CUSTOMER_AUTH_MODE?.trim() === \"disabled\") {\n return c.json({ authenticated: false, disabled: true })\n }\n\n const { db, dispose } = openDatabase(c.env)\n try {\n const betterAuth = await 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\", async (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(await 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 = await 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 return {\n handler: auth,\n getBootstrapStatusForRequest,\n getCurrentUserForRequest,\n hasAuthPermission,\n resolveAuthRequest,\n validateApiTokenAccess,\n }\n}\n"]}
|