Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ USE_REDIS_CACHE=true
PORT=3001
APP_NAME=STATION BACKEND

# CORS Configuration
# Production: https://station.drdnt.org
ALLOWED_ORIGIN=http://localhost:5173

# UEX Sync Configuration
UEX_SYNC_ENABLED=true
UEX_CATEGORIES_SYNC_ENABLED=true
Expand Down
4 changes: 4 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@
"cache-manager-redis-yet": "^5.1.5",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
"cookie-parser": "^1.4.7",
"dotenv": "^16.4.5",
"figlet": "^1.8.0",
"helmet": "^8.0.0",
"joi": "^17.13.3",
Comment on lines +53 to +57
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cookie-parser (and @types/cookie-parser) and joi are added as dependencies here, but there are no usages in the backend codebase. If they’re not required for this PR, please remove them to avoid dependency bloat; if they are intended for env validation / cookie auth, wire them up in code (e.g., ConfigModule validation schema for ALLOWED_ORIGIN, or app.use(cookieParser())) within the same change.

Copilot uses AI. Check for mistakes.
"passport": "^0.7.0",
"passport-http-bearer": "^1.0.1",
"passport-jwt": "^4.0.1",
Expand All @@ -68,6 +71,7 @@
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.3.9",
"@types/express": "^4.17.21",
"@types/cookie-parser": "^1.4.8",
"@types/figlet": "^1.7.0",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.12",
Expand Down
18 changes: 14 additions & 4 deletions backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import 'reflect-metadata';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger, ValidationPipe } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import * as figlet from 'figlet';
import * as dotenv from 'dotenv';
import helmet from 'helmet';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';

dotenv.config();
Expand All @@ -13,14 +15,22 @@ async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Application configuration
const port = process.env.PORT || 3001;
const appName = process.env.APP_NAME || 'STATION BACKEND';
const configService = app.get(ConfigService);
const port = configService.get<string>('PORT') || 3001;
const appName = configService.get<string>('APP_NAME') || 'STATION BACKEND';

// ASCII Art for Application Name
console.log(figlet.textSync(appName, { horizontalLayout: 'full' }));

// Enable CORS (if needed for APIs)
app.enableCors();
// Security headers — must be registered before other middleware
app.use(helmet());
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helmet’s default contentSecurityPolicy commonly blocks Swagger UI (inline scripts/styles used by /api/docs), which can cause the docs page to render blank or throw CSP errors in the browser. Configure Helmet so Swagger still works (e.g., disable/relax CSP globally, or apply a different Helmet config for the Swagger route).

Suggested change
app.use(helmet());
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: [`'self'`],
baseUri: [`'self'`],
objectSrc: [`'none'`],
scriptSrc: [`'self'`, `'unsafe-inline'`],
styleSrc: [`'self'`, `'unsafe-inline'`],
imgSrc: [`'self'`, 'data:', 'https:'],
fontSrc: [`'self'`, 'https:', 'data:'],
},
},
}),
);

Copilot uses AI. Check for mistakes.

// CORS — restrict to known origin
app.enableCors({
origin: configService.get<string>('ALLOWED_ORIGIN'),
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
});
Comment on lines +28 to +33
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ALLOWED_ORIGIN is optional here (configService.get(...) can return undefined). If it’s missing/misconfigured, the CORS middleware will fall back to its defaults, which undermines the goal of restricting origins (and can also break credentialed CORS). Make this a required startup config (e.g., use getOrThrow, or explicitly check and throw before calling enableCors) and consider trimming/validating the value (URI, no trailing slash).

Copilot uses AI. Check for mistakes.

// Global Validation Pipe
app.useGlobalPipes(
Expand Down
82 changes: 82 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading