Init
This commit is contained in:
116
backend/src/main.ts
Normal file
116
backend/src/main.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { webcrypto } from 'crypto';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
|
||||
// Polyfill crypto for @nestjs/typeorm
|
||||
if (!global.crypto) {
|
||||
global.crypto = webcrypto as any;
|
||||
}
|
||||
import { Logger, ValidationPipe } from '@nestjs/common';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { utilities, WinstonModule } from 'nest-winston';
|
||||
import winston from 'winston';
|
||||
import helmet from 'helmet';
|
||||
//import rateLimit from 'express-rate-limit';
|
||||
import cookieParser from 'cookie-parser';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { ApiDocumentation } from './documentation';
|
||||
import { extractSubdomain, LoggingInterceptor } from './common';
|
||||
|
||||
function getLogger() {
|
||||
return process.env.WINSTON_ENABLED === 'true'
|
||||
? WinstonModule.createLogger({
|
||||
level: 'debug',
|
||||
transports: [
|
||||
new winston.transports.Console({
|
||||
format: winston.format.combine(
|
||||
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }),
|
||||
utilities.format.nestLike(process.env.APPLICATION_NAME, { colors: true, prettyPrint: true }),
|
||||
),
|
||||
}),
|
||||
],
|
||||
})
|
||||
: undefined;
|
||||
}
|
||||
|
||||
async function bootstrap() {
|
||||
if (process.env.NEW_RELIC_ENABLED === 'true') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
require('newrelic');
|
||||
}
|
||||
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule, { rawBody: true, logger: getLogger() });
|
||||
|
||||
// Security headers
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
scriptSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "blob:"],
|
||||
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
|
||||
imgSrc: ["'self'", "data:", "blob:", "https://*"],
|
||||
fontSrc: ["'self'", "https://fonts.gstatic.com"],
|
||||
connectSrc: ["'self'"],
|
||||
frameSrc: ["'self'"],
|
||||
objectSrc: ["'none'"],
|
||||
baseUri: ["'self'"],
|
||||
formAction: ["'self'"]
|
||||
}
|
||||
},
|
||||
hsts: {
|
||||
maxAge: 31536000,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
},
|
||||
referrerPolicy: { policy: 'strict-origin-when-cross-origin' }
|
||||
}));
|
||||
|
||||
// Rate limiting disabled to eliminate 429 errors
|
||||
// app.use(
|
||||
// rateLimit({
|
||||
// windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
// max: 1000, // limit each IP to 1000 requests per windowMs
|
||||
// message: 'Too many requests from this IP, please try again later.',
|
||||
// standardHeaders: true,
|
||||
// legacyHeaders: false,
|
||||
// }),
|
||||
// );
|
||||
|
||||
// CORS with restrictions
|
||||
app.enableCors({
|
||||
origin: process.env['FRONTEND_URL'] || 'http://localhost:3000',
|
||||
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
|
||||
credentials: true,
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'X-CSRF-Token']
|
||||
});
|
||||
|
||||
app.set('trust proxy', true);
|
||||
app.use(cookieParser());
|
||||
app.use(extractSubdomain);
|
||||
app.setGlobalPrefix('api');
|
||||
|
||||
// Global validation
|
||||
app.useGlobalPipes(new ValidationPipe({
|
||||
whitelist: true,
|
||||
forbidNonWhitelisted: false,
|
||||
transform: true,
|
||||
disableErrorMessages: process.env['NODE_ENV'] === 'production'
|
||||
}));
|
||||
|
||||
app.useGlobalInterceptors(new LoggingInterceptor());
|
||||
|
||||
ApiDocumentation.configure(app);
|
||||
|
||||
const logger = new Logger('main');
|
||||
|
||||
process.on('uncaughtException', (error) => {
|
||||
logger.error(`Uncaught Exception`, error.stack);
|
||||
});
|
||||
|
||||
await app.listen(process.env.APPLICATION_PORT, '127.0.0.1');
|
||||
|
||||
logger.log(`Application is running on: ${await app.getUrl()}`);
|
||||
logger.log(`Application version is: ${process.env.npm_package_version}`);
|
||||
}
|
||||
|
||||
bootstrap();
|
||||
Reference in New Issue
Block a user