backend: Update meet-room-options schema and validation to enforce roomIdPrefix length limit
This commit is contained in:
parent
817135433a
commit
20ef57b14c
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user