From 6e2cad452121bde64dc692c618b9f12ffc31469e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adel=20Rodr=C3=ADguez?= Date: Sun, 1 Feb 2026 15:19:30 -0400 Subject: [PATCH] feat: add trusted origins configuration for auth --- .../src/functions/shared/auth/index.ts | 7 ++++- .../src/functions/shared/auth/options.ts | 1 - packages/env/src/presets.ts | 26 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/functions/shared/auth/index.ts b/packages/backend/src/functions/shared/auth/index.ts index 6fad52f0..f846aed4 100644 --- a/packages/backend/src/functions/shared/auth/index.ts +++ b/packages/backend/src/functions/shared/auth/index.ts @@ -5,4 +5,9 @@ import { authOptions } from "#functions/shared/auth/options.ts" import env from "#functions/shared/env.ts" export const convexAuth = (ctx: GenericCtx) => - createAuth({ ...authOptions(ctx), baseURL: env.CONVEX_SITE_URL, secret: env.AUTH_SECRET }) + createAuth({ + ...authOptions(ctx), + baseURL: env.CONVEX_SITE_URL, + secret: env.AUTH_SECRET, + trustedOrigins: env.AUTH_TRUSTED_ORIGINS, + }) diff --git a/packages/backend/src/functions/shared/auth/options.ts b/packages/backend/src/functions/shared/auth/options.ts index 05ef747c..cb02e1f3 100644 --- a/packages/backend/src/functions/shared/auth/options.ts +++ b/packages/backend/src/functions/shared/auth/options.ts @@ -33,5 +33,4 @@ export const authOptions = (ctx: GenericCtx) => expiresIn: SESSION_EXPIRES_IN, updateAge: SESSION_UPDATE_AGE, }, - trustedOrigins: ["init://"], }) satisfies AuthOptions diff --git a/packages/env/src/presets.ts b/packages/env/src/presets.ts index a9c28664..78341781 100644 --- a/packages/env/src/presets.ts +++ b/packages/env/src/presets.ts @@ -18,6 +18,32 @@ export const auth = () => runtimeEnv: process.env, server: { AUTH_SECRET: z.string(), + AUTH_TRUSTED_ORIGINS: z + .string() + .transform((value) => + value + .split(",") + .map((item) => item.trim()) + .filter(Boolean) + ) + .pipe( + z.array( + z.union([ + // Exact http/https origin (domain, localhost, or IPv4; optional port) + z + .string() + .regex( + /^https?:\/\/(?:(?:[a-z0-9-]+\.)+[a-z0-9-]+|localhost|(?:\d{1,3}\.){3}\d{1,3})(?::\d{1,5})?$/i + ), + // HTTP/HTTPS wildcard subdomain + z.string().regex(/^https?:\/\/\*\.(?:[a-z0-9-]+\.)+[a-z0-9-]+(?::\d{1,5})?$/i), + // Protocol-agnostic wildcard subdomain + z.string().regex(/^\*\.(?:[a-z0-9-]+\.)+[a-z0-9-]+$/i), + // Custom schemes (chrome-extension, myapp, exp, etc.) + z.string().regex(/^(?!https?:\/\/)[a-z][a-z0-9+.-]*:\/\/[^\s]*$/i), + ]) + ) + ), }, skipValidation: isCI, })