Skip to content
Merged
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
51 changes: 49 additions & 2 deletions BackendAcademy/src/app.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AppModule } from './app.module';
import request from 'supertest';

describe('AppController', () => {
let appController: AppController;

beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
const module: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();

appController = app.get<AppController>(AppController);
appController = module.get<AppController>(AppController);
});

describe('getHello', () => {
Expand All @@ -20,3 +23,47 @@ describe('AppController', () => {
});
});
});

describe('Request body size limit (e2e)', () => {
let app: INestApplication;

beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();

app = moduleFixture.createNestApplication();
await app.init();
});

afterEach(async () => {
await app.close();
});

it('should reject oversized JSON bodies with 413 Payload Too Large', async () => {
// Create a payload larger than the default 1MB limit
const oversizedPayload = { data: 'x'.repeat(2 * 1024 * 1024) }; // 2MB

const response = await request(app.getHttpServer())
.post('/api/test')
.send(oversizedPayload)
.expect(413);

expect(response.body).toHaveProperty('message');
expect(response.body.message).toContain('payload too large');
});

it('should accept JSON bodies within the size limit', async () => {
// Create a payload well within the 1MB limit
const validPayload = { data: 'x'.repeat(100) };

// Note: This endpoint may not exist, but the body size limit
// middleware should still allow the request through (possibly 404)
const response = await request(app.getHttpServer())
.post('/api/test')
.send(validPayload);

// Should not be 413 (Payload Too Large)
expect(response.status).not.toBe(413);
});
});
11 changes: 9 additions & 2 deletions BackendAcademy/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ConfigService } from '@nestjs/config';
import { NestExpressApplication } from '@nestjs/platform-express';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import helmet from 'helmet';
import * as express from 'express';
import { AppModule } from './app.module';

// Application entry point: creates the Nest app, applies global
Expand All @@ -26,6 +27,14 @@ async function bootstrap() {
// paths for monitoring tools that expect them un-prefixed).
app.setGlobalPrefix('api', { exclude: ['health'] });

const configService = app.get(ConfigService);
// Enforces a maximum request body size to prevent DoS attacks from
// oversized payloads. Defaults to 1MB; configurable via MAX_BODY_SIZE
// env var (e.g., '5mb', '10mb'). Requests exceeding this limit return
// HTTP 413 (Payload Too Large) with a clear error message.
const maxBodySize = configService.get<string>('MAX_BODY_SIZE', '1mb');
app.use(express.json({ limit: maxBodySize }));

// Global validation pipe applied to all incoming request bodies/params:
// - whitelist: strips properties not defined on the target DTO
// - transform: converts payloads into instances of their DTO classes
Expand All @@ -38,8 +47,6 @@ async function bootstrap() {
forbidNonWhitelisted: true,
}),
);

const configService = app.get(ConfigService);
// Swagger docs default to enabled unless explicitly turned off via
// the SWAGGER_ENABLED env var.
const swaggerEnabled = configService.get<string>('SWAGGER_ENABLED', 'true') === 'true';
Expand Down
3 changes: 2 additions & 1 deletion BackendAcademy/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false,
"esModuleInterop": true,
"resolveJsonModule": true
"resolveJsonModule": true,
"ignoreDeprecations": "6.0"
},
"include": ["src/**/*", "test/**/*"],
"exclude": ["node_modules", "dist"]
Expand Down
Loading