diff --git a/backend/openapi/components/requestBodies/update-room-config-request.yaml b/backend/openapi/components/requestBodies/update-room-config-request.yaml new file mode 100644 index 0000000..860b82b --- /dev/null +++ b/backend/openapi/components/requestBodies/update-room-config-request.yaml @@ -0,0 +1,16 @@ +description: New room config +content: + application/json: + schema: + type: object + properties: + config: + $ref: '../schemas/meet-room-config.yaml#/MeetRoomConfig' + example: + config: + chatConfig: + enabled: true + recordingConfig: + enabled: false + virtualBackgroundConfig: + enabled: true diff --git a/backend/openapi/components/requestBodies/update-room-preferences-request.yaml b/backend/openapi/components/requestBodies/update-room-preferences-request.yaml deleted file mode 100644 index 2da1ea1..0000000 --- a/backend/openapi/components/requestBodies/update-room-preferences-request.yaml +++ /dev/null @@ -1,16 +0,0 @@ -description: New room preferences -content: - application/json: - schema: - type: object - properties: - preferences: - $ref: '../schemas/meet-room-preferences.yaml#/MeetRoomPreferences' - example: - preferences: - chatPreferences: - enabled: true - recordingPreferences: - enabled: false - virtualBackgroundPreferences: - enabled: true diff --git a/backend/openapi/components/responses/success-get-room-config.yaml b/backend/openapi/components/responses/success-get-room-config.yaml new file mode 100644 index 0000000..eb206ea --- /dev/null +++ b/backend/openapi/components/responses/success-get-room-config.yaml @@ -0,0 +1,5 @@ +description: Success response for retrieving the room config +content: + application/json: + schema: + $ref: '../schemas/meet-room-config.yaml#/MeetRoomConfig' diff --git a/backend/openapi/components/responses/success-get-room-preferences.yaml b/backend/openapi/components/responses/success-get-room-preferences.yaml deleted file mode 100644 index 167c48c..0000000 --- a/backend/openapi/components/responses/success-get-room-preferences.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: Success response for retrieving the room preferences -content: - application/json: - schema: - $ref: '../schemas/meet-room-preferences.yaml#/MeetRoomPreferences' diff --git a/backend/openapi/components/responses/success-get-room.yaml b/backend/openapi/components/responses/success-get-room.yaml index 9ab724e..c11c272 100644 --- a/backend/openapi/components/responses/success-get-room.yaml +++ b/backend/openapi/components/responses/success-get-room.yaml @@ -14,12 +14,12 @@ content: autoDeletionPolicy: withMeeting: when_meeting_ends withRecordings: close - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' @@ -31,19 +31,19 @@ content: value: roomId: 'room-123' - fields=roomId,roomName,creationDate,autoDeletionDate,preferences: - summary: Room details with roomId, roomName, creationDate, autoDeletionDate, and preferences + fields=roomId,roomName,creationDate,autoDeletionDate,config: + summary: Room details with roomId, roomName, creationDate, autoDeletionDate, and config value: roomId: 'room-123' roomName: 'room' creationDate: 1620000000000 autoDeletionDate: 1900000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true fields=moderatorUrl,speakerUrl: diff --git a/backend/openapi/components/responses/success-get-rooms.yaml b/backend/openapi/components/responses/success-get-rooms.yaml index b16e55d..cae8982 100644 --- a/backend/openapi/components/responses/success-get-rooms.yaml +++ b/backend/openapi/components/responses/success-get-rooms.yaml @@ -23,12 +23,12 @@ content: autoDeletionPolicy: withMeeting: when_meeting_ends withRecordings: close - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' @@ -41,12 +41,12 @@ content: autoDeletionPolicy: withMeeting: when_meeting_ends withRecordings: close - preferences: - chatPreferences: + config: + chatConfig: enabled: false - recordingPreferences: + recordingConfig: enabled: true - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: false moderatorUrl: 'http://localhost:6080/room/room-456?secret=789012' speakerUrl: 'http://localhost:6080/room/room-456?secret=210987' @@ -65,31 +65,31 @@ content: isTruncated: false maxItems: 10 - fields=roomId,roomName,creationDate,autoDeletionDate,preferences: - summary: Room details including preferences but no URLs + fields=roomId,roomName,creationDate,autoDeletionDate,config: + summary: Room details including config but no URLs value: rooms: - roomId: 'room-123' roomName: 'room' creationDate: 1620000000000 autoDeletionDate: 1900000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true - roomId: 'room-456' roomName: 'room' creationDate: 1620001000000 autoDeletionDate: 1900000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: false - recordingPreferences: + recordingConfig: enabled: true - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: false pagination: isTruncated: true diff --git a/backend/openapi/components/responses/success-room-process-deletion.yaml b/backend/openapi/components/responses/success-room-process-deletion.yaml index 87b69b3..beba872 100644 --- a/backend/openapi/components/responses/success-room-process-deletion.yaml +++ b/backend/openapi/components/responses/success-room-process-deletion.yaml @@ -40,12 +40,12 @@ content: roomId: room-123 roomName: room creationDate: 1620000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' @@ -63,12 +63,12 @@ content: roomId: room-123 roomName: room creationDate: 1620000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' diff --git a/backend/openapi/components/responses/success-room-schedule-deletion.yaml b/backend/openapi/components/responses/success-room-schedule-deletion.yaml index 494a405..dd2550d 100644 --- a/backend/openapi/components/responses/success-room-schedule-deletion.yaml +++ b/backend/openapi/components/responses/success-room-schedule-deletion.yaml @@ -25,12 +25,12 @@ content: roomId: room-123 roomName: room creationDate: 1620000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' @@ -44,12 +44,12 @@ content: roomId: room-123 roomName: room creationDate: 1620000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' @@ -63,12 +63,12 @@ content: roomId: room-123 roomName: room creationDate: 1620000000000 - preferences: - chatPreferences: + config: + chatConfig: enabled: true - recordingPreferences: + recordingConfig: enabled: false - virtualBackgroundPreferences: + virtualBackgroundConfig: enabled: true moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456' speakerUrl: 'http://localhost:6080/room/room-123?secret=654321' diff --git a/backend/openapi/components/responses/success-update-room-preferences.yaml b/backend/openapi/components/responses/success-update-room-config.yaml similarity index 55% rename from backend/openapi/components/responses/success-update-room-preferences.yaml rename to backend/openapi/components/responses/success-update-room-config.yaml index 3b5305c..21f1e02 100644 --- a/backend/openapi/components/responses/success-update-room-preferences.yaml +++ b/backend/openapi/components/responses/success-update-room-config.yaml @@ -1,4 +1,4 @@ -description: Success response for updating room preferences +description: Success response for updating room config content: application/json: schema: @@ -7,4 +7,4 @@ content: message: type: string example: - message: Room preferences for room 'room-123' updated successfully + message: Room config for room 'room-123' updated successfully diff --git a/backend/openapi/components/schemas/meet-room-preferences.yaml b/backend/openapi/components/schemas/meet-room-config.yaml similarity index 70% rename from backend/openapi/components/schemas/meet-room-preferences.yaml rename to backend/openapi/components/schemas/meet-room-config.yaml index 5f77419..2e1d130 100644 --- a/backend/openapi/components/schemas/meet-room-preferences.yaml +++ b/backend/openapi/components/schemas/meet-room-config.yaml @@ -1,16 +1,16 @@ -MeetRoomPreferences: +MeetRoomConfig: type: object properties: - chatPreferences: - $ref: '#/MeetChatPreferences' - description: Preferences for the chat feature in the room. - recordingPreferences: - $ref: '#/MeetRecordingPreferences' - description: Preferences for recording the room. - virtualBackgroundPreferences: - $ref: '#/MeetVirtualBackgroundPreferences' - description: Preferences for virtual background in the room. -MeetChatPreferences: + chatConfig: + $ref: '#/MeetChatConfig' + description: Config for the chat feature in the room. + recordingConfig: + $ref: '#/MeetRecordingConfig' + description: Config for recording the room. + virtualBackgroundConfig: + $ref: '#/MeetVirtualBackgroundConfig' + description: Config for virtual background in the room. +MeetChatConfig: type: object properties: enabled: @@ -18,7 +18,7 @@ MeetChatPreferences: default: true example: true description: If true, the room will be allowed to send and receive chat messages. -MeetRecordingPreferences: +MeetRecordingConfig: type: object properties: enabled: @@ -39,7 +39,7 @@ MeetRecordingPreferences: - `admin`: Only administrators can access the recording. - `admin_moderator`: Administrators and moderators can access the recording. - `admin_moderator_speaker`: Administrators, moderators and speakers can access the recording. -MeetVirtualBackgroundPreferences: +MeetVirtualBackgroundConfig: type: object properties: enabled: diff --git a/backend/openapi/components/schemas/meet-room-options.yaml b/backend/openapi/components/schemas/meet-room-options.yaml index dd56198..0c0ac3e 100644 --- a/backend/openapi/components/schemas/meet-room-options.yaml +++ b/backend/openapi/components/schemas/meet-room-options.yaml @@ -54,7 +54,7 @@ properties: # description: > # The maximum number of participants allowed in the room. If the number of participants exceeds # this limit, new participants will not be allowed to join. - preferences: - $ref: './meet-room-preferences.yaml#/MeetRoomPreferences' + config: + $ref: './meet-room-config.yaml#/MeetRoomConfig' description: > - The preferences for the room. These preferences will be used to configure the room's settings. + The config for the room. These config will be used to configure the room's settings. diff --git a/backend/openapi/components/schemas/meet-room.yaml b/backend/openapi/components/schemas/meet-room.yaml index 66246ca..b5db64a 100644 --- a/backend/openapi/components/schemas/meet-room.yaml +++ b/backend/openapi/components/schemas/meet-room.yaml @@ -58,9 +58,9 @@ properties: Policy for automatic deletion when the room has recordings. Options are: - force: The room and its recordings will be deleted. - close: The room will be closed instead of deleted, maintaining its recordings. - preferences: - $ref: meet-room-preferences.yaml#/MeetRoomPreferences - description: The preferences for the room. + config: + $ref: meet-room-config.yaml#/MeetRoomConfig + description: The config for the room. # maxParticipants: # type: integer # example: 10 diff --git a/backend/openapi/openvidu-meet-api.yaml b/backend/openapi/openvidu-meet-api.yaml index 725d6e1..a111313 100644 --- a/backend/openapi/openvidu-meet-api.yaml +++ b/backend/openapi/openvidu-meet-api.yaml @@ -13,8 +13,8 @@ paths: $ref: './paths/rooms.yaml#/~1rooms' /rooms/{roomId}: $ref: './paths/rooms.yaml#/~1rooms~1{roomId}' - /rooms/{roomId}/preferences: - $ref: './paths/rooms.yaml#/~1rooms~1{roomId}~1preferences' + /rooms/{roomId}/config: + $ref: './paths/rooms.yaml#/~1rooms~1{roomId}~1config' /recordings: $ref: './paths/recordings.yaml#/~1recordings' /recordings/download: @@ -33,8 +33,8 @@ components: $ref: components/schemas/meet-room.yaml MeetRoomOptions: $ref: components/schemas/meet-room-options.yaml - MeetRoomPreferences: - $ref: './components/schemas/meet-room-preferences.yaml#/MeetRoomPreferences' + MeetRoomConfig: + $ref: './components/schemas/meet-room-config.yaml#/MeetRoomConfig' MeetRecording: $ref: components/schemas/meet-recording.yaml Error: diff --git a/backend/openapi/openvidu-meet-internal-api.yaml b/backend/openapi/openvidu-meet-internal-api.yaml index 107ea3c..bbf6e90 100644 --- a/backend/openapi/openvidu-meet-internal-api.yaml +++ b/backend/openapi/openvidu-meet-internal-api.yaml @@ -63,8 +63,8 @@ components: $ref: components/schemas/meet-room.yaml MeetRoomOptions: $ref: components/schemas/meet-room-options.yaml - MeetRoomPreferences: - $ref: components/schemas/meet-room-preferences.yaml#/MeetRoomPreferences + MeetRoomConfig: + $ref: components/schemas/meet-room-config.yaml#/MeetRoomConfig MeetRoomRoleAndPermissions: $ref: components/schemas/internal/meet-room-role-permissions.yaml MeetRecording: diff --git a/backend/openapi/paths/rooms.yaml b/backend/openapi/paths/rooms.yaml index 71eb4a2..8857c36 100644 --- a/backend/openapi/paths/rooms.yaml +++ b/backend/openapi/paths/rooms.yaml @@ -151,12 +151,12 @@ $ref: '../components/responses/validation-error.yaml' '500': $ref: '../components/responses/internal-server-error.yaml' -/rooms/{roomId}/preferences: +/rooms/{roomId}/config: get: - operationId: getRoomPreferences - summary: Get room preferences + operationId: getRoomConfig + summary: Get room config description: > - Retrieves the preferences of an OpenVidu Meet room with the specified room ID. + Retrieves the config of an OpenVidu Meet room with the specified room ID. tags: - OpenVidu Meet - Rooms security: @@ -168,7 +168,7 @@ - $ref: '../components/parameters/internal/x-participant-role.yaml' responses: '200': - $ref: '../components/responses/success-get-room-preferences.yaml' + $ref: '../components/responses/success-get-room-config.yaml' '400': $ref: '../components/responses/internal/error-invalid-participant-role.yaml' '401': @@ -182,10 +182,10 @@ '500': $ref: '../components/responses/internal-server-error.yaml' put: - operationId: updateRoomPreferences - summary: Update room preferences + operationId: updateRoomConfig + summary: Update room config description: > - Updates the preferences of an OpenVidu Meet room with the specified room ID. + Updates the config of an OpenVidu Meet room with the specified room ID. tags: - OpenVidu Meet - Rooms security: @@ -194,10 +194,10 @@ parameters: - $ref: '../components/parameters/room-id-path.yaml' requestBody: - $ref: '../components/requestBodies/update-room-preferences-request.yaml' + $ref: '../components/requestBodies/update-room-config-request.yaml' responses: '200': - $ref: '../components/responses/success-update-room-preferences.yaml' + $ref: '../components/responses/success-update-room-config.yaml' '401': $ref: '../components/responses/unauthorized-error.yaml' '403': diff --git a/backend/src/controllers/room.controller.ts b/backend/src/controllers/room.controller.ts index 217cb23..93e7d05 100644 --- a/backend/src/controllers/room.controller.ts +++ b/backend/src/controllers/room.controller.ts @@ -128,34 +128,34 @@ export const bulkDeleteRooms = async (req: Request, res: Response) => { } }; -export const getRoomPreferences = async (req: Request, res: Response) => { +export const getRoomConfig = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const roomService = container.get(RoomService); const { roomId } = req.params; - logger.verbose(`Getting room preferences for room '${roomId}'`); + logger.verbose(`Getting room config for room '${roomId}'`); try { - const { preferences } = await roomService.getMeetRoom(roomId); - return res.status(200).json(preferences); + const { config } = await roomService.getMeetRoom(roomId); + return res.status(200).json(config); } catch (error) { - handleError(res, error, `getting room preferences for room '${roomId}'`); + handleError(res, error, `getting room config for room '${roomId}'`); } }; -export const updateRoomPreferences = async (req: Request, res: Response) => { +export const updateRoomConfig = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const roomService = container.get(RoomService); - const { preferences } = req.body; + const { config } = req.body; const { roomId } = req.params; - logger.verbose(`Updating room preferences for room '${roomId}'`); + logger.verbose(`Updating room config for room '${roomId}'`); try { - await roomService.updateMeetRoomPreferences(roomId, preferences); - return res.status(200).json({ message: `Room preferences for room '${roomId}' updated successfully` }); + await roomService.updateMeetRoomConfig(roomId, config); + return res.status(200).json({ message: `Room config for room '${roomId}' updated successfully` }); } catch (error) { - handleError(res, error, `updating room preferences for room '${roomId}'`); + handleError(res, error, `updating room config for room '${roomId}'`); } }; diff --git a/backend/src/helpers/room.helper.ts b/backend/src/helpers/room.helper.ts index 6ec0dd1..32df839 100644 --- a/backend/src/helpers/room.helper.ts +++ b/backend/src/helpers/room.helper.ts @@ -17,7 +17,7 @@ export class MeetRoomHelper { roomName: room.roomName, autoDeletionDate: room.autoDeletionDate, autoDeletionPolicy: room.autoDeletionPolicy, - preferences: room.preferences + config: room.config // maxParticipants: room.maxParticipants }; } diff --git a/backend/src/middlewares/recording.middleware.ts b/backend/src/middlewares/recording.middleware.ts index 2449a3d..72d41c9 100644 --- a/backend/src/middlewares/recording.middleware.ts +++ b/backend/src/middlewares/recording.middleware.ts @@ -27,7 +27,7 @@ export const withRecordingEnabled = async (req: Request, res: Response, next: Ne const roomId = extractRoomIdFromRequest(req); const room: MeetRoom = await roomService.getMeetRoom(roomId!); - if (!room.preferences?.recordingPreferences?.enabled) { + if (!room.config?.recordingConfig?.enabled) { logger.debug(`Recording is disabled for room '${roomId}'`); const error = errorRecordingDisabled(roomId!); return rejectRequestFromMeetError(res, error); @@ -35,7 +35,7 @@ export const withRecordingEnabled = async (req: Request, res: Response, next: Ne return next(); } catch (error) { - handleError(res, error, 'checking recording preferences'); + handleError(res, error, 'checking recording config'); } }; diff --git a/backend/src/middlewares/request-validators/room-validator.middleware.ts b/backend/src/middlewares/request-validators/room-validator.middleware.ts index 900d6c3..e707608 100644 --- a/backend/src/middlewares/request-validators/room-validator.middleware.ts +++ b/backend/src/middlewares/request-validators/room-validator.middleware.ts @@ -1,15 +1,15 @@ import { - MeetChatPreferences, + MeetChatConfig, MeetRecordingAccess, - MeetRecordingPreferences, + MeetRecordingConfig, MeetRoomAutoDeletionPolicy, + MeetRoomConfig, MeetRoomDeletionPolicyWithMeeting, MeetRoomDeletionPolicyWithRecordings, MeetRoomFilters, MeetRoomOptions, - MeetRoomPreferences, MeetRoomStatus, - MeetVirtualBackgroundPreferences, + MeetVirtualBackgroundConfig, ParticipantRole, RecordingPermissions } from '@typings-ce'; @@ -65,7 +65,7 @@ const RecordingAccessSchema: z.ZodType = z.enum([ MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ]); -const RecordingPreferencesSchema: z.ZodType = z +const RecordingConfigSchema: z.ZodType = z .object({ enabled: z.boolean(), allowAccessTo: RecordingAccessSchema.optional() @@ -81,18 +81,18 @@ const RecordingPreferencesSchema: z.ZodType = z } ); -const ChatPreferencesSchema: z.ZodType = z.object({ +const ChatConfigSchema: z.ZodType = z.object({ enabled: z.boolean() }); -const VirtualBackgroundPreferencesSchema: z.ZodType = z.object({ +const VirtualBackgroundConfigSchema: z.ZodType = z.object({ enabled: z.boolean() }); -const RoomPreferencesSchema: z.ZodType = z.object({ - recordingPreferences: RecordingPreferencesSchema, - chatPreferences: ChatPreferencesSchema, - virtualBackgroundPreferences: VirtualBackgroundPreferencesSchema +const RoomConfigSchema: z.ZodType = z.object({ + recordingConfig: RecordingConfigSchema, + chatConfig: ChatConfigSchema, + virtualBackgroundConfig: VirtualBackgroundConfigSchema }); const RoomDeletionPolicyWithMeetingSchema: z.ZodType = z.enum([ @@ -150,10 +150,10 @@ const RoomRequestOptionsSchema: z.ZodType = z.object({ path: ['withRecordings'] } ), - preferences: RoomPreferencesSchema.optional().default({ - recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + config: RoomConfigSchema.optional().default({ + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }) // maxParticipants: z // .number() @@ -223,8 +223,8 @@ const BulkDeleteRoomsSchema = z.object({ withRecordings: RoomDeletionPolicyWithRecordingsSchema.optional().default(MeetRoomDeletionPolicyWithRecordings.FAIL) }); -const UpdateRoomPreferencesSchema = z.object({ - preferences: RoomPreferencesSchema +const UpdateRoomConfigSchema = z.object({ + config: RoomConfigSchema }); const UpdateRoomStatusSchema = z.object({ @@ -270,8 +270,8 @@ export const withValidRoomFiltersRequest = (req: Request, res: Response, next: N next(); }; -export const withValidRoomPreferences = (req: Request, res: Response, next: NextFunction) => { - const { success, error, data } = UpdateRoomPreferencesSchema.safeParse(req.body); +export const withValidRoomConfig = (req: Request, res: Response, next: NextFunction) => { + const { success, error, data } = UpdateRoomConfigSchema.safeParse(req.body); if (!success) { return rejectUnprocessableRequest(res, error); diff --git a/backend/src/middlewares/room.middleware.ts b/backend/src/middlewares/room.middleware.ts index ee24a3f..8991102 100644 --- a/backend/src/middlewares/room.middleware.ts +++ b/backend/src/middlewares/room.middleware.ts @@ -62,7 +62,7 @@ export const configureRecordingTokenAuth = async (req: Request, res: Response, n throw errorRoomMetadataNotFound(roomId); } - const recordingAccess = room.preferences!.recordingPreferences.allowAccessTo; + const recordingAccess = room.config!.recordingConfig.allowAccessTo; if (!recordingAccess || recordingAccess === MeetRecordingAccess.ADMIN) { // Deny request if the room is configured to allow access to recordings only for admins diff --git a/backend/src/routes/room.routes.ts b/backend/src/routes/room.routes.ts index 1ea3fd6..b0661fd 100644 --- a/backend/src/routes/room.routes.ts +++ b/backend/src/routes/room.routes.ts @@ -11,11 +11,11 @@ import { tokenAndRoleValidator, withAuth, withValidRoomBulkDeleteRequest, + withValidRoomConfig, withValidRoomDeleteRequest, withValidRoomFiltersRequest, withValidRoomId, withValidRoomOptions, - withValidRoomPreferences, withValidRoomSecret, withValidRoomStatus } from '../middlewares/index.js'; @@ -59,18 +59,18 @@ roomRouter.delete( ); roomRouter.get( - '/:roomId/preferences', + '/:roomId/config', withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN), participantTokenValidator), withValidRoomId, configureRoomAuthorization, - roomCtrl.getRoomPreferences + roomCtrl.getRoomConfig ); roomRouter.put( - '/:roomId/preferences', + '/:roomId/config', withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN)), withValidRoomId, - withValidRoomPreferences, - roomCtrl.updateRoomPreferences + withValidRoomConfig, + roomCtrl.updateRoomConfig ); roomRouter.put( diff --git a/backend/src/services/frontend-event.service.ts b/backend/src/services/frontend-event.service.ts index 413762e..6f8063d 100644 --- a/backend/src/services/frontend-event.service.ts +++ b/backend/src/services/frontend-event.service.ts @@ -1,14 +1,14 @@ -import { MeetRoom, MeetRecordingInfo, ParticipantRole } from '@typings-ce'; +import { MeetRecordingInfo, MeetRoom, ParticipantRole } from '@typings-ce'; import { inject, injectable } from 'inversify'; import { SendDataOptions } from 'livekit-server-sdk'; import { OpenViduComponentsAdapterHelper, OpenViduComponentsSignalPayload } from '../helpers/index.js'; -import { LiveKitService, LoggerService } from './index.js'; import { MeetParticipantRoleUpdatedPayload, - MeetRoomPreferencesUpdatedPayload, + MeetRoomConfigUpdatedPayload, MeetSignalPayload, MeetSignalType } from '../typings/ce/event.model.js'; +import { LiveKitService, LoggerService } from './index.js'; /** * Service responsible for all communication with the frontend @@ -67,25 +67,25 @@ export class FrontendEventService { } /** - * Sends a signal to notify participants in a room about updated room preferences. + * Sends a signal to notify participants in a room about updated room config. */ - async sendRoomPreferencesUpdatedSignal(roomId: string, updatedRoom: MeetRoom): Promise { - this.logger.debug(`Sending room preferences updated signal for room ${roomId}`); + async sendRoomConfigUpdatedSignal(roomId: string, updatedRoom: MeetRoom): Promise { + this.logger.debug(`Sending room config updated signal for room ${roomId}`); try { - const payload: MeetRoomPreferencesUpdatedPayload = { + const payload: MeetRoomConfigUpdatedPayload = { roomId, - preferences: updatedRoom.preferences!, + config: updatedRoom.config!, timestamp: Date.now() }; const options: SendDataOptions = { - topic: MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED + topic: MeetSignalType.MEET_ROOM_CONFIG_UPDATED }; await this.sendSignal(roomId, payload, options); } catch (error) { - this.logger.error(`Error sending room preferences updated signal for room ${roomId}:`, error); + this.logger.error(`Error sending room config updated signal for room ${roomId}:`, error); } } diff --git a/backend/src/services/room.service.ts b/backend/src/services/room.service.ts index a1c6e6d..287156b 100644 --- a/backend/src/services/room.service.ts +++ b/backend/src/services/room.service.ts @@ -2,13 +2,13 @@ import { MeetingEndAction, MeetRecordingAccess, MeetRoom, + MeetRoomConfig, MeetRoomDeletionErrorCode, MeetRoomDeletionPolicyWithMeeting, MeetRoomDeletionPolicyWithRecordings, MeetRoomDeletionSuccessCode, MeetRoomFilters, MeetRoomOptions, - MeetRoomPreferences, MeetRoomStatus, ParticipantRole, RecordingPermissions @@ -80,7 +80,7 @@ export class RoomService { * */ async createMeetRoom(baseUrl: string, roomOptions: MeetRoomOptions): Promise { - const { roomName, autoDeletionDate, autoDeletionPolicy, preferences } = roomOptions; + const { roomName, autoDeletionDate, autoDeletionPolicy, config } = roomOptions; const roomIdPrefix = roomName!.replace(/\s+/g, ''); // Remove all spaces const roomId = `${roomIdPrefix}-${uid(15)}`; // Generate a unique room ID based on the room name @@ -91,7 +91,7 @@ export class RoomService { // maxParticipants, autoDeletionDate, autoDeletionPolicy, - preferences: preferences!, + config: config!, moderatorUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`, speakerUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`, status: MeetRoomStatus.OPEN, @@ -135,21 +135,21 @@ export class RoomService { } /** - * Updates the preferences of a specific meeting room. + * Updates the config of a specific meeting room. * * @param roomId - The unique identifier of the meeting room to update - * @param preferences - The new preferences to apply to the meeting room + * @param config - The new config to apply to the meeting room * @returns A Promise that resolves to the updated MeetRoom object */ - async updateMeetRoomPreferences(roomId: string, preferences: MeetRoomPreferences): Promise { + async updateMeetRoomConfig(roomId: string, config: MeetRoomConfig): Promise { const room = await this.getMeetRoom(roomId); - room.preferences = preferences; + room.config = config; await this.storageService.saveMeetRoom(room); // Update the archived room metadata if it exists await Promise.all([ this.storageService.archiveRoomMetadata(roomId, true), - this.frontendEventService.sendRoomPreferencesUpdatedSignal(roomId, room) + this.frontendEventService.sendRoomConfigUpdatedSignal(roomId, room) ]); return room; } @@ -684,7 +684,7 @@ export class RoomService { } protected getRecordingPermissions(room: Partial, role: ParticipantRole): RecordingPermissions { - const recordingAccess = room.preferences!.recordingPreferences.allowAccessTo; + const recordingAccess = room.config!.recordingConfig.allowAccessTo; // A participant can delete recordings if they are a moderator and the recording access is not set to admin const canDeleteRecordings = role === ParticipantRole.MODERATOR && recordingAccess !== MeetRecordingAccess.ADMIN; diff --git a/backend/src/services/storage/storage.service.ts b/backend/src/services/storage/storage.service.ts index a0bee8f..bb26ba3 100644 --- a/backend/src/services/storage/storage.service.ts +++ b/backend/src/services/storage/storage.service.ts @@ -269,7 +269,7 @@ export class MeetStorageService< * Archives room metadata by storing essential room information in both cache and persistent storage. * * This method retrieves the room data, extracts key metadata (moderator/speaker URLs and - * recording preferences), and saves it to an archived location for future reference. + * recording config), and saves it to an archived location for future reference. * * If `updateOnlyIfExists` is true, it will only save the archived metadata if it already exists, * updating the existing entry. @@ -302,8 +302,8 @@ export class MeetStorageService< const archivedRoom: Partial = { moderatorUrl: room.moderatorUrl, speakerUrl: room.speakerUrl, - preferences: { - recordingPreferences: room.preferences?.recordingPreferences + config: { + recordingConfig: room.config?.recordingConfig } } as Partial; diff --git a/backend/tests/helpers/assertion-helpers.ts b/backend/tests/helpers/assertion-helpers.ts index 15b0065..158ab0b 100644 --- a/backend/tests/helpers/assertion-helpers.ts +++ b/backend/tests/helpers/assertion-helpers.ts @@ -9,9 +9,9 @@ import { MeetRecordingStatus, MeetRoom, MeetRoomAutoDeletionPolicy, + MeetRoomConfig, MeetRoomDeletionPolicyWithMeeting, MeetRoomDeletionPolicyWithRecordings, - MeetRoomPreferences, MeetRoomStatus, ParticipantPermissions, ParticipantRole @@ -93,22 +93,22 @@ export const expectSuccessRoomResponse = ( response: any, roomName: string, autoDeletionDate?: number, - preferences?: MeetRoomPreferences + config?: MeetRoomConfig ) => { expect(response.status).toBe(200); - expectValidRoom(response.body, roomName, preferences, autoDeletionDate); + expectValidRoom(response.body, roomName, config, autoDeletionDate); }; -export const expectSuccessRoomPreferencesResponse = (response: any, preferences: MeetRoomPreferences) => { +export const expectSuccessRoomConfigResponse = (response: any, config: MeetRoomConfig) => { expect(response.status).toBe(200); expect(response.body).toBeDefined(); - expect(response.body).toEqual(preferences); + expect(response.body).toEqual(config); }; export const expectValidRoom = ( room: MeetRoom, name: string, - preferences?: MeetRoomPreferences, + config?: MeetRoomConfig, autoDeletionDate?: number, autoDeletionPolicy?: MeetRoomAutoDeletionPolicy, status?: MeetRoomStatus, @@ -140,18 +140,18 @@ export const expectValidRoom = ( }); } - expect(room.preferences).toBeDefined(); + expect(room.config).toBeDefined(); - if (preferences !== undefined) { - expect(room.preferences).toEqual(preferences); + if (config !== undefined) { + expect(room.config).toEqual(config); } else { - expect(room.preferences).toEqual({ - recordingPreferences: { + expect(room.config).toEqual({ + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }); } diff --git a/backend/tests/helpers/request-helpers.ts b/backend/tests/helpers/request-helpers.ts index 02cf347..279922f 100644 --- a/backend/tests/helpers/request-helpers.ts +++ b/backend/tests/helpers/request-helpers.ts @@ -243,34 +243,34 @@ export const getRoom = async (roomId: string, fields?: string, cookie?: string, return await req; }; -export const getRoomPreferences = async (roomId: string) => { +export const getRoomConfig = async (roomId: string) => { checkAppIsRunning(); return await request(app) - .get(`${INTERNAL_CONFIG.API_BASE_PATH_V1}/rooms/${roomId}/preferences`) + .get(`${INTERNAL_CONFIG.API_BASE_PATH_V1}/rooms/${roomId}/config`) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY) .send(); }; -export const updateRoomPreferences = async (roomId: string, preferences: any) => { +export const updateRoomConfig = async (roomId: string, config: any) => { checkAppIsRunning(); return await request(app) - .put(`${INTERNAL_CONFIG.API_BASE_PATH_V1}/rooms/${roomId}/preferences`) + .put(`${INTERNAL_CONFIG.API_BASE_PATH_V1}/rooms/${roomId}/config`) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY) - .send({ preferences }); + .send({ config }); }; -export const updateRecordingAccessPreferencesInRoom = async (roomId: string, recordingAccess: MeetRecordingAccess) => { - const response = await updateRoomPreferences(roomId, { - recordingPreferences: { +export const updateRecordingAccessConfigInRoom = async (roomId: string, recordingAccess: MeetRecordingAccess) => { + const response = await updateRoomConfig(roomId, { + recordingConfig: { enabled: true, allowAccessTo: recordingAccess }, - chatPreferences: { + chatConfig: { enabled: true }, - virtualBackgroundPreferences: { + virtualBackgroundConfig: { enabled: true } }); @@ -297,11 +297,7 @@ export const deleteRoom = async (roomId: string, query: Record = {} return result; }; -export const bulkDeleteRooms = async ( - roomIds: any[], - withMeeting?: string, - withRecordings?: string -) => { +export const bulkDeleteRooms = async (roomIds: any[], withMeeting?: string, withRecordings?: string) => { checkAppIsRunning(); const result = await request(app) diff --git a/backend/tests/helpers/test-scenarios.ts b/backend/tests/helpers/test-scenarios.ts index da33cfe..a92af73 100644 --- a/backend/tests/helpers/test-scenarios.ts +++ b/backend/tests/helpers/test-scenarios.ts @@ -2,7 +2,7 @@ import express, { Request, Response } from 'express'; import http from 'http'; import { StringValue } from 'ms'; import { MeetRoomHelper } from '../../src/helpers'; -import { MeetRoom, MeetRoomPreferences } from '../../src/typings/ce'; +import { MeetRoom, MeetRoomConfig } from '../../src/typings/ce'; import { expectValidStartRecordingResponse } from './assertion-helpers'; import { createRoom, @@ -35,17 +35,17 @@ export interface TestContext { * * @param withParticipant Whether to join a fake participant in the room. * @param roomName Name of the room to create. - * @param preferences Optional room preferences. + * @param config Optional room config. * @returns Room data including secrets and cookies. */ export const setupSingleRoom = async ( withParticipant = false, roomName = 'TEST_ROOM', - preferences?: MeetRoomPreferences + config?: MeetRoomConfig ): Promise => { const room = await createRoom({ roomName, - preferences + config }); // Extract the room secrets and generate participant tokens, saved as cookies diff --git a/backend/tests/integration/api/recordings/start-recording.test.ts b/backend/tests/integration/api/recordings/start-recording.test.ts index 6922eaf..6cbe31d 100644 --- a/backend/tests/integration/api/recordings/start-recording.test.ts +++ b/backend/tests/integration/api/recordings/start-recording.test.ts @@ -73,7 +73,7 @@ describe('Recording API Tests', () => { expect(archivedRoom).toBeDefined(); expect(archivedRoom?.moderatorUrl).toBeDefined(); expect(archivedRoom?.speakerUrl).toBeDefined(); - expect(archivedRoom?.preferences).toBeDefined(); + expect(archivedRoom?.config).toBeDefined(); const secretsResponse = await stopRecording(recordingId, moderatorCookie); expectValidStopRecordingResponse(secretsResponse, recordingId, room.roomId, room.roomName); diff --git a/backend/tests/integration/api/rooms/create-room.test.ts b/backend/tests/integration/api/rooms/create-room.test.ts index 9fe29be..534e4c6 100644 --- a/backend/tests/integration/api/rooms/create-room.test.ts +++ b/backend/tests/integration/api/rooms/create-room.test.ts @@ -58,25 +58,19 @@ describe('Room API Tests', () => { withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE, withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE }, - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: false }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: false }, + virtualBackgroundConfig: { enabled: true } } }; const room = await createRoom(payload); - expectValidRoom( - room, - 'Example Room', - payload.preferences, - validAutoDeletionDate, - payload.autoDeletionPolicy - ); + expectValidRoom(room, 'Example Room', payload.config, validAutoDeletionDate, payload.autoDeletionPolicy); }); }); @@ -180,7 +174,9 @@ describe('Room API Tests', () => { const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); - expect(JSON.stringify(response.body.details)).toContain('FAIL policy is not allowed for withMeeting auto-deletion policy'); + expect(JSON.stringify(response.body.details)).toContain( + 'FAIL policy is not allowed for withMeeting auto-deletion policy' + ); }); it('should fail when autoDeletionPolicy.withRecordings has FAIL policy', async () => { @@ -195,7 +191,9 @@ describe('Room API Tests', () => { const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); - expect(JSON.stringify(response.body.details)).toContain('FAIL policy is not allowed for withRecordings auto-deletion policy'); + expect(JSON.stringify(response.body.details)).toContain( + 'FAIL policy is not allowed for withRecordings auto-deletion policy' + ); }); it('should fail when roomName is not a string (number provided)', async () => { @@ -220,11 +218,11 @@ describe('Room API Tests', () => { expect(JSON.stringify(response.body.details)).toContain('Expected string'); }); - it('should fail when preferences is not an object (string provided)', async () => { + it('should fail when config is not an object (string provided)', async () => { const payload = { roomName: 'TestRoom', autoDeletionDate: validAutoDeletionDate, - preferences: 'invalid-preferences' + config: 'invalid-config' }; const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422); @@ -232,19 +230,19 @@ describe('Room API Tests', () => { expect(JSON.stringify(response.body.details)).toContain('Expected object'); }); - it('should fail when preferences has an invalid structure', async () => { - // Assuming preferences expects each sub-property to be an object with a boolean "enabled", + it('should fail when config has an invalid structure', async () => { + // Assuming config expects each sub-property to be an object with a boolean "enabled", // here we deliberately use an invalid structure. const payload = { roomName: 'TestRoom', autoDeletionDate: validAutoDeletionDate, - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled: 'yes', // invalid boolean allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } } }; diff --git a/backend/tests/integration/api/rooms/generate-recording-token.test.ts b/backend/tests/integration/api/rooms/generate-recording-token.test.ts index 51bdcd4..769a947 100644 --- a/backend/tests/integration/api/rooms/generate-recording-token.test.ts +++ b/backend/tests/integration/api/rooms/generate-recording-token.test.ts @@ -1,6 +1,6 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; import { ParticipantRole } from '../../../../src/typings/ce/participant.js'; -import { MeetRecordingAccess } from '../../../../src/typings/ce/room-preferences.js'; +import { MeetRecordingAccess } from '../../../../src/typings/ce/room-config.js'; import { expectValidRecordingTokenResponse } from '../../../helpers/assertion-helpers.js'; import { deleteAllRecordings, @@ -9,7 +9,7 @@ import { disconnectFakeParticipants, generateRecordingToken, startTestServer, - updateRecordingAccessPreferencesInRoom + updateRecordingAccessConfigInRoom } from '../../../helpers/request-helpers.js'; import { RoomData, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js'; @@ -28,44 +28,35 @@ describe('Room API Tests', () => { describe('Generate Recording Token Tests', () => { it('should generate a recording token with canRetrieve and canDelete permissions when using the moderator secret and recording access is admin_moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret); expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true); }); it('should generate a recording token with canRetrieve and canDelete permissions when using the moderator secret and recording access is admin_moderator_speaker', async () => { - await updateRecordingAccessPreferencesInRoom( - roomData.room.roomId, - MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER - ); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER); const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret); expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true); }); it('should generate a recording token without any permissions when using the speaker secret and recording access is admin_moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret); expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, false, false); }); it('should generate a recording token with canRetrieve permission but not canDelete when using the speaker secret and recording access is admin_moderator_speaker', async () => { - await updateRecordingAccessPreferencesInRoom( - roomData.room.roomId, - MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER - ); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER); const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret); expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, true, false); }); it('should succeed even if the room is deleted', async () => { - await updateRecordingAccessPreferencesInRoom( - roomData.room.roomId, - MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER - ); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER); await deleteRoom(roomData.room.roomId); const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret); diff --git a/backend/tests/integration/api/rooms/get-room-preferences.test.ts b/backend/tests/integration/api/rooms/get-room-preferences.test.ts index 72b6eff..ddc0283 100644 --- a/backend/tests/integration/api/rooms/get-room-preferences.test.ts +++ b/backend/tests/integration/api/rooms/get-room-preferences.test.ts @@ -1,17 +1,17 @@ import { afterEach, beforeAll, describe, it } from '@jest/globals'; import { MeetRecordingAccess } from '../../../../src/typings/ce/index.js'; -import { expectSuccessRoomPreferencesResponse } from '../../../helpers/assertion-helpers.js'; -import { deleteAllRooms, getRoomPreferences, startTestServer } from '../../../helpers/request-helpers.js'; +import { expectSuccessRoomConfigResponse } from '../../../helpers/assertion-helpers.js'; +import { deleteAllRooms, getRoomConfig, startTestServer } from '../../../helpers/request-helpers.js'; import { setupSingleRoom } from '../../../helpers/test-scenarios.js'; describe('Room API Tests', () => { - const DEFAULT_PREFERENCES = { - recordingPreferences: { + const DEFAULT_CONFIG = { + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }; beforeAll(() => { @@ -23,33 +23,33 @@ describe('Room API Tests', () => { await deleteAllRooms(); }); - describe('Get Room Preferences Tests', () => { + describe('Get Room Config Tests', () => { it('should successfully retrieve a room by its ID', async () => { const roomData = await setupSingleRoom(); const roomId = roomData.room.roomId; - const response = await getRoomPreferences(roomId); - expectSuccessRoomPreferencesResponse(response, DEFAULT_PREFERENCES); + const response = await getRoomConfig(roomId); + expectSuccessRoomConfigResponse(response, DEFAULT_CONFIG); }); - it('should retrieve custom room preferences', async () => { + it('should retrieve custom room config', async () => { const payload = { roomName: 'custom-prefs', - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: false } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: false } } }; - const roomData = await setupSingleRoom(false, payload.roomName, payload.preferences); + const roomData = await setupSingleRoom(false, payload.roomName, payload.config); const roomId = roomData.room.roomId; - const response = await getRoomPreferences(roomId); - expectSuccessRoomPreferencesResponse(response, payload.preferences); + const response = await getRoomConfig(roomId); + expectSuccessRoomConfigResponse(response, payload.config); }); }); }); diff --git a/backend/tests/integration/api/rooms/get-room.test.ts b/backend/tests/integration/api/rooms/get-room.test.ts index 3aae58d..4602264 100644 --- a/backend/tests/integration/api/rooms/get-room.test.ts +++ b/backend/tests/integration/api/rooms/get-room.test.ts @@ -32,25 +32,25 @@ describe('Room API Tests', () => { expectSuccessRoomResponse(response, 'test-room'); }); - it('should retrieve a room with custom preferences', async () => { + it('should retrieve a room with custom config', async () => { const payload = { roomName: 'custom-prefs', - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: false } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: false } } }; - // Create a room with custom preferences + // Create a room with custom config const { roomId } = await createRoom(payload); // Retrieve the room by its ID const response = await getRoom(roomId); - expectSuccessRoomResponse(response, 'custom-prefs', undefined, payload.preferences); + expectSuccessRoomResponse(response, 'custom-prefs', undefined, payload.config); }); it('should retrieve only specified fields when using fields parameter', async () => { diff --git a/backend/tests/integration/api/rooms/update-room-preferences.test.ts b/backend/tests/integration/api/rooms/update-room-preferences.test.ts index 1af5840..2ea0635 100644 --- a/backend/tests/integration/api/rooms/update-room-preferences.test.ts +++ b/backend/tests/integration/api/rooms/update-room-preferences.test.ts @@ -1,15 +1,15 @@ import { afterEach, beforeAll, describe, expect, it, jest } from '@jest/globals'; +import { container } from '../../../../src/config/index.js'; +import { FrontendEventService } from '../../../../src/services/index.js'; +import { MeetSignalType } from '../../../../src/typings/ce/event.model.js'; import { MeetRecordingAccess } from '../../../../src/typings/ce/index.js'; import { createRoom, deleteAllRooms, getRoom, startTestServer, - updateRoomPreferences + updateRoomConfig } from '../../../helpers/request-helpers.js'; -import { FrontendEventService } from '../../../../src/services/index.js'; -import { container } from '../../../../src/config/index.js'; -import { MeetSignalType } from '../../../../src/typings/ce/event.model.js'; describe('Room API Tests', () => { beforeAll(() => { @@ -21,7 +21,7 @@ describe('Room API Tests', () => { await deleteAllRooms(); }); - describe('Update Room Preferences Tests', () => { + describe('Update Room Config Tests', () => { let frontendEventService: FrontendEventService; beforeAll(() => { @@ -29,41 +29,41 @@ describe('Room API Tests', () => { frontendEventService = container.get(FrontendEventService); }); - it('should successfully update room preferences', async () => { + it('should successfully update room config', async () => { const sendSignalSpy = jest.spyOn(frontendEventService as any, 'sendSignal'); const createdRoom = await createRoom({ roomName: 'update-test', - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } } }); - // Update the room preferences - const updatedPreferences = { - recordingPreferences: { + // Update the room config + const updatedConfig = { + recordingConfig: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN }, - chatPreferences: { enabled: false }, - virtualBackgroundPreferences: { enabled: false } + chatConfig: { enabled: false }, + virtualBackgroundConfig: { enabled: false } }; - const updateResponse = await updateRoomPreferences(createdRoom.roomId, updatedPreferences); + const updateResponse = await updateRoomConfig(createdRoom.roomId, updatedConfig); // Verify a method of frontend event service is called expect(sendSignalSpy).toHaveBeenCalledWith( createdRoom.roomId, { roomId: createdRoom.roomId, - preferences: updatedPreferences, + config: updatedConfig, timestamp: expect.any(Number) }, { - topic: MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED + topic: MeetSignalType.MEET_ROOM_CONFIG_UPDATED } ); @@ -74,33 +74,33 @@ describe('Room API Tests', () => { // Verify with a get request const getResponse = await getRoom(createdRoom.roomId); expect(getResponse.status).toBe(200); - expect(getResponse.body.preferences).toEqual(updatedPreferences); + expect(getResponse.body.config).toEqual(updatedConfig); }); it('should allow partial preference updates', async () => { - // Create a room first with all preferences enabled + // Create a room first with all config enabled const createdRoom = await createRoom({ roomName: 'partial-update', - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } } }); // Update only one preference - const partialPreferences = { - recordingPreferences: { + const partialConfig = { + recordingConfig: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }; - const updateResponse = await updateRoomPreferences(createdRoom.roomId, partialPreferences); + const updateResponse = await updateRoomConfig(createdRoom.roomId, partialConfig); // Verify update response expect(updateResponse.status).toBe(200); @@ -109,59 +109,59 @@ describe('Room API Tests', () => { // Verify with a get request const getResponse = await getRoom(createdRoom.roomId); expect(getResponse.status).toBe(200); - expect(getResponse.body.preferences).toEqual(partialPreferences); + expect(getResponse.body.config).toEqual(partialConfig); }); }); - describe('Update Room Preferences Validation failures', () => { - it('should fail when preferences have incorrect structure', async () => { + describe('Update Room Config Validation failures', () => { + it('should fail when config has incorrect structure', async () => { const { roomId } = await createRoom({ roomName: 'validation-test' }); - // Invalid preferences (missing required fields) - const invalidPreferences = { - recordingPreferences: { + // Invalid config (missing required fields) + const invalidConfig = { + recordingConfig: { enabled: false }, - // Missing chatPreferences - virtualBackgroundPreferences: { enabled: false } + // Missing chatConfig + virtualBackgroundConfig: { enabled: false } }; - const response = await updateRoomPreferences(roomId, invalidPreferences); + const response = await updateRoomConfig(roomId, invalidConfig); expect(response.status).toBe(422); expect(response.body.error).toContain('Unprocessable Entity'); - expect(JSON.stringify(response.body.details)).toContain('chatPreferences'); + expect(JSON.stringify(response.body.details)).toContain('chatConfig'); }); - it('should fail when preferences have incorrect types', async () => { + it('should fail when config has incorrect types', async () => { const createdRoom = await createRoom({ roomName: 'type-test' }); - // Invalid preferences (wrong types) - const invalidPreferences = { - recordingPreferences: { + // Invalid config (wrong types) + const invalidConfig = { + recordingConfig: { enabled: 'true', // String instead of boolean allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: false }, - virtualBackgroundPreferences: { enabled: false } + chatConfig: { enabled: false }, + virtualBackgroundConfig: { enabled: false } }; - const response = await updateRoomPreferences(createdRoom.roomId, invalidPreferences); + const response = await updateRoomConfig(createdRoom.roomId, invalidConfig); expect(response.status).toBe(422); expect(response.body.error).toContain('Unprocessable Entity'); - expect(JSON.stringify(response.body.details)).toContain('recordingPreferences.enabled'); + expect(JSON.stringify(response.body.details)).toContain('recordingConfig.enabled'); }); - it('should fail when preferences are missing required properties', async () => { + it('should fail when config is missing required properties', async () => { const createdRoom = await createRoom({ roomName: 'missing-props' }); - const emptyPreferences = {}; - const response = await updateRoomPreferences(createdRoom.roomId, emptyPreferences); + const emptyConfig = {}; + const response = await updateRoomConfig(createdRoom.roomId, emptyConfig); expect(response.status).toBe(422); expect(response.body.error).toContain('Unprocessable Entity'); @@ -172,32 +172,32 @@ describe('Room API Tests', () => { roomName: 'missing-access' }); - const invalidPreferences = { - recordingPreferences: { + const invalidConfig = { + recordingConfig: { enabled: true // Missing allowAccessTo }, - chatPreferences: { enabled: false }, - virtualBackgroundPreferences: { enabled: false } + chatConfig: { enabled: false }, + virtualBackgroundConfig: { enabled: false } }; - const response = await updateRoomPreferences(createdRoom.roomId, invalidPreferences); + const response = await updateRoomConfig(createdRoom.roomId, invalidConfig); expect(response.status).toBe(422); expect(response.body.error).toContain('Unprocessable Entity'); - expect(JSON.stringify(response.body.details)).toContain('recordingPreferences.allowAccessTo'); + expect(JSON.stringify(response.body.details)).toContain('recordingConfig.allowAccessTo'); }); it('should return 404 when updating non-existent room', async () => { const nonExistentRoomId = 'non-existent-room'; - const preferences = { - recordingPreferences: { + const config = { + recordingConfig: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: false }, - virtualBackgroundPreferences: { enabled: false } + chatConfig: { enabled: false }, + virtualBackgroundConfig: { enabled: false } }; - const response = await updateRoomPreferences(nonExistentRoomId, preferences); + const response = await updateRoomConfig(nonExistentRoomId, config); expect(response.status).toBe(404); expect(response.body.message).toContain(`'${nonExistentRoomId}' does not exist`); diff --git a/backend/tests/integration/api/security/recording-security.test.ts b/backend/tests/integration/api/security/recording-security.test.ts index dfd0dca..3e5373b 100644 --- a/backend/tests/integration/api/security/recording-security.test.ts +++ b/backend/tests/integration/api/security/recording-security.test.ts @@ -15,7 +15,7 @@ import { startTestServer, stopAllRecordings, stopRecording, - updateRecordingAccessPreferencesInRoom + updateRecordingAccessConfigInRoom } from '../../../helpers/request-helpers.js'; import { RoomData, setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js'; @@ -170,7 +170,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -184,7 +184,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -198,7 +198,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -209,7 +209,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret @@ -234,7 +234,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -250,7 +250,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -266,7 +266,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -279,7 +279,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret @@ -363,7 +363,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -379,7 +379,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -395,7 +395,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -408,7 +408,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret @@ -450,7 +450,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -467,7 +467,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -484,7 +484,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -498,7 +498,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret @@ -528,7 +528,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -544,7 +544,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -560,7 +560,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -573,7 +573,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret @@ -652,7 +652,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -668,7 +668,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -684,7 +684,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -697,7 +697,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret @@ -728,7 +728,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -745,7 +745,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom( + await updateRecordingAccessConfigInRoom( roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER ); @@ -762,7 +762,7 @@ describe('Recording API Security Tests', () => { }); it('should fail when recording access is admin_moderator and participant is speaker', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.speakerSecret @@ -776,7 +776,7 @@ describe('Recording API Security Tests', () => { }); it('should succeed when recording access is admin_moderator and participant is moderator', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR); const recordingCookie = await generateRecordingTokenCookie( roomData.room.roomId, roomData.moderatorSecret diff --git a/backend/tests/integration/api/security/room-security.test.ts b/backend/tests/integration/api/security/room-security.test.ts index e4cb62f..d46ba2e 100644 --- a/backend/tests/integration/api/security/room-security.test.ts +++ b/backend/tests/integration/api/security/room-security.test.ts @@ -12,7 +12,7 @@ import { disconnectFakeParticipants, loginUser, startTestServer, - updateRecordingAccessPreferencesInRoom + updateRecordingAccessConfigInRoom } from '../../../helpers/request-helpers.js'; import { RoomData, setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js'; @@ -179,7 +179,7 @@ describe('Room API Security Tests', () => { }); }); - describe('Get Room Preferences Tests', () => { + describe('Get Room Config Tests', () => { let roomData: RoomData; beforeAll(async () => { @@ -188,26 +188,26 @@ describe('Room API Security Tests', () => { it('should succeed when request includes API key', async () => { const response = await request(app) - .get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`) + .get(`${ROOMS_PATH}/${roomData.room.roomId}/config`) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY); expect(response.status).toBe(200); }); it('should succeed when user is authenticated as admin', async () => { const response = await request(app) - .get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`) + .get(`${ROOMS_PATH}/${roomData.room.roomId}/config`) .set('Cookie', adminCookie); expect(response.status).toBe(200); }); it('should fail when user is not authenticated', async () => { - const response = await request(app).get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`); + const response = await request(app).get(`${ROOMS_PATH}/${roomData.room.roomId}/config`); expect(response.status).toBe(401); }); it('should succeed when participant is moderator', async () => { const response = await request(app) - .get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`) + .get(`${ROOMS_PATH}/${roomData.room.roomId}/config`) .set('Cookie', roomData.moderatorCookie) .set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR); expect(response.status).toBe(200); @@ -217,7 +217,7 @@ describe('Room API Security Tests', () => { const newRoomData = await setupSingleRoom(); const response = await request(app) - .get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`) + .get(`${ROOMS_PATH}/${roomData.room.roomId}/config`) .set('Cookie', newRoomData.moderatorCookie) .set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR); expect(response.status).toBe(403); @@ -225,7 +225,7 @@ describe('Room API Security Tests', () => { it('should succeed when participant is speaker', async () => { const response = await request(app) - .get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`) + .get(`${ROOMS_PATH}/${roomData.room.roomId}/config`) .set('Cookie', roomData.speakerCookie) .set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER); expect(response.status).toBe(200); @@ -235,21 +235,21 @@ describe('Room API Security Tests', () => { const newRoomData = await setupSingleRoom(); const response = await request(app) - .get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`) + .get(`${ROOMS_PATH}/${roomData.room.roomId}/config`) .set('Cookie', newRoomData.speakerCookie) .set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER); expect(response.status).toBe(403); }); }); - describe('Update Room Preferences Tests', () => { - const roomPreferences = { - recordingPreferences: { + describe('Update Room Config Tests', () => { + const roomConfig = { + recordingConfig: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }; let roomId: string; @@ -261,24 +261,22 @@ describe('Room API Security Tests', () => { it('should succeed when request includes API key', async () => { const response = await request(app) - .put(`${ROOMS_PATH}/${roomId}/preferences`) + .put(`${ROOMS_PATH}/${roomId}/config`) .set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY) - .send({ preferences: roomPreferences }); + .send({ config: roomConfig }); expect(response.status).toBe(200); }); it('should succeed when user is authenticated as admin', async () => { const response = await request(app) - .put(`${ROOMS_PATH}/${roomId}/preferences`) + .put(`${ROOMS_PATH}/${roomId}/config`) .set('Cookie', adminCookie) - .send({ preferences: roomPreferences }); + .send({ config: roomConfig }); expect(response.status).toBe(200); }); it('should fail when user is not authenticated', async () => { - const response = await request(app) - .put(`${ROOMS_PATH}/${roomId}/preferences`) - .send({ preferences: roomPreferences }); + const response = await request(app).put(`${ROOMS_PATH}/${roomId}/config`).send({ config: roomConfig }); expect(response.status).toBe(401); }); }); @@ -308,9 +306,7 @@ describe('Room API Security Tests', () => { }); it('should fail when user is not authenticated', async () => { - const response = await request(app) - .put(`${ROOMS_PATH}/${roomId}/status`) - .send({ status: 'open' }); + const response = await request(app).put(`${ROOMS_PATH}/${roomId}/status`).send({ status: 'open' }); expect(response.status).toBe(401); }); }); @@ -323,10 +319,7 @@ describe('Room API Security Tests', () => { }); beforeEach(async () => { - await updateRecordingAccessPreferencesInRoom( - roomData.room.roomId, - MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER - ); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER); }); it('should succeed when no authentication is required and participant is speaker', async () => { @@ -414,7 +407,7 @@ describe('Room API Security Tests', () => { }); it('should fail when recording access is set to admin only', async () => { - await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN); + await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN); const response = await request(app) .post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`) diff --git a/frontend/projects/shared-meet-components/src/lib/components/rooms-lists/rooms-lists.component.scss b/frontend/projects/shared-meet-components/src/lib/components/rooms-lists/rooms-lists.component.scss index fdaf236..d8883dd 100644 --- a/frontend/projects/shared-meet-components/src/lib/components/rooms-lists/rooms-lists.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/components/rooms-lists/rooms-lists.component.scss @@ -212,12 +212,12 @@ .auto-deletion-expired { font-weight: var(--ov-meet-font-weight-semibold); - color: var(--ov-meet-color-error); + color: var(--ov-meet-color-error); - .deletion-icon { - color: var(--ov-meet-color-error); - } - } + .deletion-icon { + color: var(--ov-meet-color-error); + } + } } .no-data { @@ -240,7 +240,7 @@ color: var(--ov-meet-color-primary); } - &.room-preferences-btn { + &.room-config-btn { color: var(--ov-meet-icon-settings); } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html index f2ba9c9..cad976e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.html @@ -56,7 +56,7 @@ } @case ('recording') { - + } @case ('recordingTrigger') { @@ -64,8 +64,8 @@ @case ('recordingLayout') { } - @case ('preferences') { - + @case ('config') { + } } } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts index 7c4613a..de8d28e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.ts @@ -10,11 +10,11 @@ import { WizardNavigationConfig, WizardStep } from '@lib/models'; import { NavigationService, NotificationService, RoomService, RoomWizardStateService } from '@lib/services'; import { MeetRoomOptions } from '@lib/typings/ce'; import { RoomBasicCreationComponent } from '../room-basic-creation/room-basic-creation.component'; +import { RecordingConfigComponent } from './steps/recording-config/recording-config.component'; import { RecordingLayoutComponent } from './steps/recording-layout/recording-layout.component'; -import { RecordingPreferencesComponent } from './steps/recording-preferences/recording-preferences.component'; import { RecordingTriggerComponent } from './steps/recording-trigger/recording-trigger.component'; +import { RoomConfigComponent } from './steps/room-config/room-config.component'; import { RoomWizardRoomDetailsComponent } from './steps/room-details/room-details.component'; -import { RoomPreferencesComponent } from './steps/room-preferences/room-preferences.component'; @Component({ selector: 'ov-room-wizard', @@ -29,10 +29,10 @@ import { RoomPreferencesComponent } from './steps/room-preferences/room-preferen MatSlideToggleModule, RoomBasicCreationComponent, RoomWizardRoomDetailsComponent, - RecordingPreferencesComponent, + RecordingConfigComponent, RecordingTriggerComponent, RecordingLayoutComponent, - RoomPreferencesComponent + RoomConfigComponent ], templateUrl: './room-wizard.component.html', styleUrl: './room-wizard.component.scss' @@ -89,8 +89,8 @@ export class RoomWizardComponent implements OnInit { if (!this.roomId) return; try { - const { roomName, autoDeletionDate, preferences } = await this.roomService.getRoom(this.roomId); - this.existingRoomData = { roomName, autoDeletionDate, preferences }; + const { roomName, autoDeletionDate, config } = await this.roomService.getRoom(this.roomId); + this.existingRoomData = { roomName, autoDeletionDate, config }; if (this.existingRoomData) { this.isBasicCreation.set(false); } @@ -154,8 +154,8 @@ export class RoomWizardComponent implements OnInit { this.isCreatingRoom.set(true); try { - if (this.editMode && this.roomId && roomOptions.preferences) { - await this.roomService.updateRoomPreferences(this.roomId, roomOptions.preferences); + if (this.editMode && this.roomId && roomOptions.config) { + await this.roomService.updateRoomConfig(this.roomId, roomOptions.config); await this.navigationService.navigateTo('rooms', undefined, true); this.notificationService.showSnackbar('Room updated successfully'); } else { diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.html b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.html similarity index 94% rename from frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.html rename to frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.html index adc5f3f..e396233 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.html +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.html @@ -1,9 +1,9 @@ -
+
video_library
-

Recording Preferences

+

Recording Config

Choose whether to enable recording capabilities for this room

diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.scss similarity index 99% rename from frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.scss rename to frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.scss index 9bc33ff..0dfd389 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.scss @@ -1,6 +1,6 @@ @import '../../../../../../../../../../src/assets/styles/design-tokens'; -.recording-preferences-step { +.recording-config-step { @include ov-page-content; @include ov-container; @@ -50,7 +50,6 @@ padding: var(--ov-meet-spacing-lg) var(--ov-meet-spacing-lg) 0 var(--ov-meet-spacing-lg); overflow: hidden; - .access-header { display: flex; align-items: flex-start; diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.ts similarity index 93% rename from frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.ts rename to frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.ts index 98a9f6c..f53ae08 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-preferences/recording-preferences.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/recording-config/recording-config.component.ts @@ -18,7 +18,7 @@ interface RecordingAccessOption { } @Component({ - selector: 'ov-recording-preferences', + selector: 'ov-recording-config', standalone: true, imports: [ CommonModule, @@ -31,10 +31,10 @@ interface RecordingAccessOption { MatFormFieldModule, SelectableCardComponent ], - templateUrl: './recording-preferences.component.html', - styleUrl: './recording-preferences.component.scss' + templateUrl: './recording-config.component.html', + styleUrl: './recording-config.component.scss' }) -export class RecordingPreferencesComponent implements OnDestroy { +export class RecordingConfigComponent implements OnDestroy { recordingForm: FormGroup; isAnimatingOut = false; @@ -89,8 +89,8 @@ export class RecordingPreferencesComponent implements OnDestroy { const enabled = formValue.recordingEnabled === 'enabled'; const stepData: any = { - preferences: { - recordingPreferences: { + config: { + recordingConfig: { enabled, ...(enabled && { allowAccessTo: formValue.allowAccessTo }) } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.html b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.html similarity index 89% rename from frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.html rename to frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.html index 31e020a..33f3377 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.html +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.html @@ -1,18 +1,18 @@ -
+
video_chat
-

Room Preferences

+

Room Config

Configure additional features and functionality for your room

-
- -
+ + +
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.scss similarity index 95% rename from frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.scss rename to frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.scss index 032ac5b..354c9da 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.scss @@ -1,6 +1,6 @@ @import '../../../../../../../../../../src/assets/styles/design-tokens'; -.room-preferences-step { +.room-config-step { @include ov-page-content; @include ov-container; @@ -41,13 +41,13 @@ .step-content { margin-bottom: var(--ov-meet-spacing-md); - .preferences-form { + .config-form { display: flex; flex-direction: column; } } - .preferences-grid { + .config-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: var(--ov-meet-spacing-md); @@ -123,7 +123,7 @@ // Responsive design @media (max-width: 1024px) { - .room-preferences-step { + .room-config-step { // padding: var(--ov-meet-spacing-xs); .step-header { @@ -131,14 +131,14 @@ margin-bottom: var(--ov-meet-spacing-md); } - .preferences-grid { + .config-grid { gap: var(--ov-meet-spacing-sm); } } } @media (max-width: 768px) { - .room-preferences-step { + .room-config-step { .step-header { .step-title-group { .step-title { @@ -151,7 +151,7 @@ } } - .preferences-grid { + .config-grid { grid-template-columns: 1fr; } @@ -170,7 +170,7 @@ } @media (max-width: 480px) { - .room-preferences-step { + .room-config-step { .preference-card { .card-header { .icon-title-group { diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.ts similarity index 61% rename from frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.ts rename to frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.ts index db7bdb0..14276c0 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-preferences/room-preferences.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-config/room-config.component.ts @@ -7,22 +7,22 @@ import { RoomWizardStateService } from '@lib/services'; import { Subject, takeUntil } from 'rxjs'; @Component({ - selector: 'ov-room-preferences', + selector: 'ov-room-config', standalone: true, imports: [ReactiveFormsModule, MatCardModule, MatIconModule, MatSlideToggleModule], - templateUrl: './room-preferences.component.html', - styleUrl: './room-preferences.component.scss' + templateUrl: './room-config.component.html', + styleUrl: './room-config.component.scss' }) -export class RoomPreferencesComponent implements OnDestroy { - preferencesForm: FormGroup; +export class RoomConfigComponent implements OnDestroy { + configForm: FormGroup; private destroy$ = new Subject(); constructor(private wizardService: RoomWizardStateService) { const currentStep = this.wizardService.currentStep(); - this.preferencesForm = currentStep!.formGroup; + this.configForm = currentStep!.formGroup; - this.preferencesForm.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) => { + this.configForm.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) => { this.saveFormData(value); }); } @@ -34,34 +34,34 @@ export class RoomPreferencesComponent implements OnDestroy { private saveFormData(formValue: any): void { const stepData: any = { - preferences: { - chatPreferences: { + config: { + chatConfig: { enabled: formValue.chatEnabled }, - virtualBackgroundPreferences: { + virtualBackgroundConfig: { enabled: formValue.virtualBackgroundsEnabled } } }; - this.wizardService.updateStepData('preferences', stepData); + this.wizardService.updateStepData('config', stepData); } onChatToggleChange(event: any): void { const isEnabled = event.checked; - this.preferencesForm.patchValue({ chatEnabled: isEnabled }); + this.configForm.patchValue({ chatEnabled: isEnabled }); } onVirtualBackgroundToggleChange(event: any): void { const isEnabled = event.checked; - this.preferencesForm.patchValue({ virtualBackgroundsEnabled: isEnabled }); + this.configForm.patchValue({ virtualBackgroundsEnabled: isEnabled }); } get chatEnabled(): boolean { - return this.preferencesForm.value.chatEnabled || false; + return this.configForm.value.chatEnabled || false; } get virtualBackgroundsEnabled(): boolean { - return this.preferencesForm.value.virtualBackgroundsEnabled || false; + return this.configForm.value.virtualBackgroundsEnabled || false; } } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/rooms.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/rooms.component.ts index 8f4175c..4b53541 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/rooms.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/rooms.component.ts @@ -31,7 +31,7 @@ import { import { ILogger, LoggerService } from 'openvidu-components-angular'; @Component({ - selector: 'ov-room-preferences', + selector: 'ov-room-config', standalone: true, imports: [ MatListModule, @@ -109,7 +109,7 @@ export class RoomsComponent implements OnInit { this.openRoom(action.rooms[0]); break; case 'edit': - await this.editRoomPreferences(action.rooms[0]); + await this.editRoomConfig(action.rooms[0]); break; case 'copyModeratorLink': this.copyModeratorLink(action.rooms[0]); @@ -254,12 +254,12 @@ export class RoomsComponent implements OnInit { window.open(room.moderatorUrl, '_blank'); } - private async editRoomPreferences(room: MeetRoom) { + private async editRoomConfig(room: MeetRoom) { try { await this.navigationService.navigateTo(`rooms/${room.roomId}/edit`); } catch (error) { - this.notificationService.showSnackbar('Error navigating to room preferences'); - this.log.e('Error navigating to room preferences:', error); + this.notificationService.showSnackbar('Error navigating to room config'); + this.log.e('Error navigating to room config:', error); } } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts index ce60734..451393e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/meeting/meeting.component.ts @@ -39,7 +39,7 @@ import { } from '@lib/typings/ce'; import { MeetParticipantRoleUpdatedPayload, - MeetRoomPreferencesUpdatedPayload, + MeetRoomConfigUpdatedPayload, MeetSignalType } from '@lib/typings/ce/event.model'; import { @@ -270,7 +270,7 @@ export class MeetingComponent implements OnInit { try { await this.generateParticipantToken(); await this.addParticipantNameToUrl(); - await this.roomService.loadRoomPreferences(this.roomId); + await this.roomService.loadRoomConfig(this.roomId); this.showMeeting = true; // Subscribe to remote participants updates @@ -357,13 +357,13 @@ export class MeetingComponent implements OnInit { break; } - case MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED: { - // Update room preferences - const { preferences } = event as MeetRoomPreferencesUpdatedPayload; - this.featureConfService.setRoomPreferences(preferences); + case MeetSignalType.MEET_ROOM_CONFIG_UPDATED: { + // Update room config + const { config } = event as MeetRoomConfigUpdatedPayload; + this.featureConfService.setRoomConfig(config); // Refresh recording token if recording is enabled - if (preferences.recordingPreferences.enabled) { + if (config.recordingConfig.enabled) { try { await this.recordingService.generateRecordingToken(this.roomId, this.roomSecret); } catch (error) { diff --git a/frontend/projects/shared-meet-components/src/lib/services/feature-configuration.service.ts b/frontend/projects/shared-meet-components/src/lib/services/feature-configuration.service.ts index 2506766..f10bf30 100644 --- a/frontend/projects/shared-meet-components/src/lib/services/feature-configuration.service.ts +++ b/frontend/projects/shared-meet-components/src/lib/services/feature-configuration.service.ts @@ -1,6 +1,6 @@ import { computed, Injectable, signal } from '@angular/core'; import { - MeetRoomPreferences, + MeetRoomConfig, ParticipantPermissions, ParticipantRole, RecordingPermissions, @@ -57,7 +57,7 @@ const DEFAULT_FEATURES: ApplicationFeatures = { /** * Centralized service to manage feature configuration - * based on room preferences and participant permissions + * based on room config and participant permissions */ @Injectable({ providedIn: 'root' @@ -66,7 +66,7 @@ export class FeatureConfigurationService { protected log; // Signals to handle reactive - protected roomPreferences = signal(undefined); + protected roomConfig = signal(undefined); protected participantPermissions = signal(undefined); protected participantRole = signal(undefined); protected recordingPermissions = signal(undefined); @@ -74,7 +74,7 @@ export class FeatureConfigurationService { // Computed signal to derive features based on current configurations public readonly features = computed(() => this.calculateFeatures( - this.roomPreferences(), + this.roomConfig(), this.participantPermissions(), this.participantRole(), this.recordingPermissions() @@ -86,11 +86,11 @@ export class FeatureConfigurationService { } /** - * Updates room preferences + * Updates room config */ - setRoomPreferences(preferences: MeetRoomPreferences): void { - this.log.d('Updating room preferences', preferences); - this.roomPreferences.set(preferences); + setRoomConfig(config: MeetRoomConfig): void { + this.log.d('Updating room config', config); + this.roomConfig.set(config); } /** @@ -128,7 +128,7 @@ export class FeatureConfigurationService { * Core logic to calculate features based on all configurations */ protected calculateFeatures( - roomPrefs?: MeetRoomPreferences, + roomPrefs?: MeetRoomConfig, participantPerms?: ParticipantPermissions, role?: ParticipantRole, recordingPerms?: RecordingPermissions @@ -138,9 +138,9 @@ export class FeatureConfigurationService { // Apply room configurations if (roomPrefs) { - features.showRecordingPanel = roomPrefs.recordingPreferences.enabled; - features.showChat = roomPrefs.chatPreferences.enabled; - features.showBackgrounds = roomPrefs.virtualBackgroundPreferences.enabled; + features.showRecordingPanel = roomPrefs.recordingConfig.enabled; + features.showChat = roomPrefs.chatConfig.enabled; + features.showBackgrounds = roomPrefs.virtualBackgroundConfig.enabled; } // Apply participant permissions (these can restrict enabled features) @@ -184,7 +184,7 @@ export class FeatureConfigurationService { * Resets all configurations to their initial values */ reset(): void { - this.roomPreferences.set(undefined); + this.roomConfig.set(undefined); this.participantPermissions.set(undefined); this.participantRole.set(undefined); } diff --git a/frontend/projects/shared-meet-components/src/lib/services/room.service.ts b/frontend/projects/shared-meet-components/src/lib/services/room.service.ts index a5fe773..b4f2d0f 100644 --- a/frontend/projects/shared-meet-components/src/lib/services/room.service.ts +++ b/frontend/projects/shared-meet-components/src/lib/services/room.service.ts @@ -2,12 +2,12 @@ import { Injectable } from '@angular/core'; import { FeatureConfigurationService, HttpService, ParticipantService, SessionStorageService } from '@lib/services'; import { MeetRoom, + MeetRoomConfig, MeetRoomDeletionPolicyWithMeeting, MeetRoomDeletionPolicyWithRecordings, MeetRoomDeletionSuccessCode, MeetRoomFilters, MeetRoomOptions, - MeetRoomPreferences, MeetRoomRoleAndPermissions, MeetRoomStatus } from '@lib/typings/ce'; @@ -176,52 +176,52 @@ export class RoomService { } /** - * Retrieves the preferences for a specific room. + * Retrieves the config for a specific room. * * @param roomId - The unique identifier of the room - * @return A promise that resolves to the MeetRoomPreferences object + * @return A promise that resolves to the MeetRoomConfig object */ - async getRoomPreferences(roomId: string): Promise { - this.log.d('Fetching room preferences for roomId:', roomId); + async getRoomConfig(roomId: string): Promise { + this.log.d('Fetching room config for roomId:', roomId); try { - const path = `${this.ROOMS_API}/${roomId}/preferences`; + const path = `${this.ROOMS_API}/${roomId}/config`; const headers = this.participantService.getParticipantRoleHeader(); - const preferences = await this.httpService.getRequest(path, headers); - return preferences; + const config = await this.httpService.getRequest(path, headers); + return config; } catch (error) { - this.log.e('Error fetching room preferences', error); - throw new Error(`Failed to fetch room preferences for roomId: ${roomId}`); + this.log.e('Error fetching room config', error); + throw new Error(`Failed to fetch room config for roomId: ${roomId}`); } } /** - * Loads the room preferences and updates the feature configuration service. + * Loads the room config and updates the feature configuration service. * * @param roomId - The unique identifier of the room */ - async loadRoomPreferences(roomId: string): Promise { + async loadRoomConfig(roomId: string): Promise { try { - const preferences = await this.getRoomPreferences(roomId); - this.featureConfService.setRoomPreferences(preferences); - console.log('Room preferences loaded:', preferences); + const config = await this.getRoomConfig(roomId); + this.featureConfService.setRoomConfig(config); + console.log('Room config loaded:', config); } catch (error) { - this.log.e('Error loading room preferences', error); - throw new Error('Failed to load room preferences'); + this.log.e('Error loading room config', error); + throw new Error('Failed to load room config'); } } /** - * Saves new room preferences. + * Saves new room config. * * @param roomId - The unique identifier of the room - * @param preferences - The room preferences to be saved. - * @returns A promise that resolves when the preferences have been saved. + * @param config - The room config to be saved. + * @returns A promise that resolves when the config have been saved. */ - async updateRoomPreferences(roomId: string, preferences: MeetRoomPreferences): Promise { - this.log.d('Saving room preferences', preferences); - const path = `${this.ROOMS_API}/${roomId}/preferences`; - await this.httpService.putRequest(path, { preferences }); + async updateRoomConfig(roomId: string, config: MeetRoomConfig): Promise { + this.log.d('Saving room config', config); + const path = `${this.ROOMS_API}/${roomId}/config`; + await this.httpService.putRequest(path, { config }); } /** diff --git a/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts b/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts index 8fdab93..b52c284 100644 --- a/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts +++ b/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts @@ -3,20 +3,20 @@ import { AbstractControl, FormBuilder, ValidationErrors, Validators } from '@ang import { WizardNavigationConfig, WizardStep } from '@lib/models'; import { MeetRecordingAccess, + MeetRoomConfig, MeetRoomDeletionPolicyWithMeeting, MeetRoomDeletionPolicyWithRecordings, - MeetRoomOptions, - MeetRoomPreferences + MeetRoomOptions } from '@lib/typings/ce'; -// Default room preferences following the app's defaults -const DEFAULT_PREFERENCES: MeetRoomPreferences = { - recordingPreferences: { +// Default room config following the app's defaults +const DEFAULT_CONFIG: MeetRoomConfig = { + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }; /** @@ -32,7 +32,7 @@ export class RoomWizardStateService { private _visibleSteps = computed(() => this._steps().filter((step) => step.isVisible)); private _currentStepIndex = signal(0); private _roomOptions = signal({ - preferences: DEFAULT_PREFERENCES + config: DEFAULT_CONFIG }); public readonly steps = computed(() => this._steps()); @@ -60,9 +60,9 @@ export class RoomWizardStateService { // Initialize room options with defaults merged with existing data const initialRoomOptions: MeetRoomOptions = { ...existingData, - preferences: { - ...DEFAULT_PREFERENCES, - ...(existingData?.preferences || {}) + config: { + ...DEFAULT_CONFIG, + ...(existingData?.config || {}) } }; @@ -156,10 +156,8 @@ export class RoomWizardStateService { isActive: editMode, // Only active in edit mode isVisible: true, formGroup: this.formBuilder.group({ - recordingEnabled: initialRoomOptions.preferences!.recordingPreferences.enabled - ? 'enabled' - : 'disabled', - allowAccessTo: initialRoomOptions.preferences!.recordingPreferences.allowAccessTo + recordingEnabled: initialRoomOptions.config!.recordingConfig.enabled ? 'enabled' : 'disabled', + allowAccessTo: initialRoomOptions.config!.recordingConfig.allowAccessTo }) }, { @@ -183,14 +181,14 @@ export class RoomWizardStateService { }) }, { - id: 'preferences', + id: 'config', label: 'Room Features', isCompleted: editMode, // In edit mode, all editable steps are completed isActive: false, isVisible: true, formGroup: this.formBuilder.group({ - chatEnabled: initialRoomOptions.preferences!.chatPreferences.enabled, - virtualBackgroundsEnabled: initialRoomOptions.preferences!.virtualBackgroundPreferences.enabled + chatEnabled: initialRoomOptions.config!.chatConfig.enabled, + virtualBackgroundsEnabled: initialRoomOptions.config!.virtualBackgroundConfig.enabled }) } ]; @@ -234,13 +232,13 @@ export class RoomWizardStateService { case 'recording': updatedOptions = { ...currentOptions, - preferences: { - ...currentOptions.preferences, - recordingPreferences: { - ...currentOptions.preferences?.recordingPreferences, - ...stepData.preferences?.recordingPreferences + config: { + ...currentOptions.config, + recordingConfig: { + ...currentOptions.config?.recordingConfig, + ...stepData.config?.recordingConfig } - } as MeetRoomPreferences + } as MeetRoomConfig }; break; case 'recordingTrigger': @@ -248,24 +246,24 @@ export class RoomWizardStateService { // These steps don't update room options updatedOptions = { ...currentOptions }; break; - case 'preferences': + case 'config': updatedOptions = { ...currentOptions, - preferences: { - ...currentOptions.preferences, - chatPreferences: { - ...currentOptions.preferences?.chatPreferences, - ...stepData.preferences?.chatPreferences + config: { + ...currentOptions.config, + chatConfig: { + ...currentOptions.config?.chatConfig, + ...stepData.config?.chatConfig }, - virtualBackgroundPreferences: { - ...currentOptions.preferences?.virtualBackgroundPreferences, - ...stepData.preferences?.virtualBackgroundPreferences + virtualBackgroundConfig: { + ...currentOptions.config?.virtualBackgroundConfig, + ...stepData.config?.virtualBackgroundConfig }, - recordingPreferences: { - ...currentOptions.preferences?.recordingPreferences, - ...stepData.preferences?.recordingPreferences + recordingConfig: { + ...currentOptions.config?.recordingConfig, + ...stepData.config?.recordingConfig } - } as MeetRoomPreferences + } as MeetRoomConfig }; break; default: @@ -284,8 +282,8 @@ export class RoomWizardStateService { private updateStepsVisibility(): void { const currentSteps = this._steps(); const currentOptions = this._roomOptions(); - // TODO: Uncomment when recording preferences are implemented - const recordingEnabled = false; // currentOptions.preferences?.recordingPreferences.enabled ?? false; + // TODO: Uncomment when recording config is fully implemented + const recordingEnabled = false; // currentOptions.config?.recordingConfig.enabled ?? false; // Update recording steps visibility based on recordingEnabled const updatedSteps = currentSteps.map((step) => { @@ -414,7 +412,7 @@ export class RoomWizardStateService { */ resetWizard(): void { const defaultOptions: MeetRoomOptions = { - preferences: DEFAULT_PREFERENCES + config: DEFAULT_CONFIG }; this._roomOptions.set(defaultOptions); this._steps.set([]); diff --git a/frontend/webcomponent/package.json b/frontend/webcomponent/package.json index 51d5a4e..d94c988 100644 --- a/frontend/webcomponent/package.json +++ b/frontend/webcomponent/package.json @@ -11,7 +11,7 @@ "test:e2e-core-room": "playwright test tests/e2e/core/room.test.ts", "test:e2e-core-events": "playwright test tests/e2e/core/events.test.ts", "test:e2e-core-webhooks": "playwright test tests/e2e/core/webhooks.test.ts", - "test:e2e-ui-features": "playwright test tests/e2e/ui-feature-preferences.test.ts", + "test:e2e-ui-features": "playwright test tests/e2e/ui-feature-config.test.ts", "test:e2e-recording-access": "playwright test tests/e2e/recording-access.test.ts", "lint": "eslint 'src/**/*.ts'" }, diff --git a/frontend/webcomponent/tests/e2e/recording-access.test.ts b/frontend/webcomponent/tests/e2e/recording-access.test.ts index 8d22a2e..48f8bb8 100644 --- a/frontend/webcomponent/tests/e2e/recording-access.test.ts +++ b/frontend/webcomponent/tests/e2e/recording-access.test.ts @@ -1,5 +1,5 @@ import { test } from '@playwright/test'; -import { MeetRecordingAccess } from '../../../../typings/src/room-preferences'; +import { MeetRecordingAccess } from '../../../../typings/src/room-config'; import { MEET_TESTAPP_URL } from '../config'; import { accessRoomAs, @@ -11,7 +11,7 @@ import { loginAsAdmin, prepareForJoiningRoom, startStopRecording, - updateRoomPreferences, + updateRoomConfig, viewRecordingsAs, waitForElementInIframe } from '../helpers/function-helpers'; @@ -72,15 +72,15 @@ test.describe('Recording Access Tests', () => { }); test('should moderator not be able to access recording when access level is set to admin', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -93,15 +93,15 @@ test.describe('Recording Access Tests', () => { }); test('should speaker not be able to access recording when access level is set to admin', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -114,15 +114,15 @@ test.describe('Recording Access Tests', () => { }); test('should allow moderator to access recording when access level is set to moderator', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -135,15 +135,15 @@ test.describe('Recording Access Tests', () => { }); test('should speaker not be able to access recording when access level is set to moderator', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -156,15 +156,15 @@ test.describe('Recording Access Tests', () => { }); test('should allow moderators to access recording when access level is set to speaker', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -177,15 +177,15 @@ test.describe('Recording Access Tests', () => { }); test('should allow speaker to access recording when access level is set to speaker', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); diff --git a/frontend/webcomponent/tests/e2e/ui-feature-preferences.test.ts b/frontend/webcomponent/tests/e2e/ui-feature-config.test.ts similarity index 85% rename from frontend/webcomponent/tests/e2e/ui-feature-preferences.test.ts rename to frontend/webcomponent/tests/e2e/ui-feature-config.test.ts index bf3d09c..912fee0 100644 --- a/frontend/webcomponent/tests/e2e/ui-feature-preferences.test.ts +++ b/frontend/webcomponent/tests/e2e/ui-feature-config.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { MeetRecordingAccess } from '../../../../typings/src/room-preferences'; +import { MeetRecordingAccess } from '../../../../typings/src/room-config'; import { MEET_TESTAPP_URL } from '../config'; import { applyVirtualBackground, @@ -14,14 +14,14 @@ import { loginAsAdmin, openMoreOptionsMenu, prepareForJoiningRoom, - updateRoomPreferences, + updateRoomConfig, waitForElementInIframe, waitForVirtualBackgroundToApply } from '../helpers/function-helpers'; let subscribedToAppErrors = false; -test.describe('UI Feature Preferences Tests', () => { +test.describe('UI Feature Config Tests', () => { let roomId: string; let participantName: string; let adminCookie: string; @@ -73,15 +73,15 @@ test.describe('UI Feature Preferences Tests', () => { }); test('should show chat button when chat is enabled', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -97,15 +97,15 @@ test.describe('UI Feature Preferences Tests', () => { test('should hide chat button when chat is disabled', async ({ page }) => { // Disable chat via API - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: false }, - recordingPreferences: { + chatConfig: { enabled: false }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -126,15 +126,15 @@ test.describe('UI Feature Preferences Tests', () => { test.describe('Recording Feature', () => { test('should show recording button for moderators', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -160,15 +160,15 @@ test.describe('UI Feature Preferences Tests', () => { }); test('should not show recording button for speaker', async ({ page }) => { - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -185,15 +185,15 @@ test.describe('UI Feature Preferences Tests', () => { test('should not show recording button for moderators when recording is disabled', async ({ page }) => { // Disable recording via API - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -226,15 +226,15 @@ test.describe('UI Feature Preferences Tests', () => { }); test('should show virtual background button when enabled', async ({ page }) => { // Ensure virtual backgrounds are enabled - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -255,15 +255,15 @@ test.describe('UI Feature Preferences Tests', () => { test('should hide virtual background button when disabled', async ({ page }) => { // Disable virtual backgrounds via API - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: false } + virtualBackgroundConfig: { enabled: false } }, adminCookie ); @@ -284,15 +284,15 @@ test.describe('UI Feature Preferences Tests', () => { page }) => { // Ensure virtual backgrounds are enabled - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: true } + virtualBackgroundConfig: { enabled: true } }, adminCookie ); @@ -305,15 +305,15 @@ test.describe('UI Feature Preferences Tests', () => { await waitForVirtualBackgroundToApply(page); // Now disable virtual backgrounds - await updateRoomPreferences( + await updateRoomConfig( roomId, { - chatPreferences: { enabled: true }, - recordingPreferences: { + chatConfig: { enabled: true }, + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - virtualBackgroundPreferences: { enabled: false } + virtualBackgroundConfig: { enabled: false } }, adminCookie ); diff --git a/frontend/webcomponent/tests/helpers/function-helpers.ts b/frontend/webcomponent/tests/helpers/function-helpers.ts index 11ac8bc..516dc07 100644 --- a/frontend/webcomponent/tests/helpers/function-helpers.ts +++ b/frontend/webcomponent/tests/helpers/function-helpers.ts @@ -1,7 +1,7 @@ import { expect, FrameLocator, Locator, Page } from '@playwright/test'; import * as fs from 'fs'; import { PNG } from 'pngjs'; -import { MeetRecordingAccess, MeetRoomPreferences } from '../../../../typings/src/room-preferences'; +import { MeetRecordingAccess, MeetRoomConfig } from '../../../../typings/src/room-config'; import { MEET_ADMIN_PASSWORD, MEET_ADMIN_USER, MEET_API_KEY, MEET_API_URL, MEET_TESTAPP_URL } from '../config'; /** @@ -88,21 +88,18 @@ export async function interactWithElementInIframe( } } -// Helper function to get default room preferences -const getDefaultRoomPreferences = (): MeetRoomPreferences => ({ - recordingPreferences: { +// Helper function to get default room config +const getDefaultRoomConfig = (): MeetRoomConfig => ({ + recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, - chatPreferences: { enabled: true }, - virtualBackgroundPreferences: { enabled: true } + chatConfig: { enabled: true }, + virtualBackgroundConfig: { enabled: true } }); // Helper function to create a room for testing -export const createTestRoom = async ( - roomName: string, - preferences: MeetRoomPreferences = getDefaultRoomPreferences() -) => { +export const createTestRoom = async (roomName: string, config: MeetRoomConfig = getDefaultRoomConfig()) => { const response = await fetch(`${MEET_API_URL}/api/v1/rooms`, { method: 'POST', headers: { @@ -112,7 +109,7 @@ export const createTestRoom = async ( body: JSON.stringify({ roomName, autoDeletionDate: new Date(Date.now() + 61 * 60 * 1000).getTime(), // 1 hour from now - preferences + config }) }); @@ -126,19 +123,19 @@ export const createTestRoom = async ( return room.roomId; }; -// Helper function to update room preferences via REST API -export const updateRoomPreferences = async (roomId: string, preferences: any, adminCookie: string) => { - const response = await fetch(`${MEET_API_URL}/api/v1/rooms/${roomId}/preferences`, { +// Helper function to update room config via REST API +export const updateRoomConfig = async (roomId: string, config: any, adminCookie: string) => { + const response = await fetch(`${MEET_API_URL}/api/v1/rooms/${roomId}/config`, { method: 'PUT', headers: { 'Content-Type': 'application/json', Cookie: adminCookie }, - body: JSON.stringify({ preferences }) + body: JSON.stringify({ config }) }); if (!response.ok) { - throw new Error(`Failed to update room preferences: ${response.status} ${await response.text()}`); + throw new Error(`Failed to update room config: ${response.status} ${await response.text()}`); } return response.json(); diff --git a/testapp/public/css/home.css b/testapp/public/css/home.css index 8feb4b9..fc2800b 100644 --- a/testapp/public/css/home.css +++ b/testapp/public/css/home.css @@ -1,168 +1,168 @@ :root { - --primary-color: #4a90e2; - --secondary-color: #f4f4f4; + --primary-color: #4a90e2; + --secondary-color: #f4f4f4; } body, html { - height: 100vh; - width: 100%; - margin: 0; - background-color: #f8f9fa; - padding: 0px; - box-sizing: border-box; + height: 100vh; + width: 100%; + margin: 0; + background-color: #f8f9fa; + padding: 0px; + box-sizing: border-box; } .container { - width: 100%; - max-width: 1200px; - margin: 0 auto; - display: flex; - gap: 25px; - min-height: calc(80vh - 40px); - max-height: calc(80vh - 40px); - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); + width: 100%; + max-width: 1200px; + margin: 0 auto; + display: flex; + gap: 25px; + min-height: calc(80vh - 40px); + max-height: calc(80vh - 40px); + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } .action-buttons-container { - display: inline-flex; - gap: 2px; + display: inline-flex; + gap: 2px; } .rooms-container { - flex: 2; - background: white; - padding: 20px; - border-radius: 10px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); - display: flex; - flex-direction: column; - overflow: hidden; + flex: 2; + background: white; + padding: 20px; + border-radius: 10px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + overflow: hidden; } .create-room { - flex: 1; - background: var(--secondary-color); - padding: 15px; - border-radius: 10px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); - display: flex; - flex-direction: column; - overflow: hidden; + flex: 1; + background: var(--secondary-color); + padding: 15px; + border-radius: 10px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + overflow: hidden; } .create-room p, .create-room h2 { - margin-bottom: 0 !important ; - font-size: 0.9rem; + margin-bottom: 0 !important ; + font-size: 0.9rem; } .create-room h2 { - font-size: 1.1rem; /* Smaller title */ + font-size: 1.1rem; /* Smaller title */ } /* Collapsible sections for room creation form */ -.preferences-accordion { - flex: 1; - overflow-y: auto; +.config-accordion { + flex: 1; + overflow-y: auto; } .accordion-item { - border: none; - margin-bottom: 0.25rem; + border: none; + margin-bottom: 0.25rem; } .accordion-button { - background-color: var(--primary-color); - color: white; - border-radius: 0.25rem !important; /* Smaller radius */ - font-weight: 500; /* Less bold */ - font-size: 0.8rem; /* Smaller text */ - padding: 0.4rem 0.8rem; /* Much smaller padding */ - min-height: auto; /* Remove default height */ + background-color: var(--primary-color); + color: white; + border-radius: 0.25rem !important; /* Smaller radius */ + font-weight: 500; /* Less bold */ + font-size: 0.8rem; /* Smaller text */ + padding: 0.4rem 0.8rem; /* Much smaller padding */ + min-height: auto; /* Remove default height */ } .accordion-button:not(.collapsed) { - background-color: var(--primary-color); - color: white; - box-shadow: none; + background-color: var(--primary-color); + color: white; + box-shadow: none; } .accordion-button:focus { - box-shadow: 0 0 0 0.25rem rgba(74, 144, 226, 0.25); + box-shadow: 0 0 0 0.25rem rgba(74, 144, 226, 0.25); } .accordion-body { - padding: 0.5rem; /* Much smaller padding */ - background-color: #f8f9fa; - font-size: 0.8rem; /* Smaller text */ + padding: 0.5rem; /* Much smaller padding */ + background-color: #f8f9fa; + font-size: 0.8rem; /* Smaller text */ } form-label { - font-size: 0.8rem; /* Smaller labels */ - margin-bottom: 0.25rem; + font-size: 0.8rem; /* Smaller labels */ + margin-bottom: 0.25rem; } .form-control, .form-select { - font-size: 0.8rem; /* Smaller inputs */ - padding: 0.25rem 0.5rem; /* Smaller padding */ + font-size: 0.8rem; /* Smaller inputs */ + padding: 0.25rem 0.5rem; /* Smaller padding */ } .form-check { - margin-bottom: 0.25rem; /* Smaller spacing */ + margin-bottom: 0.25rem; /* Smaller spacing */ } .form-check-label { - font-size: 0.8rem; /* Smaller text */ + font-size: 0.8rem; /* Smaller text */ } .form-text { - font-size: 0.7rem !important; /* Much smaller help text */ - margin-top: 0.125rem; + font-size: 0.7rem !important; /* Much smaller help text */ + margin-top: 0.125rem; } #recording-access-section { - background-color: rgba(13, 110, 253, 0.1); - padding: 0.4rem; /* Smaller padding */ - border-radius: 0.25rem; - border-left: 2px solid var(--primary-color); /* Thinner border */ - margin-top: 0.25rem; + background-color: rgba(13, 110, 253, 0.1); + padding: 0.4rem; /* Smaller padding */ + border-radius: 0.25rem; + border-left: 2px solid var(--primary-color); /* Thinner border */ + margin-top: 0.25rem; } /* Compact button */ .create-room-btn { - font-size: 0.85rem; /* Smaller button text */ - padding: 0.4rem 0.8rem; /* Smaller button */ - margin-top: 0.5rem; /* Less top margin */ + font-size: 0.85rem; /* Smaller button text */ + padding: 0.4rem 0.8rem; /* Smaller button */ + margin-top: 0.5rem; /* Less top margin */ } /* Responsive adjustments */ @media (max-height: 600px) { - .container { - flex-direction: column; - max-height: none; - min-height: auto; - } + .container { + flex-direction: column; + max-height: none; + min-height: auto; + } - .create-room { - max-height: 350px; /* Smaller max height */ - } + .create-room { + max-height: 350px; /* Smaller max height */ + } } @media (max-width: 768px) { - .container { - flex-direction: column; - max-height: none; - gap: 15px; - } + .container { + flex-direction: column; + max-height: none; + gap: 15px; + } - body, - html { - padding: 10px; - } + body, + html { + padding: 10px; + } - .create-room { - padding: 10px; /* Even smaller on mobile */ - } + .create-room { + padding: 10px; /* Even smaller on mobile */ + } } diff --git a/testapp/public/views/index.mustache b/testapp/public/views/index.mustache index aa39d2b..8b009e3 100644 --- a/testapp/public/views/index.mustache +++ b/testapp/public/views/index.mustache @@ -181,10 +181,10 @@
- -
-
- + +
+
+

@@ -202,13 +202,13 @@
- +

@@ -240,13 +240,13 @@
Recording Access Level { try { @@ -38,12 +38,12 @@ export const postCreateRoom = async (req: Request, res: Response) => { try { console.log('Creating room with body:', JSON.stringify(req.body, null, 2)); const { roomName, autoDeletionDate } = req.body; - const preferences = processFormPreferences(req.body); + const config = processFormConfig(req.body); - console.log('Processed preferences:', JSON.stringify(preferences, null, 2)); + console.log('Processed config:', JSON.stringify(config, null, 2)); console.log('Room creation parameters:', { roomName, autoDeletionDate }); - const result = await createRoom({ roomName, autoDeletionDate, preferences }); + const result = await createRoom({ roomName, autoDeletionDate, config }); console.log('Room created successfully:', result); res.redirect('/'); } catch (error) { @@ -154,24 +154,24 @@ export const deleteAllRecordingsCtrl = async (_req: Request, res: Response) => { }; /** - * Converts flat form data to nested MeetRoomPreferences object + * Converts flat form data to nested MeetRoomConfig object */ -const processFormPreferences = (body: any): any => { - const preferences = { - chatPreferences: { - enabled: body['preferences.chatPreferences.enabled'] === 'on' +const processFormConfig = (body: any): any => { + const config = { + chatConfig: { + enabled: body['config.chatConfig.enabled'] === 'on' }, - recordingPreferences: { - enabled: body['preferences.recordingPreferences.enabled'] === 'on', + recordingConfig: { + enabled: body['config.recordingConfig.enabled'] === 'on', // Only include allowAccessTo if recording is enabled - ...(body['preferences.recordingPreferences.enabled'] === 'on' && { - allowAccessTo: body['preferences.recordingPreferences.allowAccessTo'] || 'admin_moderator_speaker' + ...(body['config.recordingConfig.enabled'] === 'on' && { + allowAccessTo: body['config.recordingConfig.allowAccessTo'] || 'admin_moderator_speaker' }) }, - virtualBackgroundPreferences: { - enabled: body['preferences.virtualBackgroundPreferences.enabled'] === 'on' + virtualBackgroundConfig: { + enabled: body['config.virtualBackgroundConfig.enabled'] === 'on' } }; - return preferences; + return config; }; diff --git a/typings/src/event.model.ts b/typings/src/event.model.ts index ec0e02b..e3c42fe 100644 --- a/typings/src/event.model.ts +++ b/typings/src/event.model.ts @@ -1,14 +1,14 @@ import { ParticipantRole } from './participant.js'; -import { MeetRoomPreferences } from './room-preferences.js'; +import { MeetRoomConfig } from './room-config.js'; export enum MeetSignalType { - MEET_ROOM_PREFERENCES_UPDATED = 'meet_room_preferences_updated', + MEET_ROOM_CONFIG_UPDATED = 'meet_room_config_updated', MEET_PARTICIPANT_ROLE_UPDATED = 'meet_participant_role_updated' } -export interface MeetRoomPreferencesUpdatedPayload { +export interface MeetRoomConfigUpdatedPayload { roomId: string; - preferences: MeetRoomPreferences; + config: MeetRoomConfig; timestamp: number; } @@ -20,4 +20,4 @@ export interface MeetParticipantRoleUpdatedPayload { timestamp: number; } -export type MeetSignalPayload = MeetRoomPreferencesUpdatedPayload | MeetParticipantRoleUpdatedPayload; +export type MeetSignalPayload = MeetRoomConfigUpdatedPayload | MeetParticipantRoleUpdatedPayload; diff --git a/typings/src/index.ts b/typings/src/index.ts index 127b6b4..13f4856 100644 --- a/typings/src/index.ts +++ b/typings/src/index.ts @@ -7,7 +7,7 @@ export * from './permissions/openvidu-permissions.js'; export * from './participant.js'; export * from './user.js'; -export * from './room-preferences.js'; +export * from './room-config.js'; export * from './room.js'; export * from './recording.model.js'; export * from './webhook.model.js'; diff --git a/typings/src/room-config.ts b/typings/src/room-config.ts new file mode 100644 index 0000000..eb05c9d --- /dev/null +++ b/typings/src/room-config.ts @@ -0,0 +1,30 @@ +/** + * Interface representing the config for a room. + */ +export interface MeetRoomConfig { + chatConfig: MeetChatConfig; + recordingConfig: MeetRecordingConfig; + virtualBackgroundConfig: MeetVirtualBackgroundConfig; +} + +/** + * Interface representing the config for recordings in a room. + */ +export interface MeetRecordingConfig { + enabled: boolean; + allowAccessTo?: MeetRecordingAccess; +} + +export const enum MeetRecordingAccess { + ADMIN = 'admin', // Only admins can access the recording + ADMIN_MODERATOR = 'admin_moderator', // Admins and moderators can access + ADMIN_MODERATOR_SPEAKER = 'admin_moderator_speaker' // Admins, moderators and speakers can access +} + +export interface MeetChatConfig { + enabled: boolean; +} + +export interface MeetVirtualBackgroundConfig { + enabled: boolean; +} diff --git a/typings/src/room-preferences.ts b/typings/src/room-preferences.ts deleted file mode 100644 index bcd8105..0000000 --- a/typings/src/room-preferences.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Interface representing the preferences for a room. - */ -export interface MeetRoomPreferences { - chatPreferences: MeetChatPreferences; - recordingPreferences: MeetRecordingPreferences; - virtualBackgroundPreferences: MeetVirtualBackgroundPreferences; -} - -/** - * Interface representing the preferences for recording. - */ -export interface MeetRecordingPreferences { - enabled: boolean; - allowAccessTo?: MeetRecordingAccess; -} - -export const enum MeetRecordingAccess { - ADMIN = 'admin', // Only admins can access the recording - ADMIN_MODERATOR = 'admin_moderator', // Admins and moderators can access - ADMIN_MODERATOR_SPEAKER = 'admin_moderator_speaker' // Admins, moderators and speakers can access -} - -export interface MeetChatPreferences { - enabled: boolean; -} - -export interface MeetVirtualBackgroundPreferences { - enabled: boolean; -} diff --git a/typings/src/room.ts b/typings/src/room.ts index 56eda02..9511dc5 100644 --- a/typings/src/room.ts +++ b/typings/src/room.ts @@ -1,11 +1,11 @@ import { ParticipantPermissions, ParticipantRole } from './participant.js'; -import { MeetRoomPreferences } from './room-preferences.js'; +import { MeetRoomConfig } from './room-config.js'; interface BaseRoomOptions { roomName?: string; autoDeletionDate?: number; autoDeletionPolicy?: MeetRoomAutoDeletionPolicy; - preferences?: MeetRoomPreferences; + config?: MeetRoomConfig; // maxParticipants?: number | null; } @@ -21,7 +21,7 @@ export interface MeetRoom extends BaseRoomOptions { roomId: string; roomName: string; creationDate: number; - preferences: MeetRoomPreferences; + config: MeetRoomConfig; moderatorUrl: string; speakerUrl: string; status: MeetRoomStatus;