diff --git a/package-lock.json b/package-lock.json index 9dacb2ad0331d92cfe2d4ea26e506e7b449e50cd..6e263e935453408f57369118cc2079e3205ed7cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2700,6 +2700,11 @@ } } }, + "express-rate-limit": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-4.0.4.tgz", + "integrity": "sha512-DLRj2vMO7Xgai8qWKU9O6ZztF2bdDmfFNFi9k3G9BPzJ+7MG7eWaaBikbe0eBpNGSxU8JziwW0PQKG78aNWa6g==" + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", diff --git a/package.json b/package.json index 7cf5c17ae94593863f5030b3183c73ba3ff891f3..2dd162d5d2e4d1bb28b0351c7afa69dbeefd74f0 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "bcryptjs": "^2.4.3", "class-transformer": "^0.2.3", "class-validator": "^0.9.1", + "express-rate-limit": "^4.0.4", "jsonwebtoken": "^8.5.1", "pg": "^7.11.0", "reflect-metadata": "^0.1.12", diff --git a/src/main.ts b/src/main.ts index 1c70cb25c549b76c47fc0e078b05adaba2219ebc..3c7cc4607bac085ff529775a441ef81e4e089a6a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,22 @@ import { NestFactory } from '@nestjs/core'; +import * as rateLimit from 'express-rate-limit'; import { AppModule } from './app.module'; +// due to a bug with newest release of express-rate-limit, call for rateLimit is broken +// (rateLimit as any) works as a workaround for now +// see https://github.com/nfriedly/express-rate-limit/issues/138 +const limiter = (rateLimit as any)({ + windowMs: 60 * 1000, // one minute + max: 100 // limit each IP to 100 requests per windowMs +}); + async function bootstrap() { const app = await NestFactory.create(AppModule); // Cors is needed for application/json POST app.enableCors(); + // apply limiter to all routes + app.use(limiter); await app.listen(5000); } bootstrap(); diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index c10ef159a2a6f877164ebc4bd73f740aac19a277..363e894a9e7fd0cb34df6dbd8a81b496f623bdea 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -1,8 +1,9 @@ -import { Controller, Post, Body, UsePipes, ValidationPipe, Get, UseGuards, Req } from '@nestjs/common'; +import { Controller, Post, Body, UsePipes, Get, UseGuards } from '@nestjs/common'; import { UserService } from './user.service'; import { UserDTO } from './user.dto'; import { AuthGuard } from 'src/shared/auth.guard'; +import { ValidationPipe } from 'src/shared/validation.pipe'; @Controller('user') export class UserController { diff --git a/src/user/user.dto.ts b/src/user/user.dto.ts index 4d806ad44c69002ca802b62918cfc5338f5a8924..c5bfa70cc3551645e1773e9aa7c4fb898b3f9887 100644 --- a/src/user/user.dto.ts +++ b/src/user/user.dto.ts @@ -1,8 +1,10 @@ -import { IsString } from 'class-validator'; +import { IsString, IsNotEmpty, Length } from 'class-validator'; export class UserDTO { - @IsString() + // uses class-validator built in validations + // see https://github.com/typestack/class-validator + @IsString() @IsNotEmpty() @Length(3, 31) name: string; - @IsString() + @IsString() @IsNotEmpty() @Length(3, 255) password: string; } \ No newline at end of file