Skip to content

Commit

Permalink
DEV : Clean code : add validation middleware where missing
Browse files Browse the repository at this point in the history
  • Loading branch information
juliecoust committed Jan 6, 2025
1 parent c2ed454 commit db61db1
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 310 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { NextFunction, Request, Response } from "express"
import { ValidationChain } from "express-validator"

export interface IMiddlewareInstrumentModelValidation {
rulesGetInstrumentModels: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[]
}
2 changes: 0 additions & 2 deletions src/presentation/interfaces/middleware/sample-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { ValidationChain } from "express-validator"

export interface IMiddlewareSampleValidation {
rulesGetSamples: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[]
// rulesSampleRequestCreationModel: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[]
// rulesSampleUpdateModel: ((Middleware & ContextRunner) | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[]
}


6 changes: 6 additions & 0 deletions src/presentation/interfaces/middleware/task-validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { NextFunction, Request, Response } from "express"
import { ValidationChain } from "express-validator"

export interface IMiddlewareTaskValidation {
rulesGetTasks: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[]
}
21 changes: 21 additions & 0 deletions src/presentation/middleware/instrument_model-validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NextFunction, Request, Response } from 'express';
import { validationResult, query } from 'express-validator';
import { IMiddlewareInstrumentModelValidation } from '../interfaces/middleware/instrument_model-validation';

export class MiddlewareInstrumentModelValidation implements IMiddlewareInstrumentModelValidation {
rulesGetInstrumentModels = [
query('page').default(1)
.isInt({ min: 1 }).withMessage('Page must be a number and must be greater than 0.'),
query('limit').default(10)
.isInt({ min: 1 }).withMessage('Limit must be a number and must be greater than 0.'),
query('sort_by').default("asc(user_id)"),
(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
// Centralized error handling for validation errors
return res.status(422).json({ errors: errors.array() });
}
next();
},
];
}
268 changes: 0 additions & 268 deletions src/presentation/middleware/sample-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,274 +5,6 @@ import { IMiddlewareSampleValidation } from '../interfaces/middleware/sample-val


export class MiddlewareSampleValidation implements IMiddlewareSampleValidation {
// rulesSampleRequestCreationModel = [
// // Root Folder Path Validation
// check('root_folder_path')
// .trim()
// .not().isEmpty().withMessage('Root Folder Path is required.'),

// // Sample Title Validation
// check('sample_title')
// .trim()
// .not().isEmpty().withMessage('Sample title is required.'),

// // Sample acrony Validation
// check('sample_acronym')
// .trim()
// .not().isEmpty().withMessage('Sample acronym is required.'),

// // Sample description Validation
// check('sample_description')
// .trim()
// .not().isEmpty().withMessage('Sample description is required.'),

// // Sample information Validation
// check('sample_information')
// .trim()
// .not().isEmpty().withMessage('Sample information is required.'),

// // Sample cruise Validation
// check('cruise')
// .trim()
// .not().isEmpty().withMessage('Cruise name is required.'),

// // Sample ship Validation
// check('ship').trim()
// .not().isEmpty().withMessage('Ship name is required.'),

// // Data owner name Validation
// check('data_owner_name')
// .trim()
// .not().isEmpty().withMessage('Data owner name is required.'),

// // Data owner email Validation
// check('data_owner_email').exists().withMessage('Data owner email is required.')
// .trim()
// .normalizeEmail()
// .isEmail().withMessage('Data owner email must be a valid email address.')
// .bail(),

// // Operator name Validation
// check('operator_name')
// .trim()
// .not().isEmpty().withMessage('Operator name is required.'),

// // Operator email Validation
// check('operator_email').exists().withMessage('Operator email is required.')
// .trim()
// .normalizeEmail()
// .isEmail().withMessage('Operator email must be a valid email address.')
// .bail(),

// // Chief scientist name Validation
// check('chief_scientist_name')
// .trim()
// .not().isEmpty().withMessage('Chief scientist name is required.'),

// // Chief scientist email Validation
// check('chief_scientist_email').exists().withMessage('Chief scientist email is required.')
// .trim()
// .normalizeEmail()
// .isEmail().withMessage('Chief scientist email must be a valid email address.')
// .bail(),

// // Override depth offset Validation
// check('override_depth_offset').optional()
// .isFloat().withMessage('Override depth offset must be a float value.'),

// // Enable descent filter Validation
// check('enable_descent_filter')
// .exists().withMessage('Enable descent filter is required.')
// .isBoolean().withMessage('Enable descent filter must be a boolean value.'),

// // Privacy duration Validation
// check('privacy_duration').default(2)
// .isInt({ min: 0 }).withMessage('Privacy duration must be a number and must be greater than 0.'),

// // Visible duration Validation
// check('visible_duration').default(24)
// .isInt({ min: 0 }).withMessage('Visible duration must be a number and must be greater than 0.'),

// // Public duration Validation
// check('public_duration').default(36)
// .isInt({ min: 0 }).withMessage('Public duration must be a number and must be greater than 0.'),

// // Instrument Validation
// check('instrument_model')
// .exists().withMessage('Instrument model is required.')
// .isString()
// .isIn(['UVP5HD', 'UVP5SD', 'UVP5Z', 'UVP6LP', 'UVP6HF', 'UVP6MHP', 'UVP6MHF'])
// .withMessage("Instrument model must be a string included in the following list of instrument models: ['UVP5HD', 'UVP5SD', 'UVP5Z', 'UVP6LP', 'UVP6HF', 'UVP6MHP', 'UVP6MHF']"),
// // Serial number Validation
// check('serial_number').optional()
// .trim()
// .not().isEmpty().withMessage('Serial number is required.'),
// // Sample contact Validation
// check('contact')
// .exists().withMessage('Contact is required.')
// .isObject().withMessage('Contact must be an object.')
// .bail()
// .custom((value: any) => {
// if (value.user_id === undefined) {
// throw new Error('Contact user_id is required.');
// }
// return true;
// }),
// // Sample members Validation
// check('members')
// .exists().withMessage('Members are required.')
// .isArray().withMessage('Members must be an array.')
// .bail()
// .custom((value: any) => {
// if (value.length > 0) {
// for (const member of value) {
// if (member.user_id === undefined) {
// throw new Error('Member user_id is required.');
// }
// }
// }
// return true;
// }),
// // Sample managers Validation
// check('managers')
// .exists().withMessage('Managers are required.')
// .isArray().withMessage('Managers must be an array.')
// .bail()
// .custom((value: any) => {
// if (value.length === 0) {
// throw new Error('At least one user must be a manager');
// }
// for (const manager of value) {
// if (manager.user_id === undefined) {
// throw new Error('Manager user_id is required.');
// }
// }
// return true;
// }),


// // Error Handling Middleware
// (req: Request, res: Response, next: NextFunction) => {
// const errors = validationResult(req);
// if (!errors.isEmpty()) {
// // Centralized error handling for validation errors
// return res.status(422).json({ errors: errors.array() });
// }
// next();
// },
// ];

// rulesSampleUpdateModel = [
// // Root Folder Path Validation
// check('root_folder_path').optional()
// .trim()
// .not().isEmpty().withMessage('Root Folder Path value cannot be empty.'),
// // Sample Title Validation
// check('sample_title').optional()
// .trim()
// .not().isEmpty().withMessage('Sample title cannot be empty.'),
// // Sample acrony Validation
// check('sample_acronym').optional()
// .trim()
// .not().isEmpty().withMessage('Sample acronym cannot be empty.'),
// // Sample description Validation
// check('sample_description').optional()
// .trim()
// .not().isEmpty().withMessage('Sample description cannot be empty.'),
// // Sample information Validation
// check('sample_information').optional()
// .trim()
// .not().isEmpty().withMessage('Sample information cannot be empty.'),

// // Sample cruise Validation
// check('cruise').optional()
// .trim()
// .not().isEmpty().withMessage('Cruise name cannot be empty.'),

// // Sample ship Validation
// check('ship').optional().trim()
// .not().isEmpty().withMessage('Ship name cannot be empty.'),

// // Data owner name Validation
// check('data_owner_name').optional()
// .trim()
// .not().isEmpty().withMessage('Data owner name cannot be empty.'),

// // Data owner email Validation
// check('data_owner_email').optional()
// .trim()
// .normalizeEmail()
// .isEmail().withMessage('Data owner email must be a valid email address.')
// .bail(),

// // Operator name Validation
// check('operator_name').optional()
// .trim(),
// // Operator email Validation
// check('operator_email').optional()
// .trim()
// .normalizeEmail()
// .isEmail().withMessage('Operator email must be a valid email address.')
// .bail(),

// // Chief scientist name Validation
// check('chief_scientist_name').optional()
// .trim()
// .not().isEmpty().withMessage('Chief scientist name cannot be empty.'),

// // Chief scientist email Validation
// check('chief_scientist_email').optional()
// .trim()
// .normalizeEmail()
// .isEmail().withMessage('Chief scientist email must be a valid email address.')
// .bail(),

// // Override depth offset Validation
// check('override_depth_offset').optional().optional()
// .isFloat().withMessage('Override depth offset must be a float value.'),

// // Enable descent filter Validation
// check('enable_descent_filter').optional()
// .isBoolean().withMessage('Enable descent filter must be a boolean value.'),

// // Privacy duration Validation
// check('privacy_duration').optional()
// .isInt({ min: 0 }).withMessage('Privacy duration must be a number and must be greater than 0.'),

// // Visible duration Validation
// check('visible_duration').optional()
// .isInt({ min: 0 }).withMessage('Visible duration must be a number and must be greater than 0.'),

// // Public duration Validation
// check('public_duration').optional()
// .isInt({ min: 0 }).withMessage('Public duration must be a number and must be greater than 0.'),

// // Instrument Validation
// check('instrument_model').optional()
// .isString()
// .isIn(['UVP5HD', 'UVP5SD', 'UVP5Z', 'UVP5Z', 'UVP6LP', 'UVP6HF', 'UVP6MHP', 'UVP6MHF'])
// .withMessage("Instrument model must be a string included in the following list of instrument models: ['UVP5HD', 'UVP5SD', 'UVP5Z', 'UVP6LP', 'UVP6HF', 'UVP6MHP', 'UVP6MHF']"),

// // Serial number Validation,
// check('serial_number').optional()
// .trim()
// .not().isEmpty().withMessage('Serial number cannot be empty.')
// ,
// // Sample Creation Date Validation
// check('user_creation_date')
// .isEmpty().withMessage('Sample creation date cannot be set manually.'),

// // Error Handling Middleware
// (req: Request, res: Response, next: NextFunction) => {
// const errors = validationResult(req);
// if (!errors.isEmpty()) {
// // Centralized error handling for validation errors
// return res.status(422).json({ errors: errors.array() });
// }
// next();
// },
// ]

rulesGetSamples = [
query('page').default(1)
.isInt({ min: 1 }).withMessage('Page must be a number and must be greater than 0.'),
Expand Down
21 changes: 21 additions & 0 deletions src/presentation/middleware/task-validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NextFunction, Request, Response } from 'express';
import { validationResult, query } from 'express-validator';
import { IMiddlewareTaskValidation } from '../interfaces/middleware/task-validation';

export class MiddlewareTaskValidation implements IMiddlewareTaskValidation {
rulesGetTasks = [
query('page').default(1)
.isInt({ min: 1 }).withMessage('Page must be a number and must be greater than 0.'),
query('limit').default(10)
.isInt({ min: 1 }).withMessage('Limit must be a number and must be greater than 0.'),
query('sort_by').default("asc(user_id)"),
(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
// Centralized error handling for validation errors
return res.status(422).json({ errors: errors.array() });
}
next();
},
];
}
4 changes: 0 additions & 4 deletions src/presentation/routers/auth-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ export default function AuthRouter(
})

router.get('/user/me', middlewareAuth.auth, async (req: Request, res: Response) => {

res.status(200).send((req as CustomRequest).token)

})

router.post('/refreshToken', middlewareAuth.auth_refresh, async (req: Request, res: Response) => {
Expand All @@ -74,14 +72,12 @@ export default function AuthRouter(
.clearCookie("refresh_token")
.status(200)
.json({ message: "You are Logged Out" });

})

/* PASSWORD MANAGEMENT */
// Change password
router.post('/password/change', middlewareAuthValidation.rulesPassword, middlewareAuth.auth, async (req: Request, res: Response) => {
try {

await changePasswordUseCase.execute((req as CustomRequest).token, req.body)
//TODO Unvalidate EXISTING TOKENS for the user?
//TODO logout user?
Expand Down
6 changes: 4 additions & 2 deletions src/presentation/routers/instrument_model-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import { Request, Response } from 'express'

import { GetOneInstrumentModelUseCase } from '../../domain/interfaces/use-cases/instrument_model/get-one-instrument_model'
import { SearchInstrumentModelsUseCase } from '../../domain/interfaces/use-cases/instrument_model/search-instrument_model'
import { IMiddlewareInstrumentModelValidation } from '../interfaces/middleware/instrument_model-validation'

export default function InstrumentModelsRouter(
// middlewareAuth: MiddlewareAuth,
getOneInstrumentModelsUseCase: GetOneInstrumentModelUseCase,
searchInstrumentModelsUseCase: SearchInstrumentModelsUseCase
searchInstrumentModelsUseCase: SearchInstrumentModelsUseCase,
middlewareInstrumentModelValidation: IMiddlewareInstrumentModelValidation
) {
const router = express.Router()

// Pagined and sorted list of all instrument_models
router.get('/', async (req: Request, res: Response) => {
router.get('/', middlewareInstrumentModelValidation.rulesGetInstrumentModels, async (req: Request, res: Response) => {
try {
const instrument_models = await searchInstrumentModelsUseCase.execute({ ...req.query } as any);
res.status(200).send(instrument_models)
Expand Down
Loading

0 comments on commit db61db1

Please sign in to comment.