backend: Update meet-room-options schema and validation to enforce roomIdPrefix length limit

This commit is contained in:
Carlos Santos 2025-04-15 13:22:50 +02:00
parent 817135433a
commit 20ef57b14c
3 changed files with 23 additions and 8 deletions

View File

@ -8,7 +8,7 @@ properties:
After this date, the room will be automatically deleted and no new participants can join.
If this value is set and the date has already passed, the room is marked for deletion but will only be removed after the last
If this value is set and the date has already passed, the room is marked for deletion but will only be removed after the last
participant leaves ("graceful deletion").
If this value is not defined, the room will exist indefinitely until manually deleted.
@ -17,6 +17,7 @@ properties:
example: 'room'
description: >
A prefix to be used for the room ID. The room ID will be generated by concatenating this prefix with an unique identifier.
The maximum length of the room ID is 50 characters.
# maxParticipants:
# type: integer
# example: 10

View File

@ -18,7 +18,7 @@ import INTERNAL_CONFIG from '../../config/internal-config.js';
* @param val The string to sanitize
* @returns A sanitized string safe for use as an identifier
*/
const sanitizeId = (val: string): string => {
const sanitizeRoomId = (val: string): string => {
let transformed = val
.trim() // Remove leading/trailing spaces
.replace(/\s+/g, '') // Remove all spaces
@ -34,11 +34,12 @@ const sanitizeId = (val: string): string => {
return transformed;
};
const nonEmptySanitizedString = (fieldName: string) =>
export const nonEmptySanitizedRoomId = (fieldName: string) =>
z
.string()
.min(1, { message: `${fieldName} is required and cannot be empty` })
.transform(sanitizeId)
.max(100, { message: `${fieldName} cannot exceed 100 characters` })
.transform(sanitizeRoomId)
.refine((data) => data !== '', {
message: `${fieldName} cannot be empty after sanitization`
});
@ -83,7 +84,8 @@ const RoomRequestOptionsSchema: z.ZodType<MeetRoomOptions> = z.object({
.optional(),
roomIdPrefix: z
.string()
.transform(sanitizeId)
.max(50, 'roomIdPrefix cannot exceed 50 characters')
.transform(sanitizeRoomId)
.optional()
.default(''),
preferences: RoomPreferencesSchema.optional().default({
@ -135,7 +137,7 @@ const BulkDeleteRoomsSchema = z.object({
// Pre-sanitize to check for duplicates that would become identical
for (const id of roomIds) {
const transformed = sanitizeId(id);
const transformed = sanitizeRoomId(id);
// Only add non-empty IDs
if (transformed !== '') {
@ -190,7 +192,7 @@ export const withValidRoomPreferences = (req: Request, res: Response, next: Next
};
export const withValidRoomId = (req: Request, res: Response, next: NextFunction) => {
const { success, error, data } = nonEmptySanitizedString('roomId').safeParse(req.params.roomId);
const { success, error, data } = nonEmptySanitizedRoomId('roomId').safeParse(req.params.roomId);
if (!success) {
return rejectRequest(res, error);
@ -213,7 +215,7 @@ export const withValidRoomBulkDeleteRequest = (req: Request, res: Response, next
};
export const withValidRoomDeleteRequest = (req: Request, res: Response, next: NextFunction) => {
const roomIdResult = nonEmptySanitizedString('roomId').safeParse(req.params.roomId);
const roomIdResult = nonEmptySanitizedRoomId('roomId').safeParse(req.params.roomId);
if (!roomIdResult.success) {
return rejectRequest(res, roomIdResult.error);

View File

@ -215,5 +215,17 @@ describe('OpenVidu Meet Room API Tests', () => {
expect(response.body.error).toContain('Bad Request');
expect(response.body.message).toContain('Malformed Body');
});
it('should fail when roomIdPrefix is too long', async () => {
const longRoomId = 'a'.repeat(51);
const payload = {
roomIdPrefix: longRoomId,
autoDeletionDate: validAutoDeletionDate
};
const response = await request(app).post(ROOMS_PATH).set('Cookie', userCookie).send(payload).expect(422);
expect(JSON.stringify(response.body.details)).toContain('roomIdPrefix cannot exceed 50 characters');
});
});
});