Files
recipe-app/backend/src/main.ts
T

55 lines
1.6 KiB
TypeScript

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { GlobalExceptionFilter } from './common/filters/global-exception.filter';
import helmet from 'helmet';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// CORS — tillåt endast appens egen origin (sätts via ALLOWED_ORIGIN i miljövariabler)
const allowedOrigin = process.env.ALLOWED_ORIGIN || 'https://recept.gynther.se';
app.enableCors({
origin: allowedOrigin,
methods: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
});
// Helmet som säkerhetsbackup (CSP hanteras av Next.js/Caddy)
app.use(
helmet({
contentSecurityPolicy: false,
crossOriginEmbedderPolicy: true,
crossOriginOpenerPolicy: { policy: 'same-origin' },
crossOriginResourcePolicy: { policy: 'same-origin' },
originAgentCluster: true,
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
strictTransportSecurity: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
xContentTypeOptions: true,
xFrameOptions: { action: 'deny' },
xXssProtection: false, // Deprecated, hanteras av Caddy
}),
);
app.setGlobalPrefix('api');
// Registrera global exception filter
app.useGlobalFilters(new GlobalExceptionFilter());
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
}),
);
await app.listen(8080, '0.0.0.0');
}
bootstrap();