docs(#414): add TRUSTED_ORIGINS and COOKIE_DOMAIN to .env.example
All checks were successful
ci/woodpecker/push/api Pipeline was successful
All checks were successful
ci/woodpecker/push/api Pipeline was successful
Refs #414 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -117,6 +117,14 @@ JWT_EXPIRATION=24h
|
|||||||
# Example: openssl rand -base64 32
|
# Example: openssl rand -base64 32
|
||||||
BETTER_AUTH_SECRET=REPLACE_WITH_RANDOM_SECRET_MINIMUM_32_CHARS
|
BETTER_AUTH_SECRET=REPLACE_WITH_RANDOM_SECRET_MINIMUM_32_CHARS
|
||||||
|
|
||||||
|
# Trusted Origins (comma-separated list of additional trusted origins for CORS and auth)
|
||||||
|
# These are added to NEXT_PUBLIC_APP_URL and NEXT_PUBLIC_API_URL automatically
|
||||||
|
TRUSTED_ORIGINS=
|
||||||
|
|
||||||
|
# Cookie Domain (for cross-subdomain session sharing)
|
||||||
|
# Leave empty for single-domain setups. Set to ".example.com" for cross-subdomain.
|
||||||
|
COOKIE_DOMAIN=
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# Encryption (Credential Security)
|
# Encryption (Credential Security)
|
||||||
# ======================
|
# ======================
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { NestFactory } from "@nestjs/core";
|
|||||||
import { ValidationPipe } from "@nestjs/common";
|
import { ValidationPipe } from "@nestjs/common";
|
||||||
import cookieParser from "cookie-parser";
|
import cookieParser from "cookie-parser";
|
||||||
import { AppModule } from "./app.module";
|
import { AppModule } from "./app.module";
|
||||||
|
import { getTrustedOrigins } from "./auth/auth.config";
|
||||||
import { GlobalExceptionFilter } from "./filters/global-exception.filter";
|
import { GlobalExceptionFilter } from "./filters/global-exception.filter";
|
||||||
|
|
||||||
function getPort(): number {
|
function getPort(): number {
|
||||||
@@ -47,39 +48,9 @@ async function bootstrap() {
|
|||||||
app.useGlobalFilters(new GlobalExceptionFilter());
|
app.useGlobalFilters(new GlobalExceptionFilter());
|
||||||
|
|
||||||
// Configure CORS for cookie-based authentication
|
// Configure CORS for cookie-based authentication
|
||||||
// SECURITY: Cannot use wildcard (*) with credentials: true
|
// Origin list is shared with BetterAuth trustedOrigins via getTrustedOrigins()
|
||||||
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
||||||
|
|
||||||
const allowedOrigins = [
|
|
||||||
process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:3000",
|
|
||||||
"https://app.mosaicstack.dev", // Production web
|
|
||||||
"https://api.mosaicstack.dev", // Production API
|
|
||||||
];
|
|
||||||
|
|
||||||
// Development-only origins (not allowed in production)
|
|
||||||
if (isDevelopment) {
|
|
||||||
allowedOrigins.push("http://localhost:3001"); // API origin (dev)
|
|
||||||
}
|
|
||||||
|
|
||||||
app.enableCors({
|
app.enableCors({
|
||||||
origin: (
|
origin: getTrustedOrigins(),
|
||||||
origin: string | undefined,
|
|
||||||
callback: (err: Error | null, allow?: boolean) => void
|
|
||||||
): void => {
|
|
||||||
// Allow requests with no Origin header (health checks, server-to-server,
|
|
||||||
// load balancer probes). These are not cross-origin requests per the CORS spec.
|
|
||||||
if (!origin) {
|
|
||||||
callback(null, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if origin is in allowed list
|
|
||||||
if (allowedOrigins.includes(origin)) {
|
|
||||||
callback(null, true);
|
|
||||||
} else {
|
|
||||||
callback(new Error(`Origin ${origin} not allowed by CORS`));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
credentials: true, // Required for cookie-based authentication
|
credentials: true, // Required for cookie-based authentication
|
||||||
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
||||||
allowedHeaders: ["Content-Type", "Authorization", "Cookie", "X-CSRF-Token", "X-Workspace-Id"],
|
allowedHeaders: ["Content-Type", "Authorization", "Cookie", "X-CSRF-Token", "X-Workspace-Id"],
|
||||||
|
|||||||
Reference in New Issue
Block a user