feat(api): drive CORS + trusted origins from CORS_ORIGINS env

Phone/LAN testing previously required editing both app.ts (cors origin) and
auth.ts (better-auth trustedOrigins). Now both read env.WEB_ORIGINS, parsed from
a comma-separated CORS_ORIGINS env var (default http://localhost:5173). To test
from a phone, set CORS_ORIGINS to include the LAN origin and restart the API — no
code edit. Documented in .env.example. Also fixed the worker README (db:migrate
creates ./data/app.db, not ./.tmp; phone step now uses CORS_ORIGINS). API tests
36/36 green; typecheck clean.
This commit is contained in:
Bas van Rossem
2026-06-17 16:50:21 +02:00
parent bd8e8aff2a
commit 34c48d6353
5 changed files with 25 additions and 7 deletions

View File

@@ -5,13 +5,14 @@ import { me } from './routes/me';
import { activitiesRoutes } from './routes/activities';
import { sessionsRoutes } from './routes/sessions';
import { auth } from './auth';
import { env } from './env';
export function createApp(): Hono {
const app = new Hono();
app.use(
'/api/*',
cors({
origin: ['http://localhost:5173'],
origin: env.WEB_ORIGINS,
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization'],
exposeHeaders: ['set-auth-token'], // so the SPA can read the bearer token on sign-in

View File

@@ -8,7 +8,7 @@ import { env } from './env';
export const auth = betterAuth({
secret: env.BETTER_AUTH_SECRET,
baseURL: env.BETTER_AUTH_URL,
trustedOrigins: [env.BETTER_AUTH_URL, 'http://localhost:3000', 'http://localhost:5173'],
trustedOrigins: [env.BETTER_AUTH_URL, 'http://localhost:3000', ...env.WEB_ORIGINS],
database: drizzleAdapter(db, { provider: 'sqlite', schema }),
emailAndPassword: {
enabled: true,

View File

@@ -1,6 +1,14 @@
const webOrigins = process.env.CORS_ORIGINS?.split(',')
.map((s) => s.trim())
.filter(Boolean);
export const env = {
DATABASE_URL: process.env.DATABASE_URL ?? 'file:./data/app.db',
BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET ?? 'dev-insecure-secret-change-me',
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL ?? 'http://localhost:3000',
PORT: Number(process.env.PORT ?? 3000),
// Browser origins allowed for CORS + better-auth trustedOrigins. Set CORS_ORIGINS to a
// comma-separated list (e.g. "http://localhost:5173,http://192.168.1.50:5173") to let a
// phone on the LAN reach the API — no code edit needed. Defaults to the local Vite origin.
WEB_ORIGINS: webOrigins && webOrigins.length ? webOrigins : ['http://localhost:5173'],
};