From ddbc80b0e31999854b7db7d630ca366b4e9bee2d Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Fri, 21 Mar 2025 17:26:14 +0100 Subject: [PATCH] backend: Refactor bulk delete recordings to accept recording IDs from query parameters and improve validation handling --- backend/src/controllers/recording.controller.ts | 7 ++++--- .../recording-validator.middleware.ts | 12 +++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/backend/src/controllers/recording.controller.ts b/backend/src/controllers/recording.controller.ts index d1d71bb..189d211 100644 --- a/backend/src/controllers/recording.controller.ts +++ b/backend/src/controllers/recording.controller.ts @@ -46,13 +46,14 @@ export const getRecordings = async (req: Request, res: Response) => { export const bulkDeleteRecordings = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); - const recordingIds = req.body.recordingIds; + const { recordingIds } = req.query; logger.info(`Deleting recordings: ${recordingIds}`); try { // TODO: Check role to determine if the request is from an admin or a participant - const { deleted, notDeleted } = await recordingService.bulkDeleteRecordings(recordingIds); + const recordingIdsArray = (recordingIds as string).split(','); + const { deleted, notDeleted } = await recordingService.bulkDeleteRecordings(recordingIdsArray); return res.status(200).json({ deleted, notDeleted }); } catch (error) { @@ -113,7 +114,7 @@ export const deleteRecording = async (req: Request, res: Response) => { try { // TODO: Check role to determine if the request is from an admin or a participant await recordingService.deleteRecording(recordingId); - return res.status(204); + return res.status(204).send(); } catch (error) { if (error instanceof OpenViduMeetError) { logger.error(`Error deleting recording: ${error.message}`); diff --git a/backend/src/middlewares/request-validators/recording-validator.middleware.ts b/backend/src/middlewares/request-validators/recording-validator.middleware.ts index e1449dc..04e170c 100644 --- a/backend/src/middlewares/request-validators/recording-validator.middleware.ts +++ b/backend/src/middlewares/request-validators/recording-validator.middleware.ts @@ -6,7 +6,7 @@ const sanitizeId = (val: string): string => { return val .trim() // Remove leading and trailing spaces .replace(/\s+/g, '-') // Replace spaces with hyphens - .replace(/[^a-zA-Z0-9-]/g, ''); // Remove special characters (only allow alphanumeric and hyphens) + .replace(/[^a-zA-Z0-9_-]/g, ''); // Remove special characters (allow alphanumeric, hyphens and underscores) }; const nonEmptySanitizedString = (fieldName: string) => @@ -30,8 +30,7 @@ export const BulkDeleteRecordingsSchema = z.object({ recordingIds: z.preprocess( (arg) => { if (typeof arg === 'string') { - // Si se recibe un string con valores separados por comas, - // se divide en array, eliminando espacios en blanco y valores vacĂ­os. + // If the argument is a string, it is expected to be a comma-separated list of recording IDs. return arg .split(',') .map((s) => s.trim()) @@ -41,6 +40,7 @@ export const BulkDeleteRecordingsSchema = z.object({ return arg; }, z.array(nonEmptySanitizedString('recordingId')) + .default([]) ) }); @@ -69,7 +69,7 @@ export const withValidStartRecordingRequest = (req: Request, res: Response, next }; export const withValidRecordingIdRequest = (req: Request, res: Response, next: NextFunction) => { - const { success, error, data } = GetRecordingSchema.safeParse(req.params.recordingId); + const { success, error, data } = GetRecordingSchema.safeParse({ recordingId: req.params.recordingId }); if (!success) { return rejectRequest(res, error); @@ -101,7 +101,7 @@ export const withValidRecordingBulkDeleteRequest = (req: Request, res: Response, return rejectRequest(res, error); } - req.query.recordingIds = data.recordingIds; + req.query.recordingIds = data.recordingIds.join(','); next(); }; @@ -112,8 +112,6 @@ const rejectRequest = (res: Response, error: z.ZodError) => { message: error.message })); - console.log(errors); - return res.status(422).json({ error: 'Unprocessable Entity', message: 'Invalid request body',