From ae076f981a1c5dd41f8e119dd77517de609e53f6 Mon Sep 17 00:00:00 2001 From: June1010 Date: Mon, 21 Nov 2022 11:49:53 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20class-validator=20&=20class-transformer?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/common/decorator/id.validator.ts | 32 +++++++++++++++++++++ server/src/common/decorator/index.ts | 4 +++ server/src/common/decorator/pw.validator.ts | 30 +++++++++++++++++++ server/src/common/decorator/validator.ts | 24 ---------------- server/src/main.ts | 7 +++++ server/src/user/dto/create-user.dto.ts | 14 +++++++-- server/src/user/user.controller.ts | 1 - 7 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 server/src/common/decorator/id.validator.ts create mode 100644 server/src/common/decorator/index.ts create mode 100644 server/src/common/decorator/pw.validator.ts delete mode 100644 server/src/common/decorator/validator.ts diff --git a/server/src/common/decorator/id.validator.ts b/server/src/common/decorator/id.validator.ts new file mode 100644 index 0000000..ed53e2e --- /dev/null +++ b/server/src/common/decorator/id.validator.ts @@ -0,0 +1,32 @@ +import { + registerDecorator, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from "class-validator"; + +@ValidatorConstraint({ name: "isValidId", async: false }) +class isValidIdConstraint implements ValidatorConstraintInterface { + public validate(value: string) { + return ( + typeof value === "string" && value.length >= 6 && value.length <= 20 && value.search(/^[a-zA-Z0-9]*$/) >= 0 + ); + } + + public defaultMessage(): string { + return `user id must be between 6 and 20 character long, only letters and numbers allowed`; + } +} + +export function IsValidId(validationOptions?: ValidationOptions) { + return function (object: any, propertyName: string) { + registerDecorator({ + name: "isValidId", + target: object.constructor, + propertyName: propertyName, + constraints: [], + options: validationOptions, + validator: isValidIdConstraint, + }); + }; +} diff --git a/server/src/common/decorator/index.ts b/server/src/common/decorator/index.ts new file mode 100644 index 0000000..67515b2 --- /dev/null +++ b/server/src/common/decorator/index.ts @@ -0,0 +1,4 @@ +import { IsValidId } from "./id.validator"; +import { IsValidPassword } from "./pw.validator"; + +export { IsValidId, IsValidPassword }; diff --git a/server/src/common/decorator/pw.validator.ts b/server/src/common/decorator/pw.validator.ts new file mode 100644 index 0000000..007f458 --- /dev/null +++ b/server/src/common/decorator/pw.validator.ts @@ -0,0 +1,30 @@ +import { + registerDecorator, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from "class-validator"; + +@ValidatorConstraint({ name: "isValidPassword", async: false }) +class isValidPwConstraint implements ValidatorConstraintInterface { + public validate(value: string) { + return typeof value === "string" && value.length >= 10 && value.length <= 100; + } + + public defaultMessage(): string { + return `user password must be between 10 and 100 character long`; + } +} + +export function IsValidPassword(validationOptions?: ValidationOptions) { + return function (object: any, propertyName: string) { + registerDecorator({ + name: "isValidPassword", + target: object.constructor, + propertyName: propertyName, + constraints: [], + options: validationOptions, + validator: isValidPwConstraint, + }); + }; +} diff --git a/server/src/common/decorator/validator.ts b/server/src/common/decorator/validator.ts deleted file mode 100644 index 4327e6c..0000000 --- a/server/src/common/decorator/validator.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { registerDecorator, ValidationOptions, ValidationArguments } from "class-validator"; - -export function isValidId(property: string, validationOptions?: ValidationOptions) { - return function (object: any, propertyName: string) { - registerDecorator({ - name: "isValidId", - target: object.constructor, - propertyName: propertyName, - constraints: [property], - options: validationOptions, - validator: { - validate(value: any, args: ValidationArguments) { - const [relatedPropertyName] = args.constraints; - const relatedValue = (args.object as any)[relatedPropertyName]; - return ( - typeof value === "string" && - typeof relatedValue === "string" && - value.length > relatedValue.length - ); - }, - }, - }); - }; -} diff --git a/server/src/main.ts b/server/src/main.ts index ec95c9b..73260df 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -2,6 +2,7 @@ import { NestFactory } from "@nestjs/core"; import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger"; import { AppModule } from "./app.module"; import * as cookieParser from "cookie-parser"; +import { ValidationPipe } from "@nestjs/common"; async function bootstrap() { const app = await NestFactory.create(AppModule); @@ -13,6 +14,12 @@ async function bootstrap() { .build(); const document = SwaggerModule.createDocument(app, options); app.use(cookieParser()); + app.useGlobalPipes( + new ValidationPipe({ + forbidUnknownValues: true, + transform: true, + }), + ); SwaggerModule.setup("api", app, document); await app.listen(4000); diff --git a/server/src/user/dto/create-user.dto.ts b/server/src/user/dto/create-user.dto.ts index 18de0c9..6e76e1c 100644 --- a/server/src/user/dto/create-user.dto.ts +++ b/server/src/user/dto/create-user.dto.ts @@ -1,12 +1,20 @@ -import { IsString, MinLength } from "class-validator"; +import { Type } from "class-transformer"; +import { IsNumber, IsNumberString } from "class-validator"; +import { IsValidId, IsValidPassword } from "src/common/decorator"; import { User } from "../../entities/user.entity"; export class CreateUserDto { - @IsString() - @MinLength(6) + @IsValidId() private userId: string; + + @IsValidPassword() private password: string; + + @Type(() => Number) + @IsNumber() private pace: number; + + @IsNumberString() private zipCode: string; getUserId() { diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index e028229..3a642ee 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -9,7 +9,6 @@ export class UserController { @Post() async create(@Body() createUserDto: CreateUserDto) { - createUserDto = plainToClass(CreateUserDto, createUserDto); return this.userService.create(createUserDto); } }