Snai3i-LandingPage-FormBuilder / backend / src / middlewares / validateSchemaMiddleware.ts
validateSchemaMiddleware.ts
Raw
import { Request, Response, NextFunction } from 'express';
import Joi, { ObjectSchema, object } from 'joi';
import Logger from '../utils/logger';
import { ErrorResponse } from '../utils/response';
import { HttpCodes } from '../config/errors';
import { UserI } from '../models/userModel';

const generateErorrMessage = (error: any) => {
  const errorDetails = error.details.map((err: any) => err.message).join(',');
  return `${error.name}: ${errorDetails}`;
};

export const ValidateBodySchema = (schema: ObjectSchema) => {
  return async (req: Request, res: Response, next: NextFunction) => {
    try {
      await schema.validateAsync(req.body);
      next();
    } catch (error: any) {
      const errorMsg = generateErorrMessage(error);

      Logger.error(error);
      return ErrorResponse(res, HttpCodes.UnprocessableEntity.code, errorMsg);
    }
  };
};

export const ValidateQuerySchema = (schema: ObjectSchema) => {
  return async (req: Request, res: Response, next: NextFunction) => {
    try {
      await schema.validateAsync(req.query);
      next();
    } catch (error: any) {
      const errorMsg = generateErorrMessage(error);

      Logger.error(errorMsg);
      return ErrorResponse(res, HttpCodes.UnprocessableEntity.code, errorMsg);
    }
  };
};

interface UserWithIdI extends UserI {
  userId: string;
}

const userValidation = {
  register: Joi.object<UserI>({
    firstName: Joi.string().required(),
    lastName: Joi.string().required(),
    email: Joi.string().email().required(),
    password: Joi.string().min(6).required(),
    role: Joi.string().valid('superAdmin', 'admin').required(),
  }),
  login: Joi.object<UserI>({
    email: Joi.string().required(),
    password: Joi.string().required(),
  }),
  update: Joi.object<UserWithIdI>({
    userId: Joi.string().required(),
    firstName: Joi.string(),
    lastName: Joi.string(),
    email: Joi.string().email(),
    role: Joi.string(),
    password: Joi.string().min(6),
  }),
  updatePassword: Joi.object<UserWithIdI>({
    userId: Joi.string().required(),
    password: Joi.string().min(6).required(),
  }),
  delete: Joi.object<UserWithIdI>({
    userId: Joi.string().required(),
  }),
};

const formValidation = {
  create: Joi.object({
    name: Joi.string().required(),
    elements: Joi.array().items(Joi.object()),
  }),
  getAll: Joi.object({
    page: Joi.number(),
    pageSize: Joi.number(),
    search: Joi.string(),
    sort: Joi.string(),
  }),
  update: Joi.object({
    name: Joi.string(),
    elements: Joi.array().items(Joi.object()),
    isActive: Joi.boolean(),
    user: Joi.string(),
  }),
  bulk_delete: Joi.object({
    forms: Joi.array().items(Joi.string()),
  }),
};

const formResponseValidation = {
  create: Joi.object({
    response: Joi.array()
      .items(
        Joi.object({
          elementType: Joi.string().required(),
          question: Joi.string().required(),
          answer: Joi.any().required(),
        })
      )
      .required(),
  }),
};

const stormCodeValidation = {
  generate: Joi.object({
    email: Joi.string().email().required(),
  }),
  verify: Joi.object({
    email: Joi.string().email().required(),
    code: Joi.string().required(),
  }),
};

export const Schemas = {
  user: userValidation,
  form: formValidation,
  formResponse: formResponseValidation,
  stormCode: stormCodeValidation,
};