backend: add request validation middleware for room members and users

This commit is contained in:
juancarmore 2025-12-05 15:24:02 +01:00
parent e0736677ca
commit 53ac60d37a
3 changed files with 131 additions and 11 deletions

View File

@ -0,0 +1,79 @@
import { MeetRoomMemberTokenMetadata } from '@openvidu-meet/typings';
import { NextFunction, Request, Response } from 'express';
import { rejectUnprocessableRequest } from '../../models/error.model.js';
import {
BulkDeleteRoomMembersReqSchema,
RoomMemberFiltersSchema,
RoomMemberOptionsSchema,
RoomMemberTokenMetadataSchema,
RoomMemberTokenOptionsSchema,
UpdateRoomMemberReqSchema
} from '../../models/zod-schemas/room-member.schema.js';
export const validateCreateRoomMemberReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = RoomMemberOptionsSchema.safeParse(req.body);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.body = data;
next();
};
export const validateGetRoomMembersReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = RoomMemberFiltersSchema.safeParse(req.query);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.query = {
...data,
maxItems: data.maxItems?.toString()
};
next();
};
export const validateBulkDeleteRoomMembersReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = BulkDeleteRoomMembersReqSchema.safeParse(req.query);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.query = data;
next();
};
export const validateUpdateRoomMemberReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = UpdateRoomMemberReqSchema.safeParse(req.body);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.body = data;
next();
};
export const validateCreateRoomMemberTokenReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = RoomMemberTokenOptionsSchema.safeParse(req.body);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.body = data;
next();
};
export const validateRoomMemberTokenMetadata = (metadata: unknown): MeetRoomMemberTokenMetadata => {
const { success, error, data } = RoomMemberTokenMetadataSchema.safeParse(metadata);
if (!success) {
throw new Error(`Invalid metadata: ${error.message}`);
}
return data;
};

View File

@ -1,15 +1,14 @@
import { MeetRoomMemberTokenMetadata } from '@openvidu-meet/typings';
import { NextFunction, Request, Response } from 'express';
import { rejectUnprocessableRequest } from '../../models/error.model.js';
import {
BulkDeleteRoomsReqSchema,
DeleteRoomReqSchema,
RoomFiltersSchema,
nonEmptySanitizedRoomId,
RoomMemberTokenMetadataSchema,
RoomMemberTokenOptionsSchema,
RoomFiltersSchema,
RoomOptionsSchema,
UpdateRoomAnonymousReqSchema,
UpdateRoomConfigReqSchema,
UpdateRoomRolesReqSchema,
UpdateRoomStatusReqSchema
} from '../../models/zod-schemas/room.schema.js';
@ -102,8 +101,8 @@ export const validateUpdateRoomStatusReq = (req: Request, res: Response, next: N
next();
};
export const validateCreateRoomMemberTokenReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = RoomMemberTokenOptionsSchema.safeParse(req.body);
export const validateUpdateRoomRolesReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = UpdateRoomRolesReqSchema.safeParse(req.body);
if (!success) {
return rejectUnprocessableRequest(res, error);
@ -113,12 +112,13 @@ export const validateCreateRoomMemberTokenReq = (req: Request, res: Response, ne
next();
};
export const validateRoomMemberTokenMetadata = (metadata: unknown): MeetRoomMemberTokenMetadata => {
const { success, error, data } = RoomMemberTokenMetadataSchema.safeParse(metadata);
export const validateUpdateRoomAnonymousReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = UpdateRoomAnonymousReqSchema.safeParse(req.body);
if (!success) {
throw new Error(`Invalid metadata: ${error.message}`);
return rejectUnprocessableRequest(res, error);
}
return data;
req.body = data;
next();
};

View File

@ -1,6 +1,47 @@
import { NextFunction, Request, Response } from 'express';
import { rejectUnprocessableRequest } from '../../models/error.model.js';
import { ChangePasswordReqSchema } from '../../models/zod-schemas/user.schema.js';
import {
BulkDeleteUsersReqSchema,
ChangePasswordReqSchema,
CreateUserReqSchema,
UserFiltersSchema
} from '../../models/zod-schemas/user.schema.js';
export const validateCreateUserReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = CreateUserReqSchema.safeParse(req.body);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.body = data;
next();
};
export const validateGetUsersReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = UserFiltersSchema.safeParse(req.query);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.query = {
...data,
maxItems: data.maxItems?.toString()
};
next();
};
export const validateBulkDeleteUsersReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = BulkDeleteUsersReqSchema.safeParse(req.query);
if (!success) {
return rejectUnprocessableRequest(res, error);
}
req.query = data;
next();
};
export const validateChangePasswordReq = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = ChangePasswordReqSchema.safeParse(req.body);