From 26acf302c282ef48209299241ede54168c3d02bd Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Sun, 4 Jan 2026 17:36:52 +0330 Subject: [PATCH] fix : sep gateway --- src/core/middlewares/validator.middleware.ts | 143 +++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/core/middlewares/validator.middleware.ts diff --git a/src/core/middlewares/validator.middleware.ts b/src/core/middlewares/validator.middleware.ts new file mode 100644 index 0000000..e511500 --- /dev/null +++ b/src/core/middlewares/validator.middleware.ts @@ -0,0 +1,143 @@ +import { ClassConstructor, plainToInstance } from "class-transformer"; +import { ValidationError, validate } from "class-validator"; +import { NextFunction, Request, RequestHandler, Response } from "express"; +import { injectable } from "inversify"; + +import { BadRequestError } from "../app/app.errors"; + +@injectable() +export class ValidationMiddleware { + static validateInputWithLogging(DTO: ClassConstructor, logPrefix: string = "Request Body"): RequestHandler { + return async (req: Request, _res: Response, next: NextFunction): Promise => { + try { + // Log the raw request body before validation + console.log(`${logPrefix}:`, JSON.stringify(req.body, null, 2)); + + // Convert the request body to an instance of the DTO class + const validationClass = plainToInstance(DTO, req.body, { + excludeExtraneousValues: true, + }); + + // Validate the DTO instance, including nested objects + const errors: ValidationError[] = await validate(validationClass, { + whitelist: true, + // forbidNonWhitelisted: true, + // transform: true, + }); + if (errors.length > 0) { + const errorMsg = errors.map((error) => ValidationMiddleware.flattenValidationErrors(error)).flat(); + + next(new BadRequestError(errorMsg)); + // throw new BadRequestError("Bad Request", errorMsg); + } else { + req.body = validationClass; + next(); + } + } catch (error) { + next(error); + } + }; + } + + static validateInput(DTO: ClassConstructor): RequestHandler { + return async (req: Request, _res: Response, next: NextFunction): Promise => { + try { + // Convert the request body to an instance of the DTO class + const validationClass = plainToInstance(DTO, req.body, { + excludeExtraneousValues: true, + }); + + // Validate the DTO instance, including nested objects + const errors: ValidationError[] = await validate(validationClass, { + whitelist: true, + // forbidNonWhitelisted: true, + // transform: true, + }); + if (errors.length > 0) { + const errorMsg = errors.map((error) => ValidationMiddleware.flattenValidationErrors(error)).flat(); + + next(new BadRequestError(errorMsg)); + // throw new BadRequestError("Bad Request", errorMsg); + } else { + req.body = validationClass; + next(); + } + } catch (error) { + next(error); + } + }; + } + + static validateParameter(DTO: ClassConstructor): RequestHandler { + return async (req: Request, _res: Response, next: NextFunction): Promise => { + try { + // Convert the request body to an instance of the DTO class + const validationClass = plainToInstance(DTO, req.params, { + excludeExtraneousValues: true, + enableImplicitConversion: true, + }); + + // Validate the DTO instance, including nested objects + const errors: ValidationError[] = await validate(validationClass, { + whitelist: true, + // forbidNonWhitelisted: true, + // transform: true, + }); + if (errors.length > 0) { + const errorMsg = errors.map((error) => ValidationMiddleware.flattenValidationErrors(error)).flat(); + + next(new BadRequestError(errorMsg)); + // throw new BadRequestError("Bad Request", errorMsg); + } else { + req.query = validationClass; + next(); + } + } catch (error) { + next(error); + } + }; + } + + static validateQuery(DTO: ClassConstructor): RequestHandler { + return async (req: Request, _res: Response, next: NextFunction): Promise => { + try { + // Convert the request body to an instance of the DTO class + const validationClass = plainToInstance(DTO, req.query, { + excludeExtraneousValues: true, + enableImplicitConversion: true, + }); + + // Validate the DTO instance, including nested objects + const errors: ValidationError[] = await validate(validationClass, { + whitelist: true, + // forbidNonWhitelisted: true, + // transform: true, + }); + if (errors.length > 0) { + const errorMsg = errors.map((error) => ValidationMiddleware.flattenValidationErrors(error)).flat(); + + next(new BadRequestError(errorMsg)); + // throw new BadRequestError("Bad Request", errorMsg); + } else { + req.query = validationClass; + next(); + } + } catch (error) { + next(error); + } + }; + } + + // Helper function to recursively flatten nested validation errors + private static flattenValidationErrors(error: ValidationError): string[] { + if (error.constraints) { + return Object.values(error.constraints); + } + + if (error.children && error.children.length > 0) { + return error.children.map(ValidationMiddleware.flattenValidationErrors).flat(); + } + + return []; + } +} \ No newline at end of file