Rename room preferences to room config
This commit is contained in:
parent
686af46102
commit
40742d22f8
@ -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
|
||||||
@ -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
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
description: Success response for retrieving the room config
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '../schemas/meet-room-config.yaml#/MeetRoomConfig'
|
||||||
@ -1,5 +0,0 @@
|
|||||||
description: Success response for retrieving the room preferences
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '../schemas/meet-room-preferences.yaml#/MeetRoomPreferences'
|
|
||||||
@ -14,12 +14,12 @@ content:
|
|||||||
autoDeletionPolicy:
|
autoDeletionPolicy:
|
||||||
withMeeting: when_meeting_ends
|
withMeeting: when_meeting_ends
|
||||||
withRecordings: close
|
withRecordings: close
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
@ -31,19 +31,19 @@ content:
|
|||||||
value:
|
value:
|
||||||
roomId: 'room-123'
|
roomId: 'room-123'
|
||||||
|
|
||||||
fields=roomId,roomName,creationDate,autoDeletionDate,preferences:
|
fields=roomId,roomName,creationDate,autoDeletionDate,config:
|
||||||
summary: Room details with roomId, roomName, creationDate, autoDeletionDate, and preferences
|
summary: Room details with roomId, roomName, creationDate, autoDeletionDate, and config
|
||||||
value:
|
value:
|
||||||
roomId: 'room-123'
|
roomId: 'room-123'
|
||||||
roomName: 'room'
|
roomName: 'room'
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
autoDeletionDate: 1900000000000
|
autoDeletionDate: 1900000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
fields=moderatorUrl,speakerUrl:
|
fields=moderatorUrl,speakerUrl:
|
||||||
|
|||||||
@ -23,12 +23,12 @@ content:
|
|||||||
autoDeletionPolicy:
|
autoDeletionPolicy:
|
||||||
withMeeting: when_meeting_ends
|
withMeeting: when_meeting_ends
|
||||||
withRecordings: close
|
withRecordings: close
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
@ -41,12 +41,12 @@ content:
|
|||||||
autoDeletionPolicy:
|
autoDeletionPolicy:
|
||||||
withMeeting: when_meeting_ends
|
withMeeting: when_meeting_ends
|
||||||
withRecordings: close
|
withRecordings: close
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-456?secret=789012'
|
moderatorUrl: 'http://localhost:6080/room/room-456?secret=789012'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-456?secret=210987'
|
speakerUrl: 'http://localhost:6080/room/room-456?secret=210987'
|
||||||
@ -65,31 +65,31 @@ content:
|
|||||||
isTruncated: false
|
isTruncated: false
|
||||||
maxItems: 10
|
maxItems: 10
|
||||||
|
|
||||||
fields=roomId,roomName,creationDate,autoDeletionDate,preferences:
|
fields=roomId,roomName,creationDate,autoDeletionDate,config:
|
||||||
summary: Room details including preferences but no URLs
|
summary: Room details including config but no URLs
|
||||||
value:
|
value:
|
||||||
rooms:
|
rooms:
|
||||||
- roomId: 'room-123'
|
- roomId: 'room-123'
|
||||||
roomName: 'room'
|
roomName: 'room'
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
autoDeletionDate: 1900000000000
|
autoDeletionDate: 1900000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
- roomId: 'room-456'
|
- roomId: 'room-456'
|
||||||
roomName: 'room'
|
roomName: 'room'
|
||||||
creationDate: 1620001000000
|
creationDate: 1620001000000
|
||||||
autoDeletionDate: 1900000000000
|
autoDeletionDate: 1900000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
pagination:
|
pagination:
|
||||||
isTruncated: true
|
isTruncated: true
|
||||||
|
|||||||
@ -40,12 +40,12 @@ content:
|
|||||||
roomId: room-123
|
roomId: room-123
|
||||||
roomName: room
|
roomName: room
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
@ -63,12 +63,12 @@ content:
|
|||||||
roomId: room-123
|
roomId: room-123
|
||||||
roomName: room
|
roomName: room
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
|
|||||||
@ -25,12 +25,12 @@ content:
|
|||||||
roomId: room-123
|
roomId: room-123
|
||||||
roomName: room
|
roomName: room
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
@ -44,12 +44,12 @@ content:
|
|||||||
roomId: room-123
|
roomId: room-123
|
||||||
roomName: room
|
roomName: room
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
@ -63,12 +63,12 @@ content:
|
|||||||
roomId: room-123
|
roomId: room-123
|
||||||
roomName: room
|
roomName: room
|
||||||
creationDate: 1620000000000
|
creationDate: 1620000000000
|
||||||
preferences:
|
config:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
description: Success response for updating room preferences
|
description: Success response for updating room config
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
@ -7,4 +7,4 @@ content:
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
example:
|
example:
|
||||||
message: Room preferences for room 'room-123' updated successfully
|
message: Room config for room 'room-123' updated successfully
|
||||||
@ -1,16 +1,16 @@
|
|||||||
MeetRoomPreferences:
|
MeetRoomConfig:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
chatPreferences:
|
chatConfig:
|
||||||
$ref: '#/MeetChatPreferences'
|
$ref: '#/MeetChatConfig'
|
||||||
description: Preferences for the chat feature in the room.
|
description: Config for the chat feature in the room.
|
||||||
recordingPreferences:
|
recordingConfig:
|
||||||
$ref: '#/MeetRecordingPreferences'
|
$ref: '#/MeetRecordingConfig'
|
||||||
description: Preferences for recording the room.
|
description: Config for recording the room.
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundConfig:
|
||||||
$ref: '#/MeetVirtualBackgroundPreferences'
|
$ref: '#/MeetVirtualBackgroundConfig'
|
||||||
description: Preferences for virtual background in the room.
|
description: Config for virtual background in the room.
|
||||||
MeetChatPreferences:
|
MeetChatConfig:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
enabled:
|
enabled:
|
||||||
@ -18,7 +18,7 @@ MeetChatPreferences:
|
|||||||
default: true
|
default: true
|
||||||
example: true
|
example: true
|
||||||
description: If true, the room will be allowed to send and receive chat messages.
|
description: If true, the room will be allowed to send and receive chat messages.
|
||||||
MeetRecordingPreferences:
|
MeetRecordingConfig:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
enabled:
|
enabled:
|
||||||
@ -39,7 +39,7 @@ MeetRecordingPreferences:
|
|||||||
- `admin`: Only administrators can access the recording.
|
- `admin`: Only administrators can access the recording.
|
||||||
- `admin_moderator`: Administrators and moderators can access the recording.
|
- `admin_moderator`: Administrators and moderators can access the recording.
|
||||||
- `admin_moderator_speaker`: Administrators, moderators and speakers can access the recording.
|
- `admin_moderator_speaker`: Administrators, moderators and speakers can access the recording.
|
||||||
MeetVirtualBackgroundPreferences:
|
MeetVirtualBackgroundConfig:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
enabled:
|
enabled:
|
||||||
@ -54,7 +54,7 @@ properties:
|
|||||||
# description: >
|
# description: >
|
||||||
# The maximum number of participants allowed in the room. If the number of participants exceeds
|
# 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.
|
# this limit, new participants will not be allowed to join.
|
||||||
preferences:
|
config:
|
||||||
$ref: './meet-room-preferences.yaml#/MeetRoomPreferences'
|
$ref: './meet-room-config.yaml#/MeetRoomConfig'
|
||||||
description: >
|
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.
|
||||||
|
|||||||
@ -58,9 +58,9 @@ properties:
|
|||||||
Policy for automatic deletion when the room has recordings. Options are:
|
Policy for automatic deletion when the room has recordings. Options are:
|
||||||
- force: The room and its recordings will be deleted.
|
- force: The room and its recordings will be deleted.
|
||||||
- close: The room will be closed instead of deleted, maintaining its recordings.
|
- close: The room will be closed instead of deleted, maintaining its recordings.
|
||||||
preferences:
|
config:
|
||||||
$ref: meet-room-preferences.yaml#/MeetRoomPreferences
|
$ref: meet-room-config.yaml#/MeetRoomConfig
|
||||||
description: The preferences for the room.
|
description: The config for the room.
|
||||||
# maxParticipants:
|
# maxParticipants:
|
||||||
# type: integer
|
# type: integer
|
||||||
# example: 10
|
# example: 10
|
||||||
|
|||||||
@ -13,8 +13,8 @@ paths:
|
|||||||
$ref: './paths/rooms.yaml#/~1rooms'
|
$ref: './paths/rooms.yaml#/~1rooms'
|
||||||
/rooms/{roomId}:
|
/rooms/{roomId}:
|
||||||
$ref: './paths/rooms.yaml#/~1rooms~1{roomId}'
|
$ref: './paths/rooms.yaml#/~1rooms~1{roomId}'
|
||||||
/rooms/{roomId}/preferences:
|
/rooms/{roomId}/config:
|
||||||
$ref: './paths/rooms.yaml#/~1rooms~1{roomId}~1preferences'
|
$ref: './paths/rooms.yaml#/~1rooms~1{roomId}~1config'
|
||||||
/recordings:
|
/recordings:
|
||||||
$ref: './paths/recordings.yaml#/~1recordings'
|
$ref: './paths/recordings.yaml#/~1recordings'
|
||||||
/recordings/download:
|
/recordings/download:
|
||||||
@ -33,8 +33,8 @@ components:
|
|||||||
$ref: components/schemas/meet-room.yaml
|
$ref: components/schemas/meet-room.yaml
|
||||||
MeetRoomOptions:
|
MeetRoomOptions:
|
||||||
$ref: components/schemas/meet-room-options.yaml
|
$ref: components/schemas/meet-room-options.yaml
|
||||||
MeetRoomPreferences:
|
MeetRoomConfig:
|
||||||
$ref: './components/schemas/meet-room-preferences.yaml#/MeetRoomPreferences'
|
$ref: './components/schemas/meet-room-config.yaml#/MeetRoomConfig'
|
||||||
MeetRecording:
|
MeetRecording:
|
||||||
$ref: components/schemas/meet-recording.yaml
|
$ref: components/schemas/meet-recording.yaml
|
||||||
Error:
|
Error:
|
||||||
|
|||||||
@ -63,8 +63,8 @@ components:
|
|||||||
$ref: components/schemas/meet-room.yaml
|
$ref: components/schemas/meet-room.yaml
|
||||||
MeetRoomOptions:
|
MeetRoomOptions:
|
||||||
$ref: components/schemas/meet-room-options.yaml
|
$ref: components/schemas/meet-room-options.yaml
|
||||||
MeetRoomPreferences:
|
MeetRoomConfig:
|
||||||
$ref: components/schemas/meet-room-preferences.yaml#/MeetRoomPreferences
|
$ref: components/schemas/meet-room-config.yaml#/MeetRoomConfig
|
||||||
MeetRoomRoleAndPermissions:
|
MeetRoomRoleAndPermissions:
|
||||||
$ref: components/schemas/internal/meet-room-role-permissions.yaml
|
$ref: components/schemas/internal/meet-room-role-permissions.yaml
|
||||||
MeetRecording:
|
MeetRecording:
|
||||||
|
|||||||
@ -151,12 +151,12 @@
|
|||||||
$ref: '../components/responses/validation-error.yaml'
|
$ref: '../components/responses/validation-error.yaml'
|
||||||
'500':
|
'500':
|
||||||
$ref: '../components/responses/internal-server-error.yaml'
|
$ref: '../components/responses/internal-server-error.yaml'
|
||||||
/rooms/{roomId}/preferences:
|
/rooms/{roomId}/config:
|
||||||
get:
|
get:
|
||||||
operationId: getRoomPreferences
|
operationId: getRoomConfig
|
||||||
summary: Get room preferences
|
summary: Get room config
|
||||||
description: >
|
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:
|
tags:
|
||||||
- OpenVidu Meet - Rooms
|
- OpenVidu Meet - Rooms
|
||||||
security:
|
security:
|
||||||
@ -168,7 +168,7 @@
|
|||||||
- $ref: '../components/parameters/internal/x-participant-role.yaml'
|
- $ref: '../components/parameters/internal/x-participant-role.yaml'
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
$ref: '../components/responses/success-get-room-preferences.yaml'
|
$ref: '../components/responses/success-get-room-config.yaml'
|
||||||
'400':
|
'400':
|
||||||
$ref: '../components/responses/internal/error-invalid-participant-role.yaml'
|
$ref: '../components/responses/internal/error-invalid-participant-role.yaml'
|
||||||
'401':
|
'401':
|
||||||
@ -182,10 +182,10 @@
|
|||||||
'500':
|
'500':
|
||||||
$ref: '../components/responses/internal-server-error.yaml'
|
$ref: '../components/responses/internal-server-error.yaml'
|
||||||
put:
|
put:
|
||||||
operationId: updateRoomPreferences
|
operationId: updateRoomConfig
|
||||||
summary: Update room preferences
|
summary: Update room config
|
||||||
description: >
|
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:
|
tags:
|
||||||
- OpenVidu Meet - Rooms
|
- OpenVidu Meet - Rooms
|
||||||
security:
|
security:
|
||||||
@ -194,10 +194,10 @@
|
|||||||
parameters:
|
parameters:
|
||||||
- $ref: '../components/parameters/room-id-path.yaml'
|
- $ref: '../components/parameters/room-id-path.yaml'
|
||||||
requestBody:
|
requestBody:
|
||||||
$ref: '../components/requestBodies/update-room-preferences-request.yaml'
|
$ref: '../components/requestBodies/update-room-config-request.yaml'
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
$ref: '../components/responses/success-update-room-preferences.yaml'
|
$ref: '../components/responses/success-update-room-config.yaml'
|
||||||
'401':
|
'401':
|
||||||
$ref: '../components/responses/unauthorized-error.yaml'
|
$ref: '../components/responses/unauthorized-error.yaml'
|
||||||
'403':
|
'403':
|
||||||
|
|||||||
@ -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 logger = container.get(LoggerService);
|
||||||
const roomService = container.get(RoomService);
|
const roomService = container.get(RoomService);
|
||||||
const { roomId } = req.params;
|
const { roomId } = req.params;
|
||||||
|
|
||||||
logger.verbose(`Getting room preferences for room '${roomId}'`);
|
logger.verbose(`Getting room config for room '${roomId}'`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { preferences } = await roomService.getMeetRoom(roomId);
|
const { config } = await roomService.getMeetRoom(roomId);
|
||||||
return res.status(200).json(preferences);
|
return res.status(200).json(config);
|
||||||
} catch (error) {
|
} 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 logger = container.get(LoggerService);
|
||||||
const roomService = container.get(RoomService);
|
const roomService = container.get(RoomService);
|
||||||
const { preferences } = req.body;
|
const { config } = req.body;
|
||||||
const { roomId } = req.params;
|
const { roomId } = req.params;
|
||||||
|
|
||||||
logger.verbose(`Updating room preferences for room '${roomId}'`);
|
logger.verbose(`Updating room config for room '${roomId}'`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await roomService.updateMeetRoomPreferences(roomId, preferences);
|
await roomService.updateMeetRoomConfig(roomId, config);
|
||||||
return res.status(200).json({ message: `Room preferences for room '${roomId}' updated successfully` });
|
return res.status(200).json({ message: `Room config for room '${roomId}' updated successfully` });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(res, error, `updating room preferences for room '${roomId}'`);
|
handleError(res, error, `updating room config for room '${roomId}'`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export class MeetRoomHelper {
|
|||||||
roomName: room.roomName,
|
roomName: room.roomName,
|
||||||
autoDeletionDate: room.autoDeletionDate,
|
autoDeletionDate: room.autoDeletionDate,
|
||||||
autoDeletionPolicy: room.autoDeletionPolicy,
|
autoDeletionPolicy: room.autoDeletionPolicy,
|
||||||
preferences: room.preferences
|
config: room.config
|
||||||
// maxParticipants: room.maxParticipants
|
// maxParticipants: room.maxParticipants
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export const withRecordingEnabled = async (req: Request, res: Response, next: Ne
|
|||||||
const roomId = extractRoomIdFromRequest(req);
|
const roomId = extractRoomIdFromRequest(req);
|
||||||
const room: MeetRoom = await roomService.getMeetRoom(roomId!);
|
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}'`);
|
logger.debug(`Recording is disabled for room '${roomId}'`);
|
||||||
const error = errorRecordingDisabled(roomId!);
|
const error = errorRecordingDisabled(roomId!);
|
||||||
return rejectRequestFromMeetError(res, error);
|
return rejectRequestFromMeetError(res, error);
|
||||||
@ -35,7 +35,7 @@ export const withRecordingEnabled = async (req: Request, res: Response, next: Ne
|
|||||||
|
|
||||||
return next();
|
return next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(res, error, 'checking recording preferences');
|
handleError(res, error, 'checking recording config');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import {
|
import {
|
||||||
MeetChatPreferences,
|
MeetChatConfig,
|
||||||
MeetRecordingAccess,
|
MeetRecordingAccess,
|
||||||
MeetRecordingPreferences,
|
MeetRecordingConfig,
|
||||||
MeetRoomAutoDeletionPolicy,
|
MeetRoomAutoDeletionPolicy,
|
||||||
|
MeetRoomConfig,
|
||||||
MeetRoomDeletionPolicyWithMeeting,
|
MeetRoomDeletionPolicyWithMeeting,
|
||||||
MeetRoomDeletionPolicyWithRecordings,
|
MeetRoomDeletionPolicyWithRecordings,
|
||||||
MeetRoomFilters,
|
MeetRoomFilters,
|
||||||
MeetRoomOptions,
|
MeetRoomOptions,
|
||||||
MeetRoomPreferences,
|
|
||||||
MeetRoomStatus,
|
MeetRoomStatus,
|
||||||
MeetVirtualBackgroundPreferences,
|
MeetVirtualBackgroundConfig,
|
||||||
ParticipantRole,
|
ParticipantRole,
|
||||||
RecordingPermissions
|
RecordingPermissions
|
||||||
} from '@typings-ce';
|
} from '@typings-ce';
|
||||||
@ -65,7 +65,7 @@ const RecordingAccessSchema: z.ZodType<MeetRecordingAccess> = z.enum([
|
|||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const RecordingPreferencesSchema: z.ZodType<MeetRecordingPreferences> = z
|
const RecordingConfigSchema: z.ZodType<MeetRecordingConfig> = z
|
||||||
.object({
|
.object({
|
||||||
enabled: z.boolean(),
|
enabled: z.boolean(),
|
||||||
allowAccessTo: RecordingAccessSchema.optional()
|
allowAccessTo: RecordingAccessSchema.optional()
|
||||||
@ -81,18 +81,18 @@ const RecordingPreferencesSchema: z.ZodType<MeetRecordingPreferences> = z
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const ChatPreferencesSchema: z.ZodType<MeetChatPreferences> = z.object({
|
const ChatConfigSchema: z.ZodType<MeetChatConfig> = z.object({
|
||||||
enabled: z.boolean()
|
enabled: z.boolean()
|
||||||
});
|
});
|
||||||
|
|
||||||
const VirtualBackgroundPreferencesSchema: z.ZodType<MeetVirtualBackgroundPreferences> = z.object({
|
const VirtualBackgroundConfigSchema: z.ZodType<MeetVirtualBackgroundConfig> = z.object({
|
||||||
enabled: z.boolean()
|
enabled: z.boolean()
|
||||||
});
|
});
|
||||||
|
|
||||||
const RoomPreferencesSchema: z.ZodType<MeetRoomPreferences> = z.object({
|
const RoomConfigSchema: z.ZodType<MeetRoomConfig> = z.object({
|
||||||
recordingPreferences: RecordingPreferencesSchema,
|
recordingConfig: RecordingConfigSchema,
|
||||||
chatPreferences: ChatPreferencesSchema,
|
chatConfig: ChatConfigSchema,
|
||||||
virtualBackgroundPreferences: VirtualBackgroundPreferencesSchema
|
virtualBackgroundConfig: VirtualBackgroundConfigSchema
|
||||||
});
|
});
|
||||||
|
|
||||||
const RoomDeletionPolicyWithMeetingSchema: z.ZodType<MeetRoomDeletionPolicyWithMeeting> = z.enum([
|
const RoomDeletionPolicyWithMeetingSchema: z.ZodType<MeetRoomDeletionPolicyWithMeeting> = z.enum([
|
||||||
@ -150,10 +150,10 @@ const RoomRequestOptionsSchema: z.ZodType<MeetRoomOptions> = z.object({
|
|||||||
path: ['withRecordings']
|
path: ['withRecordings']
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
preferences: RoomPreferencesSchema.optional().default({
|
config: RoomConfigSchema.optional().default({
|
||||||
recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER },
|
recordingConfig: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER },
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
})
|
})
|
||||||
// maxParticipants: z
|
// maxParticipants: z
|
||||||
// .number()
|
// .number()
|
||||||
@ -223,8 +223,8 @@ const BulkDeleteRoomsSchema = z.object({
|
|||||||
withRecordings: RoomDeletionPolicyWithRecordingsSchema.optional().default(MeetRoomDeletionPolicyWithRecordings.FAIL)
|
withRecordings: RoomDeletionPolicyWithRecordingsSchema.optional().default(MeetRoomDeletionPolicyWithRecordings.FAIL)
|
||||||
});
|
});
|
||||||
|
|
||||||
const UpdateRoomPreferencesSchema = z.object({
|
const UpdateRoomConfigSchema = z.object({
|
||||||
preferences: RoomPreferencesSchema
|
config: RoomConfigSchema
|
||||||
});
|
});
|
||||||
|
|
||||||
const UpdateRoomStatusSchema = z.object({
|
const UpdateRoomStatusSchema = z.object({
|
||||||
@ -270,8 +270,8 @@ export const withValidRoomFiltersRequest = (req: Request, res: Response, next: N
|
|||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const withValidRoomPreferences = (req: Request, res: Response, next: NextFunction) => {
|
export const withValidRoomConfig = (req: Request, res: Response, next: NextFunction) => {
|
||||||
const { success, error, data } = UpdateRoomPreferencesSchema.safeParse(req.body);
|
const { success, error, data } = UpdateRoomConfigSchema.safeParse(req.body);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return rejectUnprocessableRequest(res, error);
|
return rejectUnprocessableRequest(res, error);
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export const configureRecordingTokenAuth = async (req: Request, res: Response, n
|
|||||||
throw errorRoomMetadataNotFound(roomId);
|
throw errorRoomMetadataNotFound(roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const recordingAccess = room.preferences!.recordingPreferences.allowAccessTo;
|
const recordingAccess = room.config!.recordingConfig.allowAccessTo;
|
||||||
|
|
||||||
if (!recordingAccess || recordingAccess === MeetRecordingAccess.ADMIN) {
|
if (!recordingAccess || recordingAccess === MeetRecordingAccess.ADMIN) {
|
||||||
// Deny request if the room is configured to allow access to recordings only for admins
|
// Deny request if the room is configured to allow access to recordings only for admins
|
||||||
|
|||||||
@ -11,11 +11,11 @@ import {
|
|||||||
tokenAndRoleValidator,
|
tokenAndRoleValidator,
|
||||||
withAuth,
|
withAuth,
|
||||||
withValidRoomBulkDeleteRequest,
|
withValidRoomBulkDeleteRequest,
|
||||||
|
withValidRoomConfig,
|
||||||
withValidRoomDeleteRequest,
|
withValidRoomDeleteRequest,
|
||||||
withValidRoomFiltersRequest,
|
withValidRoomFiltersRequest,
|
||||||
withValidRoomId,
|
withValidRoomId,
|
||||||
withValidRoomOptions,
|
withValidRoomOptions,
|
||||||
withValidRoomPreferences,
|
|
||||||
withValidRoomSecret,
|
withValidRoomSecret,
|
||||||
withValidRoomStatus
|
withValidRoomStatus
|
||||||
} from '../middlewares/index.js';
|
} from '../middlewares/index.js';
|
||||||
@ -59,18 +59,18 @@ roomRouter.delete(
|
|||||||
);
|
);
|
||||||
|
|
||||||
roomRouter.get(
|
roomRouter.get(
|
||||||
'/:roomId/preferences',
|
'/:roomId/config',
|
||||||
withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN), participantTokenValidator),
|
withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN), participantTokenValidator),
|
||||||
withValidRoomId,
|
withValidRoomId,
|
||||||
configureRoomAuthorization,
|
configureRoomAuthorization,
|
||||||
roomCtrl.getRoomPreferences
|
roomCtrl.getRoomConfig
|
||||||
);
|
);
|
||||||
roomRouter.put(
|
roomRouter.put(
|
||||||
'/:roomId/preferences',
|
'/:roomId/config',
|
||||||
withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN)),
|
withAuth(apiKeyValidator, tokenAndRoleValidator(UserRole.ADMIN)),
|
||||||
withValidRoomId,
|
withValidRoomId,
|
||||||
withValidRoomPreferences,
|
withValidRoomConfig,
|
||||||
roomCtrl.updateRoomPreferences
|
roomCtrl.updateRoomConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
roomRouter.put(
|
roomRouter.put(
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { MeetRoom, MeetRecordingInfo, ParticipantRole } from '@typings-ce';
|
import { MeetRecordingInfo, MeetRoom, ParticipantRole } from '@typings-ce';
|
||||||
import { inject, injectable } from 'inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { SendDataOptions } from 'livekit-server-sdk';
|
import { SendDataOptions } from 'livekit-server-sdk';
|
||||||
import { OpenViduComponentsAdapterHelper, OpenViduComponentsSignalPayload } from '../helpers/index.js';
|
import { OpenViduComponentsAdapterHelper, OpenViduComponentsSignalPayload } from '../helpers/index.js';
|
||||||
import { LiveKitService, LoggerService } from './index.js';
|
|
||||||
import {
|
import {
|
||||||
MeetParticipantRoleUpdatedPayload,
|
MeetParticipantRoleUpdatedPayload,
|
||||||
MeetRoomPreferencesUpdatedPayload,
|
MeetRoomConfigUpdatedPayload,
|
||||||
MeetSignalPayload,
|
MeetSignalPayload,
|
||||||
MeetSignalType
|
MeetSignalType
|
||||||
} from '../typings/ce/event.model.js';
|
} from '../typings/ce/event.model.js';
|
||||||
|
import { LiveKitService, LoggerService } from './index.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service responsible for all communication with the frontend
|
* 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<void> {
|
async sendRoomConfigUpdatedSignal(roomId: string, updatedRoom: MeetRoom): Promise<void> {
|
||||||
this.logger.debug(`Sending room preferences updated signal for room ${roomId}`);
|
this.logger.debug(`Sending room config updated signal for room ${roomId}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const payload: MeetRoomPreferencesUpdatedPayload = {
|
const payload: MeetRoomConfigUpdatedPayload = {
|
||||||
roomId,
|
roomId,
|
||||||
preferences: updatedRoom.preferences!,
|
config: updatedRoom.config!,
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
};
|
};
|
||||||
|
|
||||||
const options: SendDataOptions = {
|
const options: SendDataOptions = {
|
||||||
topic: MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED
|
topic: MeetSignalType.MEET_ROOM_CONFIG_UPDATED
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.sendSignal(roomId, payload, options);
|
await this.sendSignal(roomId, payload, options);
|
||||||
} catch (error) {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,13 +2,13 @@ import {
|
|||||||
MeetingEndAction,
|
MeetingEndAction,
|
||||||
MeetRecordingAccess,
|
MeetRecordingAccess,
|
||||||
MeetRoom,
|
MeetRoom,
|
||||||
|
MeetRoomConfig,
|
||||||
MeetRoomDeletionErrorCode,
|
MeetRoomDeletionErrorCode,
|
||||||
MeetRoomDeletionPolicyWithMeeting,
|
MeetRoomDeletionPolicyWithMeeting,
|
||||||
MeetRoomDeletionPolicyWithRecordings,
|
MeetRoomDeletionPolicyWithRecordings,
|
||||||
MeetRoomDeletionSuccessCode,
|
MeetRoomDeletionSuccessCode,
|
||||||
MeetRoomFilters,
|
MeetRoomFilters,
|
||||||
MeetRoomOptions,
|
MeetRoomOptions,
|
||||||
MeetRoomPreferences,
|
|
||||||
MeetRoomStatus,
|
MeetRoomStatus,
|
||||||
ParticipantRole,
|
ParticipantRole,
|
||||||
RecordingPermissions
|
RecordingPermissions
|
||||||
@ -80,7 +80,7 @@ export class RoomService {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async createMeetRoom(baseUrl: string, roomOptions: MeetRoomOptions): Promise<MeetRoom> {
|
async createMeetRoom(baseUrl: string, roomOptions: MeetRoomOptions): Promise<MeetRoom> {
|
||||||
const { roomName, autoDeletionDate, autoDeletionPolicy, preferences } = roomOptions;
|
const { roomName, autoDeletionDate, autoDeletionPolicy, config } = roomOptions;
|
||||||
const roomIdPrefix = roomName!.replace(/\s+/g, ''); // Remove all spaces
|
const roomIdPrefix = roomName!.replace(/\s+/g, ''); // Remove all spaces
|
||||||
const roomId = `${roomIdPrefix}-${uid(15)}`; // Generate a unique room ID based on the room name
|
const roomId = `${roomIdPrefix}-${uid(15)}`; // Generate a unique room ID based on the room name
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ export class RoomService {
|
|||||||
// maxParticipants,
|
// maxParticipants,
|
||||||
autoDeletionDate,
|
autoDeletionDate,
|
||||||
autoDeletionPolicy,
|
autoDeletionPolicy,
|
||||||
preferences: preferences!,
|
config: config!,
|
||||||
moderatorUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
moderatorUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
||||||
speakerUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
speakerUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
||||||
status: MeetRoomStatus.OPEN,
|
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 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
|
* @returns A Promise that resolves to the updated MeetRoom object
|
||||||
*/
|
*/
|
||||||
async updateMeetRoomPreferences(roomId: string, preferences: MeetRoomPreferences): Promise<MeetRoom> {
|
async updateMeetRoomConfig(roomId: string, config: MeetRoomConfig): Promise<MeetRoom> {
|
||||||
const room = await this.getMeetRoom(roomId);
|
const room = await this.getMeetRoom(roomId);
|
||||||
room.preferences = preferences;
|
room.config = config;
|
||||||
|
|
||||||
await this.storageService.saveMeetRoom(room);
|
await this.storageService.saveMeetRoom(room);
|
||||||
// Update the archived room metadata if it exists
|
// Update the archived room metadata if it exists
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.storageService.archiveRoomMetadata(roomId, true),
|
this.storageService.archiveRoomMetadata(roomId, true),
|
||||||
this.frontendEventService.sendRoomPreferencesUpdatedSignal(roomId, room)
|
this.frontendEventService.sendRoomConfigUpdatedSignal(roomId, room)
|
||||||
]);
|
]);
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
@ -684,7 +684,7 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected getRecordingPermissions(room: Partial<MeetRoom>, role: ParticipantRole): RecordingPermissions {
|
protected getRecordingPermissions(room: Partial<MeetRoom>, 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
|
// 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;
|
const canDeleteRecordings = role === ParticipantRole.MODERATOR && recordingAccess !== MeetRecordingAccess.ADMIN;
|
||||||
|
|||||||
@ -269,7 +269,7 @@ export class MeetStorageService<
|
|||||||
* Archives room metadata by storing essential room information in both cache and persistent storage.
|
* 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
|
* 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,
|
* If `updateOnlyIfExists` is true, it will only save the archived metadata if it already exists,
|
||||||
* updating the existing entry.
|
* updating the existing entry.
|
||||||
@ -302,8 +302,8 @@ export class MeetStorageService<
|
|||||||
const archivedRoom: Partial<MRoom> = {
|
const archivedRoom: Partial<MRoom> = {
|
||||||
moderatorUrl: room.moderatorUrl,
|
moderatorUrl: room.moderatorUrl,
|
||||||
speakerUrl: room.speakerUrl,
|
speakerUrl: room.speakerUrl,
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: room.preferences?.recordingPreferences
|
recordingConfig: room.config?.recordingConfig
|
||||||
}
|
}
|
||||||
} as Partial<MRoom>;
|
} as Partial<MRoom>;
|
||||||
|
|
||||||
|
|||||||
@ -9,9 +9,9 @@ import {
|
|||||||
MeetRecordingStatus,
|
MeetRecordingStatus,
|
||||||
MeetRoom,
|
MeetRoom,
|
||||||
MeetRoomAutoDeletionPolicy,
|
MeetRoomAutoDeletionPolicy,
|
||||||
|
MeetRoomConfig,
|
||||||
MeetRoomDeletionPolicyWithMeeting,
|
MeetRoomDeletionPolicyWithMeeting,
|
||||||
MeetRoomDeletionPolicyWithRecordings,
|
MeetRoomDeletionPolicyWithRecordings,
|
||||||
MeetRoomPreferences,
|
|
||||||
MeetRoomStatus,
|
MeetRoomStatus,
|
||||||
ParticipantPermissions,
|
ParticipantPermissions,
|
||||||
ParticipantRole
|
ParticipantRole
|
||||||
@ -93,22 +93,22 @@ export const expectSuccessRoomResponse = (
|
|||||||
response: any,
|
response: any,
|
||||||
roomName: string,
|
roomName: string,
|
||||||
autoDeletionDate?: number,
|
autoDeletionDate?: number,
|
||||||
preferences?: MeetRoomPreferences
|
config?: MeetRoomConfig
|
||||||
) => {
|
) => {
|
||||||
expect(response.status).toBe(200);
|
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.status).toBe(200);
|
||||||
expect(response.body).toBeDefined();
|
expect(response.body).toBeDefined();
|
||||||
expect(response.body).toEqual(preferences);
|
expect(response.body).toEqual(config);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const expectValidRoom = (
|
export const expectValidRoom = (
|
||||||
room: MeetRoom,
|
room: MeetRoom,
|
||||||
name: string,
|
name: string,
|
||||||
preferences?: MeetRoomPreferences,
|
config?: MeetRoomConfig,
|
||||||
autoDeletionDate?: number,
|
autoDeletionDate?: number,
|
||||||
autoDeletionPolicy?: MeetRoomAutoDeletionPolicy,
|
autoDeletionPolicy?: MeetRoomAutoDeletionPolicy,
|
||||||
status?: MeetRoomStatus,
|
status?: MeetRoomStatus,
|
||||||
@ -140,18 +140,18 @@ export const expectValidRoom = (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(room.preferences).toBeDefined();
|
expect(room.config).toBeDefined();
|
||||||
|
|
||||||
if (preferences !== undefined) {
|
if (config !== undefined) {
|
||||||
expect(room.preferences).toEqual(preferences);
|
expect(room.config).toEqual(config);
|
||||||
} else {
|
} else {
|
||||||
expect(room.preferences).toEqual({
|
expect(room.config).toEqual({
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -243,34 +243,34 @@ export const getRoom = async (roomId: string, fields?: string, cookie?: string,
|
|||||||
return await req;
|
return await req;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRoomPreferences = async (roomId: string) => {
|
export const getRoomConfig = async (roomId: string) => {
|
||||||
checkAppIsRunning();
|
checkAppIsRunning();
|
||||||
|
|
||||||
return await request(app)
|
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)
|
.set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY)
|
||||||
.send();
|
.send();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateRoomPreferences = async (roomId: string, preferences: any) => {
|
export const updateRoomConfig = async (roomId: string, config: any) => {
|
||||||
checkAppIsRunning();
|
checkAppIsRunning();
|
||||||
|
|
||||||
return await request(app)
|
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)
|
.set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY)
|
||||||
.send({ preferences });
|
.send({ config });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateRecordingAccessPreferencesInRoom = async (roomId: string, recordingAccess: MeetRecordingAccess) => {
|
export const updateRecordingAccessConfigInRoom = async (roomId: string, recordingAccess: MeetRecordingAccess) => {
|
||||||
const response = await updateRoomPreferences(roomId, {
|
const response = await updateRoomConfig(roomId, {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: recordingAccess
|
allowAccessTo: recordingAccess
|
||||||
},
|
},
|
||||||
chatPreferences: {
|
chatConfig: {
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: {
|
virtualBackgroundConfig: {
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -297,11 +297,7 @@ export const deleteRoom = async (roomId: string, query: Record<string, any> = {}
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bulkDeleteRooms = async (
|
export const bulkDeleteRooms = async (roomIds: any[], withMeeting?: string, withRecordings?: string) => {
|
||||||
roomIds: any[],
|
|
||||||
withMeeting?: string,
|
|
||||||
withRecordings?: string
|
|
||||||
) => {
|
|
||||||
checkAppIsRunning();
|
checkAppIsRunning();
|
||||||
|
|
||||||
const result = await request(app)
|
const result = await request(app)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import express, { Request, Response } from 'express';
|
|||||||
import http from 'http';
|
import http from 'http';
|
||||||
import { StringValue } from 'ms';
|
import { StringValue } from 'ms';
|
||||||
import { MeetRoomHelper } from '../../src/helpers';
|
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 { expectValidStartRecordingResponse } from './assertion-helpers';
|
||||||
import {
|
import {
|
||||||
createRoom,
|
createRoom,
|
||||||
@ -35,17 +35,17 @@ export interface TestContext {
|
|||||||
*
|
*
|
||||||
* @param withParticipant Whether to join a fake participant in the room.
|
* @param withParticipant Whether to join a fake participant in the room.
|
||||||
* @param roomName Name of the room to create.
|
* @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.
|
* @returns Room data including secrets and cookies.
|
||||||
*/
|
*/
|
||||||
export const setupSingleRoom = async (
|
export const setupSingleRoom = async (
|
||||||
withParticipant = false,
|
withParticipant = false,
|
||||||
roomName = 'TEST_ROOM',
|
roomName = 'TEST_ROOM',
|
||||||
preferences?: MeetRoomPreferences
|
config?: MeetRoomConfig
|
||||||
): Promise<RoomData> => {
|
): Promise<RoomData> => {
|
||||||
const room = await createRoom({
|
const room = await createRoom({
|
||||||
roomName,
|
roomName,
|
||||||
preferences
|
config
|
||||||
});
|
});
|
||||||
|
|
||||||
// Extract the room secrets and generate participant tokens, saved as cookies
|
// Extract the room secrets and generate participant tokens, saved as cookies
|
||||||
|
|||||||
@ -73,7 +73,7 @@ describe('Recording API Tests', () => {
|
|||||||
expect(archivedRoom).toBeDefined();
|
expect(archivedRoom).toBeDefined();
|
||||||
expect(archivedRoom?.moderatorUrl).toBeDefined();
|
expect(archivedRoom?.moderatorUrl).toBeDefined();
|
||||||
expect(archivedRoom?.speakerUrl).toBeDefined();
|
expect(archivedRoom?.speakerUrl).toBeDefined();
|
||||||
expect(archivedRoom?.preferences).toBeDefined();
|
expect(archivedRoom?.config).toBeDefined();
|
||||||
|
|
||||||
const secretsResponse = await stopRecording(recordingId, moderatorCookie);
|
const secretsResponse = await stopRecording(recordingId, moderatorCookie);
|
||||||
expectValidStopRecordingResponse(secretsResponse, recordingId, room.roomId, room.roomName);
|
expectValidStopRecordingResponse(secretsResponse, recordingId, room.roomId, room.roomName);
|
||||||
|
|||||||
@ -58,25 +58,19 @@ describe('Room API Tests', () => {
|
|||||||
withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE,
|
withMeeting: MeetRoomDeletionPolicyWithMeeting.FORCE,
|
||||||
withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE
|
withRecordings: MeetRoomDeletionPolicyWithRecordings.FORCE
|
||||||
},
|
},
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatConfig: { enabled: false },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const room = await createRoom(payload);
|
const room = await createRoom(payload);
|
||||||
|
|
||||||
expectValidRoom(
|
expectValidRoom(room, 'Example Room', payload.config, validAutoDeletionDate, payload.autoDeletionPolicy);
|
||||||
room,
|
|
||||||
'Example Room',
|
|
||||||
payload.preferences,
|
|
||||||
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);
|
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 () => {
|
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);
|
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 () => {
|
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');
|
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 = {
|
const payload = {
|
||||||
roomName: 'TestRoom',
|
roomName: 'TestRoom',
|
||||||
autoDeletionDate: validAutoDeletionDate,
|
autoDeletionDate: validAutoDeletionDate,
|
||||||
preferences: 'invalid-preferences'
|
config: 'invalid-config'
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app).post(ROOMS_PATH).set('Cookie', adminCookie).send(payload).expect(422);
|
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');
|
expect(JSON.stringify(response.body.details)).toContain('Expected object');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when preferences has an invalid structure', async () => {
|
it('should fail when config has an invalid structure', async () => {
|
||||||
// Assuming preferences expects each sub-property to be an object with a boolean "enabled",
|
// Assuming config expects each sub-property to be an object with a boolean "enabled",
|
||||||
// here we deliberately use an invalid structure.
|
// here we deliberately use an invalid structure.
|
||||||
const payload = {
|
const payload = {
|
||||||
roomName: 'TestRoom',
|
roomName: 'TestRoom',
|
||||||
autoDeletionDate: validAutoDeletionDate,
|
autoDeletionDate: validAutoDeletionDate,
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: 'yes', // invalid boolean
|
enabled: 'yes', // invalid boolean
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { afterAll, beforeAll, describe, expect, it } from '@jest/globals';
|
import { afterAll, beforeAll, describe, expect, it } from '@jest/globals';
|
||||||
import { ParticipantRole } from '../../../../src/typings/ce/participant.js';
|
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 { expectValidRecordingTokenResponse } from '../../../helpers/assertion-helpers.js';
|
||||||
import {
|
import {
|
||||||
deleteAllRecordings,
|
deleteAllRecordings,
|
||||||
@ -9,7 +9,7 @@ import {
|
|||||||
disconnectFakeParticipants,
|
disconnectFakeParticipants,
|
||||||
generateRecordingToken,
|
generateRecordingToken,
|
||||||
startTestServer,
|
startTestServer,
|
||||||
updateRecordingAccessPreferencesInRoom
|
updateRecordingAccessConfigInRoom
|
||||||
} from '../../../helpers/request-helpers.js';
|
} from '../../../helpers/request-helpers.js';
|
||||||
import { RoomData, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js';
|
import { RoomData, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.js';
|
||||||
|
|
||||||
@ -28,44 +28,35 @@ describe('Room API Tests', () => {
|
|||||||
|
|
||||||
describe('Generate Recording Token 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 () => {
|
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);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true);
|
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 () => {
|
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(
|
await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER);
|
||||||
roomData.room.roomId,
|
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
|
||||||
);
|
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true);
|
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 () => {
|
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);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, false, false);
|
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 () => {
|
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(
|
await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER);
|
||||||
roomData.room.roomId,
|
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
|
||||||
);
|
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, true, false);
|
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, true, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed even if the room is deleted', async () => {
|
it('should succeed even if the room is deleted', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER);
|
||||||
roomData.room.roomId,
|
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
|
||||||
);
|
|
||||||
await deleteRoom(roomData.room.roomId);
|
await deleteRoom(roomData.room.roomId);
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import { afterEach, beforeAll, describe, it } from '@jest/globals';
|
import { afterEach, beforeAll, describe, it } from '@jest/globals';
|
||||||
import { MeetRecordingAccess } from '../../../../src/typings/ce/index.js';
|
import { MeetRecordingAccess } from '../../../../src/typings/ce/index.js';
|
||||||
import { expectSuccessRoomPreferencesResponse } from '../../../helpers/assertion-helpers.js';
|
import { expectSuccessRoomConfigResponse } from '../../../helpers/assertion-helpers.js';
|
||||||
import { deleteAllRooms, getRoomPreferences, startTestServer } from '../../../helpers/request-helpers.js';
|
import { deleteAllRooms, getRoomConfig, startTestServer } from '../../../helpers/request-helpers.js';
|
||||||
import { setupSingleRoom } from '../../../helpers/test-scenarios.js';
|
import { setupSingleRoom } from '../../../helpers/test-scenarios.js';
|
||||||
|
|
||||||
describe('Room API Tests', () => {
|
describe('Room API Tests', () => {
|
||||||
const DEFAULT_PREFERENCES = {
|
const DEFAULT_CONFIG = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@ -23,33 +23,33 @@ describe('Room API Tests', () => {
|
|||||||
await deleteAllRooms();
|
await deleteAllRooms();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Get Room Preferences Tests', () => {
|
describe('Get Room Config Tests', () => {
|
||||||
it('should successfully retrieve a room by its ID', async () => {
|
it('should successfully retrieve a room by its ID', async () => {
|
||||||
const roomData = await setupSingleRoom();
|
const roomData = await setupSingleRoom();
|
||||||
const roomId = roomData.room.roomId;
|
const roomId = roomData.room.roomId;
|
||||||
|
|
||||||
const response = await getRoomPreferences(roomId);
|
const response = await getRoomConfig(roomId);
|
||||||
expectSuccessRoomPreferencesResponse(response, DEFAULT_PREFERENCES);
|
expectSuccessRoomConfigResponse(response, DEFAULT_CONFIG);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve custom room preferences', async () => {
|
it('should retrieve custom room config', async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
roomName: 'custom-prefs',
|
roomName: 'custom-prefs',
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
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 roomId = roomData.room.roomId;
|
||||||
|
|
||||||
const response = await getRoomPreferences(roomId);
|
const response = await getRoomConfig(roomId);
|
||||||
expectSuccessRoomPreferencesResponse(response, payload.preferences);
|
expectSuccessRoomConfigResponse(response, payload.config);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -32,25 +32,25 @@ describe('Room API Tests', () => {
|
|||||||
expectSuccessRoomResponse(response, 'test-room');
|
expectSuccessRoomResponse(response, 'test-room');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve a room with custom preferences', async () => {
|
it('should retrieve a room with custom config', async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
roomName: 'custom-prefs',
|
roomName: 'custom-prefs',
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundConfig: { enabled: false }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Create a room with custom preferences
|
// Create a room with custom config
|
||||||
const { roomId } = await createRoom(payload);
|
const { roomId } = await createRoom(payload);
|
||||||
|
|
||||||
// Retrieve the room by its ID
|
// Retrieve the room by its ID
|
||||||
const response = await getRoom(roomId);
|
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 () => {
|
it('should retrieve only specified fields when using fields parameter', async () => {
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { afterEach, beforeAll, describe, expect, it, jest } from '@jest/globals';
|
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 { MeetRecordingAccess } from '../../../../src/typings/ce/index.js';
|
||||||
import {
|
import {
|
||||||
createRoom,
|
createRoom,
|
||||||
deleteAllRooms,
|
deleteAllRooms,
|
||||||
getRoom,
|
getRoom,
|
||||||
startTestServer,
|
startTestServer,
|
||||||
updateRoomPreferences
|
updateRoomConfig
|
||||||
} from '../../../helpers/request-helpers.js';
|
} 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', () => {
|
describe('Room API Tests', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@ -21,7 +21,7 @@ describe('Room API Tests', () => {
|
|||||||
await deleteAllRooms();
|
await deleteAllRooms();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Update Room Preferences Tests', () => {
|
describe('Update Room Config Tests', () => {
|
||||||
let frontendEventService: FrontendEventService;
|
let frontendEventService: FrontendEventService;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@ -29,41 +29,41 @@ describe('Room API Tests', () => {
|
|||||||
frontendEventService = container.get(FrontendEventService);
|
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 sendSignalSpy = jest.spyOn(frontendEventService as any, 'sendSignal');
|
||||||
const createdRoom = await createRoom({
|
const createdRoom = await createRoom({
|
||||||
roomName: 'update-test',
|
roomName: 'update-test',
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the room preferences
|
// Update the room config
|
||||||
const updatedPreferences = {
|
const updatedConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN
|
allowAccessTo: MeetRecordingAccess.ADMIN
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatConfig: { enabled: false },
|
||||||
virtualBackgroundPreferences: { 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
|
// Verify a method of frontend event service is called
|
||||||
expect(sendSignalSpy).toHaveBeenCalledWith(
|
expect(sendSignalSpy).toHaveBeenCalledWith(
|
||||||
createdRoom.roomId,
|
createdRoom.roomId,
|
||||||
{
|
{
|
||||||
roomId: createdRoom.roomId,
|
roomId: createdRoom.roomId,
|
||||||
preferences: updatedPreferences,
|
config: updatedConfig,
|
||||||
timestamp: expect.any(Number)
|
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
|
// Verify with a get request
|
||||||
const getResponse = await getRoom(createdRoom.roomId);
|
const getResponse = await getRoom(createdRoom.roomId);
|
||||||
expect(getResponse.status).toBe(200);
|
expect(getResponse.status).toBe(200);
|
||||||
expect(getResponse.body.preferences).toEqual(updatedPreferences);
|
expect(getResponse.body.config).toEqual(updatedConfig);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow partial preference updates', async () => {
|
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({
|
const createdRoom = await createRoom({
|
||||||
roomName: 'partial-update',
|
roomName: 'partial-update',
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update only one preference
|
// Update only one preference
|
||||||
const partialPreferences = {
|
const partialConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
};
|
};
|
||||||
const updateResponse = await updateRoomPreferences(createdRoom.roomId, partialPreferences);
|
const updateResponse = await updateRoomConfig(createdRoom.roomId, partialConfig);
|
||||||
|
|
||||||
// Verify update response
|
// Verify update response
|
||||||
expect(updateResponse.status).toBe(200);
|
expect(updateResponse.status).toBe(200);
|
||||||
@ -109,59 +109,59 @@ describe('Room API Tests', () => {
|
|||||||
// Verify with a get request
|
// Verify with a get request
|
||||||
const getResponse = await getRoom(createdRoom.roomId);
|
const getResponse = await getRoom(createdRoom.roomId);
|
||||||
expect(getResponse.status).toBe(200);
|
expect(getResponse.status).toBe(200);
|
||||||
expect(getResponse.body.preferences).toEqual(partialPreferences);
|
expect(getResponse.body.config).toEqual(partialConfig);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Update Room Preferences Validation failures', () => {
|
describe('Update Room Config Validation failures', () => {
|
||||||
it('should fail when preferences have incorrect structure', async () => {
|
it('should fail when config has incorrect structure', async () => {
|
||||||
const { roomId } = await createRoom({
|
const { roomId } = await createRoom({
|
||||||
roomName: 'validation-test'
|
roomName: 'validation-test'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Invalid preferences (missing required fields)
|
// Invalid config (missing required fields)
|
||||||
const invalidPreferences = {
|
const invalidConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
// Missing chatPreferences
|
// Missing chatConfig
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundConfig: { enabled: false }
|
||||||
};
|
};
|
||||||
const response = await updateRoomPreferences(roomId, invalidPreferences);
|
const response = await updateRoomConfig(roomId, invalidConfig);
|
||||||
|
|
||||||
expect(response.status).toBe(422);
|
expect(response.status).toBe(422);
|
||||||
expect(response.body.error).toContain('Unprocessable Entity');
|
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({
|
const createdRoom = await createRoom({
|
||||||
roomName: 'type-test'
|
roomName: 'type-test'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Invalid preferences (wrong types)
|
// Invalid config (wrong types)
|
||||||
const invalidPreferences = {
|
const invalidConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: 'true', // String instead of boolean
|
enabled: 'true', // String instead of boolean
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatConfig: { enabled: false },
|
||||||
virtualBackgroundPreferences: { 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.status).toBe(422);
|
||||||
expect(response.body.error).toContain('Unprocessable Entity');
|
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({
|
const createdRoom = await createRoom({
|
||||||
roomName: 'missing-props'
|
roomName: 'missing-props'
|
||||||
});
|
});
|
||||||
|
|
||||||
const emptyPreferences = {};
|
const emptyConfig = {};
|
||||||
const response = await updateRoomPreferences(createdRoom.roomId, emptyPreferences);
|
const response = await updateRoomConfig(createdRoom.roomId, emptyConfig);
|
||||||
|
|
||||||
expect(response.status).toBe(422);
|
expect(response.status).toBe(422);
|
||||||
expect(response.body.error).toContain('Unprocessable Entity');
|
expect(response.body.error).toContain('Unprocessable Entity');
|
||||||
@ -172,32 +172,32 @@ describe('Room API Tests', () => {
|
|||||||
roomName: 'missing-access'
|
roomName: 'missing-access'
|
||||||
});
|
});
|
||||||
|
|
||||||
const invalidPreferences = {
|
const invalidConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true // Missing allowAccessTo
|
enabled: true // Missing allowAccessTo
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatConfig: { enabled: false },
|
||||||
virtualBackgroundPreferences: { 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.status).toBe(422);
|
||||||
expect(response.body.error).toContain('Unprocessable Entity');
|
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 () => {
|
it('should return 404 when updating non-existent room', async () => {
|
||||||
const nonExistentRoomId = 'non-existent-room';
|
const nonExistentRoomId = 'non-existent-room';
|
||||||
|
|
||||||
const preferences = {
|
const config = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatConfig: { enabled: false },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundConfig: { enabled: false }
|
||||||
};
|
};
|
||||||
const response = await updateRoomPreferences(nonExistentRoomId, preferences);
|
const response = await updateRoomConfig(nonExistentRoomId, config);
|
||||||
|
|
||||||
expect(response.status).toBe(404);
|
expect(response.status).toBe(404);
|
||||||
expect(response.body.message).toContain(`'${nonExistentRoomId}' does not exist`);
|
expect(response.body.message).toContain(`'${nonExistentRoomId}' does not exist`);
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import {
|
|||||||
startTestServer,
|
startTestServer,
|
||||||
stopAllRecordings,
|
stopAllRecordings,
|
||||||
stopRecording,
|
stopRecording,
|
||||||
updateRecordingAccessPreferencesInRoom
|
updateRecordingAccessConfigInRoom
|
||||||
} from '../../../helpers/request-helpers.js';
|
} from '../../../helpers/request-helpers.js';
|
||||||
import { RoomData, setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
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 () => {
|
it('should fail when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
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 () => {
|
it('should fail when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
it('should succeed when recording access is admin_moderator_speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.speakerSecret
|
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 () => {
|
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(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret
|
roomData.moderatorSecret
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {
|
|||||||
disconnectFakeParticipants,
|
disconnectFakeParticipants,
|
||||||
loginUser,
|
loginUser,
|
||||||
startTestServer,
|
startTestServer,
|
||||||
updateRecordingAccessPreferencesInRoom
|
updateRecordingAccessConfigInRoom
|
||||||
} from '../../../helpers/request-helpers.js';
|
} from '../../../helpers/request-helpers.js';
|
||||||
import { RoomData, setupSingleRoom, setupSingleRoomWithRecording } from '../../../helpers/test-scenarios.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;
|
let roomData: RoomData;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@ -188,26 +188,26 @@ describe('Room API Security Tests', () => {
|
|||||||
|
|
||||||
it('should succeed when request includes API key', async () => {
|
it('should succeed when request includes API key', async () => {
|
||||||
const response = await request(app)
|
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);
|
.set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when user is authenticated as admin', async () => {
|
it('should succeed when user is authenticated as admin', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${ROOMS_PATH}/${roomData.room.roomId}/config`)
|
||||||
.set('Cookie', adminCookie);
|
.set('Cookie', adminCookie);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when user is not authenticated', async () => {
|
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);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when participant is moderator', async () => {
|
it('should succeed when participant is moderator', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${ROOMS_PATH}/${roomData.room.roomId}/config`)
|
||||||
.set('Cookie', roomData.moderatorCookie)
|
.set('Cookie', roomData.moderatorCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@ -217,7 +217,7 @@ describe('Room API Security Tests', () => {
|
|||||||
const newRoomData = await setupSingleRoom();
|
const newRoomData = await setupSingleRoom();
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${ROOMS_PATH}/${roomData.room.roomId}/config`)
|
||||||
.set('Cookie', newRoomData.moderatorCookie)
|
.set('Cookie', newRoomData.moderatorCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.MODERATOR);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
@ -225,7 +225,7 @@ describe('Room API Security Tests', () => {
|
|||||||
|
|
||||||
it('should succeed when participant is speaker', async () => {
|
it('should succeed when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${ROOMS_PATH}/${roomData.room.roomId}/config`)
|
||||||
.set('Cookie', roomData.speakerCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@ -235,21 +235,21 @@ describe('Room API Security Tests', () => {
|
|||||||
const newRoomData = await setupSingleRoom();
|
const newRoomData = await setupSingleRoom();
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${ROOMS_PATH}/${roomData.room.roomId}/config`)
|
||||||
.set('Cookie', newRoomData.speakerCookie)
|
.set('Cookie', newRoomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Update Room Preferences Tests', () => {
|
describe('Update Room Config Tests', () => {
|
||||||
const roomPreferences = {
|
const roomConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
};
|
};
|
||||||
|
|
||||||
let roomId: string;
|
let roomId: string;
|
||||||
@ -261,24 +261,22 @@ describe('Room API Security Tests', () => {
|
|||||||
|
|
||||||
it('should succeed when request includes API key', async () => {
|
it('should succeed when request includes API key', async () => {
|
||||||
const response = await request(app)
|
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)
|
.set(INTERNAL_CONFIG.API_KEY_HEADER, MEET_INITIAL_API_KEY)
|
||||||
.send({ preferences: roomPreferences });
|
.send({ config: roomConfig });
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when user is authenticated as admin', async () => {
|
it('should succeed when user is authenticated as admin', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.put(`${ROOMS_PATH}/${roomId}/preferences`)
|
.put(`${ROOMS_PATH}/${roomId}/config`)
|
||||||
.set('Cookie', adminCookie)
|
.set('Cookie', adminCookie)
|
||||||
.send({ preferences: roomPreferences });
|
.send({ config: roomConfig });
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when user is not authenticated', async () => {
|
it('should fail when user is not authenticated', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app).put(`${ROOMS_PATH}/${roomId}/config`).send({ config: roomConfig });
|
||||||
.put(`${ROOMS_PATH}/${roomId}/preferences`)
|
|
||||||
.send({ preferences: roomPreferences });
|
|
||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -308,9 +306,7 @@ describe('Room API Security Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when user is not authenticated', async () => {
|
it('should fail when user is not authenticated', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app).put(`${ROOMS_PATH}/${roomId}/status`).send({ status: 'open' });
|
||||||
.put(`${ROOMS_PATH}/${roomId}/status`)
|
|
||||||
.send({ status: 'open' });
|
|
||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -323,10 +319,7 @@ describe('Room API Security Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessConfigInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER);
|
||||||
roomData.room.roomId,
|
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when no authentication is required and participant is speaker', async () => {
|
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 () => {
|
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)
|
const response = await request(app)
|
||||||
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
||||||
|
|||||||
@ -240,7 +240,7 @@
|
|||||||
color: var(--ov-meet-color-primary);
|
color: var(--ov-meet-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.room-preferences-btn {
|
&.room-config-btn {
|
||||||
color: var(--ov-meet-icon-settings);
|
color: var(--ov-meet-icon-settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,7 @@
|
|||||||
<ov-room-wizard-room-details></ov-room-wizard-room-details>
|
<ov-room-wizard-room-details></ov-room-wizard-room-details>
|
||||||
}
|
}
|
||||||
@case ('recording') {
|
@case ('recording') {
|
||||||
<ov-recording-preferences></ov-recording-preferences>
|
<ov-recording-config></ov-recording-config>
|
||||||
}
|
}
|
||||||
@case ('recordingTrigger') {
|
@case ('recordingTrigger') {
|
||||||
<ov-recording-trigger></ov-recording-trigger>
|
<ov-recording-trigger></ov-recording-trigger>
|
||||||
@ -64,8 +64,8 @@
|
|||||||
@case ('recordingLayout') {
|
@case ('recordingLayout') {
|
||||||
<ov-recording-layout></ov-recording-layout>
|
<ov-recording-layout></ov-recording-layout>
|
||||||
}
|
}
|
||||||
@case ('preferences') {
|
@case ('config') {
|
||||||
<ov-room-preferences></ov-room-preferences>
|
<ov-room-config></ov-room-config>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,11 +10,11 @@ import { WizardNavigationConfig, WizardStep } from '@lib/models';
|
|||||||
import { NavigationService, NotificationService, RoomService, RoomWizardStateService } from '@lib/services';
|
import { NavigationService, NotificationService, RoomService, RoomWizardStateService } from '@lib/services';
|
||||||
import { MeetRoomOptions } from '@lib/typings/ce';
|
import { MeetRoomOptions } from '@lib/typings/ce';
|
||||||
import { RoomBasicCreationComponent } from '../room-basic-creation/room-basic-creation.component';
|
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 { 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 { 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 { RoomWizardRoomDetailsComponent } from './steps/room-details/room-details.component';
|
||||||
import { RoomPreferencesComponent } from './steps/room-preferences/room-preferences.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-room-wizard',
|
selector: 'ov-room-wizard',
|
||||||
@ -29,10 +29,10 @@ import { RoomPreferencesComponent } from './steps/room-preferences/room-preferen
|
|||||||
MatSlideToggleModule,
|
MatSlideToggleModule,
|
||||||
RoomBasicCreationComponent,
|
RoomBasicCreationComponent,
|
||||||
RoomWizardRoomDetailsComponent,
|
RoomWizardRoomDetailsComponent,
|
||||||
RecordingPreferencesComponent,
|
RecordingConfigComponent,
|
||||||
RecordingTriggerComponent,
|
RecordingTriggerComponent,
|
||||||
RecordingLayoutComponent,
|
RecordingLayoutComponent,
|
||||||
RoomPreferencesComponent
|
RoomConfigComponent
|
||||||
],
|
],
|
||||||
templateUrl: './room-wizard.component.html',
|
templateUrl: './room-wizard.component.html',
|
||||||
styleUrl: './room-wizard.component.scss'
|
styleUrl: './room-wizard.component.scss'
|
||||||
@ -89,8 +89,8 @@ export class RoomWizardComponent implements OnInit {
|
|||||||
if (!this.roomId) return;
|
if (!this.roomId) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { roomName, autoDeletionDate, preferences } = await this.roomService.getRoom(this.roomId);
|
const { roomName, autoDeletionDate, config } = await this.roomService.getRoom(this.roomId);
|
||||||
this.existingRoomData = { roomName, autoDeletionDate, preferences };
|
this.existingRoomData = { roomName, autoDeletionDate, config };
|
||||||
if (this.existingRoomData) {
|
if (this.existingRoomData) {
|
||||||
this.isBasicCreation.set(false);
|
this.isBasicCreation.set(false);
|
||||||
}
|
}
|
||||||
@ -154,8 +154,8 @@ export class RoomWizardComponent implements OnInit {
|
|||||||
this.isCreatingRoom.set(true);
|
this.isCreatingRoom.set(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.editMode && this.roomId && roomOptions.preferences) {
|
if (this.editMode && this.roomId && roomOptions.config) {
|
||||||
await this.roomService.updateRoomPreferences(this.roomId, roomOptions.preferences);
|
await this.roomService.updateRoomConfig(this.roomId, roomOptions.config);
|
||||||
await this.navigationService.navigateTo('rooms', undefined, true);
|
await this.navigationService.navigateTo('rooms', undefined, true);
|
||||||
this.notificationService.showSnackbar('Room updated successfully');
|
this.notificationService.showSnackbar('Room updated successfully');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<div class="recording-preferences-step fade-in">
|
<div class="recording-config-step fade-in">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<header class="step-header">
|
<header class="step-header">
|
||||||
<mat-icon class="ov-recording-icon step-icon">video_library</mat-icon>
|
<mat-icon class="ov-recording-icon step-icon">video_library</mat-icon>
|
||||||
<div class="step-title-group">
|
<div class="step-title-group">
|
||||||
<h3 class="step-title">Recording Preferences</h3>
|
<h3 class="step-title">Recording Config</h3>
|
||||||
<p class="step-description">Choose whether to enable recording capabilities for this room</p>
|
<p class="step-description">Choose whether to enable recording capabilities for this room</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
@import '../../../../../../../../../../src/assets/styles/design-tokens';
|
@import '../../../../../../../../../../src/assets/styles/design-tokens';
|
||||||
|
|
||||||
.recording-preferences-step {
|
.recording-config-step {
|
||||||
@include ov-page-content;
|
@include ov-page-content;
|
||||||
@include ov-container;
|
@include ov-container;
|
||||||
|
|
||||||
@ -50,7 +50,6 @@
|
|||||||
padding: var(--ov-meet-spacing-lg) var(--ov-meet-spacing-lg) 0 var(--ov-meet-spacing-lg);
|
padding: var(--ov-meet-spacing-lg) var(--ov-meet-spacing-lg) 0 var(--ov-meet-spacing-lg);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
|
||||||
.access-header {
|
.access-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@ -18,7 +18,7 @@ interface RecordingAccessOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-recording-preferences',
|
selector: 'ov-recording-config',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@ -31,10 +31,10 @@ interface RecordingAccessOption {
|
|||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
SelectableCardComponent
|
SelectableCardComponent
|
||||||
],
|
],
|
||||||
templateUrl: './recording-preferences.component.html',
|
templateUrl: './recording-config.component.html',
|
||||||
styleUrl: './recording-preferences.component.scss'
|
styleUrl: './recording-config.component.scss'
|
||||||
})
|
})
|
||||||
export class RecordingPreferencesComponent implements OnDestroy {
|
export class RecordingConfigComponent implements OnDestroy {
|
||||||
recordingForm: FormGroup;
|
recordingForm: FormGroup;
|
||||||
isAnimatingOut = false;
|
isAnimatingOut = false;
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ export class RecordingPreferencesComponent implements OnDestroy {
|
|||||||
const enabled = formValue.recordingEnabled === 'enabled';
|
const enabled = formValue.recordingEnabled === 'enabled';
|
||||||
|
|
||||||
const stepData: any = {
|
const stepData: any = {
|
||||||
preferences: {
|
config: {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled,
|
enabled,
|
||||||
...(enabled && { allowAccessTo: formValue.allowAccessTo })
|
...(enabled && { allowAccessTo: formValue.allowAccessTo })
|
||||||
}
|
}
|
||||||
@ -1,18 +1,18 @@
|
|||||||
<div class="room-preferences-step fade-in">
|
<div class="room-config-step fade-in">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<header class="step-header">
|
<header class="step-header">
|
||||||
<mat-icon class="ov-room-icon step-icon">video_chat</mat-icon>
|
<mat-icon class="ov-room-icon step-icon">video_chat</mat-icon>
|
||||||
<div class="step-title-group">
|
<div class="step-title-group">
|
||||||
<h3 class="step-title">Room Preferences</h3>
|
<h3 class="step-title">Room Config</h3>
|
||||||
<p class="step-description">Configure additional features and functionality for your room</p>
|
<p class="step-description">Configure additional features and functionality for your room</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Form Section -->
|
<!-- Form Section -->
|
||||||
<main class="step-content">
|
<main class="step-content">
|
||||||
<form [formGroup]="preferencesForm" class="preferences-form">
|
<form [formGroup]="configForm" class="config-form">
|
||||||
<!-- Preferences Cards Grid -->
|
<!-- Config Cards Grid -->
|
||||||
<div class="preferences-grid">
|
<div class="config-grid">
|
||||||
<!-- Chat Settings Card -->
|
<!-- Chat Settings Card -->
|
||||||
<mat-card class="preference-card">
|
<mat-card class="preference-card">
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
@import '../../../../../../../../../../src/assets/styles/design-tokens';
|
@import '../../../../../../../../../../src/assets/styles/design-tokens';
|
||||||
|
|
||||||
.room-preferences-step {
|
.room-config-step {
|
||||||
@include ov-page-content;
|
@include ov-page-content;
|
||||||
@include ov-container;
|
@include ov-container;
|
||||||
|
|
||||||
@ -41,13 +41,13 @@
|
|||||||
.step-content {
|
.step-content {
|
||||||
margin-bottom: var(--ov-meet-spacing-md);
|
margin-bottom: var(--ov-meet-spacing-md);
|
||||||
|
|
||||||
.preferences-form {
|
.config-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.preferences-grid {
|
.config-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||||
gap: var(--ov-meet-spacing-md);
|
gap: var(--ov-meet-spacing-md);
|
||||||
@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
// Responsive design
|
// Responsive design
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
.room-preferences-step {
|
.room-config-step {
|
||||||
// padding: var(--ov-meet-spacing-xs);
|
// padding: var(--ov-meet-spacing-xs);
|
||||||
|
|
||||||
.step-header {
|
.step-header {
|
||||||
@ -131,14 +131,14 @@
|
|||||||
margin-bottom: var(--ov-meet-spacing-md);
|
margin-bottom: var(--ov-meet-spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.preferences-grid {
|
.config-grid {
|
||||||
gap: var(--ov-meet-spacing-sm);
|
gap: var(--ov-meet-spacing-sm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.room-preferences-step {
|
.room-config-step {
|
||||||
.step-header {
|
.step-header {
|
||||||
.step-title-group {
|
.step-title-group {
|
||||||
.step-title {
|
.step-title {
|
||||||
@ -151,7 +151,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.preferences-grid {
|
.config-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +170,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.room-preferences-step {
|
.room-config-step {
|
||||||
.preference-card {
|
.preference-card {
|
||||||
.card-header {
|
.card-header {
|
||||||
.icon-title-group {
|
.icon-title-group {
|
||||||
@ -7,22 +7,22 @@ import { RoomWizardStateService } from '@lib/services';
|
|||||||
import { Subject, takeUntil } from 'rxjs';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-room-preferences',
|
selector: 'ov-room-config',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [ReactiveFormsModule, MatCardModule, MatIconModule, MatSlideToggleModule],
|
imports: [ReactiveFormsModule, MatCardModule, MatIconModule, MatSlideToggleModule],
|
||||||
templateUrl: './room-preferences.component.html',
|
templateUrl: './room-config.component.html',
|
||||||
styleUrl: './room-preferences.component.scss'
|
styleUrl: './room-config.component.scss'
|
||||||
})
|
})
|
||||||
export class RoomPreferencesComponent implements OnDestroy {
|
export class RoomConfigComponent implements OnDestroy {
|
||||||
preferencesForm: FormGroup;
|
configForm: FormGroup;
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
constructor(private wizardService: RoomWizardStateService) {
|
constructor(private wizardService: RoomWizardStateService) {
|
||||||
const currentStep = this.wizardService.currentStep();
|
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);
|
this.saveFormData(value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -34,34 +34,34 @@ export class RoomPreferencesComponent implements OnDestroy {
|
|||||||
|
|
||||||
private saveFormData(formValue: any): void {
|
private saveFormData(formValue: any): void {
|
||||||
const stepData: any = {
|
const stepData: any = {
|
||||||
preferences: {
|
config: {
|
||||||
chatPreferences: {
|
chatConfig: {
|
||||||
enabled: formValue.chatEnabled
|
enabled: formValue.chatEnabled
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: {
|
virtualBackgroundConfig: {
|
||||||
enabled: formValue.virtualBackgroundsEnabled
|
enabled: formValue.virtualBackgroundsEnabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.wizardService.updateStepData('preferences', stepData);
|
this.wizardService.updateStepData('config', stepData);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChatToggleChange(event: any): void {
|
onChatToggleChange(event: any): void {
|
||||||
const isEnabled = event.checked;
|
const isEnabled = event.checked;
|
||||||
this.preferencesForm.patchValue({ chatEnabled: isEnabled });
|
this.configForm.patchValue({ chatEnabled: isEnabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
onVirtualBackgroundToggleChange(event: any): void {
|
onVirtualBackgroundToggleChange(event: any): void {
|
||||||
const isEnabled = event.checked;
|
const isEnabled = event.checked;
|
||||||
this.preferencesForm.patchValue({ virtualBackgroundsEnabled: isEnabled });
|
this.configForm.patchValue({ virtualBackgroundsEnabled: isEnabled });
|
||||||
}
|
}
|
||||||
|
|
||||||
get chatEnabled(): boolean {
|
get chatEnabled(): boolean {
|
||||||
return this.preferencesForm.value.chatEnabled || false;
|
return this.configForm.value.chatEnabled || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get virtualBackgroundsEnabled(): boolean {
|
get virtualBackgroundsEnabled(): boolean {
|
||||||
return this.preferencesForm.value.virtualBackgroundsEnabled || false;
|
return this.configForm.value.virtualBackgroundsEnabled || false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ import {
|
|||||||
import { ILogger, LoggerService } from 'openvidu-components-angular';
|
import { ILogger, LoggerService } from 'openvidu-components-angular';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-room-preferences',
|
selector: 'ov-room-config',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
MatListModule,
|
MatListModule,
|
||||||
@ -109,7 +109,7 @@ export class RoomsComponent implements OnInit {
|
|||||||
this.openRoom(action.rooms[0]);
|
this.openRoom(action.rooms[0]);
|
||||||
break;
|
break;
|
||||||
case 'edit':
|
case 'edit':
|
||||||
await this.editRoomPreferences(action.rooms[0]);
|
await this.editRoomConfig(action.rooms[0]);
|
||||||
break;
|
break;
|
||||||
case 'copyModeratorLink':
|
case 'copyModeratorLink':
|
||||||
this.copyModeratorLink(action.rooms[0]);
|
this.copyModeratorLink(action.rooms[0]);
|
||||||
@ -254,12 +254,12 @@ export class RoomsComponent implements OnInit {
|
|||||||
window.open(room.moderatorUrl, '_blank');
|
window.open(room.moderatorUrl, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async editRoomPreferences(room: MeetRoom) {
|
private async editRoomConfig(room: MeetRoom) {
|
||||||
try {
|
try {
|
||||||
await this.navigationService.navigateTo(`rooms/${room.roomId}/edit`);
|
await this.navigationService.navigateTo(`rooms/${room.roomId}/edit`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.notificationService.showSnackbar('Error navigating to room preferences');
|
this.notificationService.showSnackbar('Error navigating to room config');
|
||||||
this.log.e('Error navigating to room preferences:', error);
|
this.log.e('Error navigating to room config:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ import {
|
|||||||
} from '@lib/typings/ce';
|
} from '@lib/typings/ce';
|
||||||
import {
|
import {
|
||||||
MeetParticipantRoleUpdatedPayload,
|
MeetParticipantRoleUpdatedPayload,
|
||||||
MeetRoomPreferencesUpdatedPayload,
|
MeetRoomConfigUpdatedPayload,
|
||||||
MeetSignalType
|
MeetSignalType
|
||||||
} from '@lib/typings/ce/event.model';
|
} from '@lib/typings/ce/event.model';
|
||||||
import {
|
import {
|
||||||
@ -270,7 +270,7 @@ export class MeetingComponent implements OnInit {
|
|||||||
try {
|
try {
|
||||||
await this.generateParticipantToken();
|
await this.generateParticipantToken();
|
||||||
await this.addParticipantNameToUrl();
|
await this.addParticipantNameToUrl();
|
||||||
await this.roomService.loadRoomPreferences(this.roomId);
|
await this.roomService.loadRoomConfig(this.roomId);
|
||||||
this.showMeeting = true;
|
this.showMeeting = true;
|
||||||
|
|
||||||
// Subscribe to remote participants updates
|
// Subscribe to remote participants updates
|
||||||
@ -357,13 +357,13 @@ export class MeetingComponent implements OnInit {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MeetSignalType.MEET_ROOM_PREFERENCES_UPDATED: {
|
case MeetSignalType.MEET_ROOM_CONFIG_UPDATED: {
|
||||||
// Update room preferences
|
// Update room config
|
||||||
const { preferences } = event as MeetRoomPreferencesUpdatedPayload;
|
const { config } = event as MeetRoomConfigUpdatedPayload;
|
||||||
this.featureConfService.setRoomPreferences(preferences);
|
this.featureConfService.setRoomConfig(config);
|
||||||
|
|
||||||
// Refresh recording token if recording is enabled
|
// Refresh recording token if recording is enabled
|
||||||
if (preferences.recordingPreferences.enabled) {
|
if (config.recordingConfig.enabled) {
|
||||||
try {
|
try {
|
||||||
await this.recordingService.generateRecordingToken(this.roomId, this.roomSecret);
|
await this.recordingService.generateRecordingToken(this.roomId, this.roomSecret);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { computed, Injectable, signal } from '@angular/core';
|
import { computed, Injectable, signal } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
MeetRoomPreferences,
|
MeetRoomConfig,
|
||||||
ParticipantPermissions,
|
ParticipantPermissions,
|
||||||
ParticipantRole,
|
ParticipantRole,
|
||||||
RecordingPermissions,
|
RecordingPermissions,
|
||||||
@ -57,7 +57,7 @@ const DEFAULT_FEATURES: ApplicationFeatures = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Centralized service to manage feature configuration
|
* Centralized service to manage feature configuration
|
||||||
* based on room preferences and participant permissions
|
* based on room config and participant permissions
|
||||||
*/
|
*/
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -66,7 +66,7 @@ export class FeatureConfigurationService {
|
|||||||
protected log;
|
protected log;
|
||||||
|
|
||||||
// Signals to handle reactive
|
// Signals to handle reactive
|
||||||
protected roomPreferences = signal<MeetRoomPreferences | undefined>(undefined);
|
protected roomConfig = signal<MeetRoomConfig | undefined>(undefined);
|
||||||
protected participantPermissions = signal<ParticipantPermissions | undefined>(undefined);
|
protected participantPermissions = signal<ParticipantPermissions | undefined>(undefined);
|
||||||
protected participantRole = signal<ParticipantRole | undefined>(undefined);
|
protected participantRole = signal<ParticipantRole | undefined>(undefined);
|
||||||
protected recordingPermissions = signal<RecordingPermissions | undefined>(undefined);
|
protected recordingPermissions = signal<RecordingPermissions | undefined>(undefined);
|
||||||
@ -74,7 +74,7 @@ export class FeatureConfigurationService {
|
|||||||
// Computed signal to derive features based on current configurations
|
// Computed signal to derive features based on current configurations
|
||||||
public readonly features = computed<ApplicationFeatures>(() =>
|
public readonly features = computed<ApplicationFeatures>(() =>
|
||||||
this.calculateFeatures(
|
this.calculateFeatures(
|
||||||
this.roomPreferences(),
|
this.roomConfig(),
|
||||||
this.participantPermissions(),
|
this.participantPermissions(),
|
||||||
this.participantRole(),
|
this.participantRole(),
|
||||||
this.recordingPermissions()
|
this.recordingPermissions()
|
||||||
@ -86,11 +86,11 @@ export class FeatureConfigurationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates room preferences
|
* Updates room config
|
||||||
*/
|
*/
|
||||||
setRoomPreferences(preferences: MeetRoomPreferences): void {
|
setRoomConfig(config: MeetRoomConfig): void {
|
||||||
this.log.d('Updating room preferences', preferences);
|
this.log.d('Updating room config', config);
|
||||||
this.roomPreferences.set(preferences);
|
this.roomConfig.set(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +128,7 @@ export class FeatureConfigurationService {
|
|||||||
* Core logic to calculate features based on all configurations
|
* Core logic to calculate features based on all configurations
|
||||||
*/
|
*/
|
||||||
protected calculateFeatures(
|
protected calculateFeatures(
|
||||||
roomPrefs?: MeetRoomPreferences,
|
roomPrefs?: MeetRoomConfig,
|
||||||
participantPerms?: ParticipantPermissions,
|
participantPerms?: ParticipantPermissions,
|
||||||
role?: ParticipantRole,
|
role?: ParticipantRole,
|
||||||
recordingPerms?: RecordingPermissions
|
recordingPerms?: RecordingPermissions
|
||||||
@ -138,9 +138,9 @@ export class FeatureConfigurationService {
|
|||||||
|
|
||||||
// Apply room configurations
|
// Apply room configurations
|
||||||
if (roomPrefs) {
|
if (roomPrefs) {
|
||||||
features.showRecordingPanel = roomPrefs.recordingPreferences.enabled;
|
features.showRecordingPanel = roomPrefs.recordingConfig.enabled;
|
||||||
features.showChat = roomPrefs.chatPreferences.enabled;
|
features.showChat = roomPrefs.chatConfig.enabled;
|
||||||
features.showBackgrounds = roomPrefs.virtualBackgroundPreferences.enabled;
|
features.showBackgrounds = roomPrefs.virtualBackgroundConfig.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply participant permissions (these can restrict enabled features)
|
// Apply participant permissions (these can restrict enabled features)
|
||||||
@ -184,7 +184,7 @@ export class FeatureConfigurationService {
|
|||||||
* Resets all configurations to their initial values
|
* Resets all configurations to their initial values
|
||||||
*/
|
*/
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this.roomPreferences.set(undefined);
|
this.roomConfig.set(undefined);
|
||||||
this.participantPermissions.set(undefined);
|
this.participantPermissions.set(undefined);
|
||||||
this.participantRole.set(undefined);
|
this.participantRole.set(undefined);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,12 @@ import { Injectable } from '@angular/core';
|
|||||||
import { FeatureConfigurationService, HttpService, ParticipantService, SessionStorageService } from '@lib/services';
|
import { FeatureConfigurationService, HttpService, ParticipantService, SessionStorageService } from '@lib/services';
|
||||||
import {
|
import {
|
||||||
MeetRoom,
|
MeetRoom,
|
||||||
|
MeetRoomConfig,
|
||||||
MeetRoomDeletionPolicyWithMeeting,
|
MeetRoomDeletionPolicyWithMeeting,
|
||||||
MeetRoomDeletionPolicyWithRecordings,
|
MeetRoomDeletionPolicyWithRecordings,
|
||||||
MeetRoomDeletionSuccessCode,
|
MeetRoomDeletionSuccessCode,
|
||||||
MeetRoomFilters,
|
MeetRoomFilters,
|
||||||
MeetRoomOptions,
|
MeetRoomOptions,
|
||||||
MeetRoomPreferences,
|
|
||||||
MeetRoomRoleAndPermissions,
|
MeetRoomRoleAndPermissions,
|
||||||
MeetRoomStatus
|
MeetRoomStatus
|
||||||
} from '@lib/typings/ce';
|
} 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
|
* @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<MeetRoomPreferences> {
|
async getRoomConfig(roomId: string): Promise<MeetRoomConfig> {
|
||||||
this.log.d('Fetching room preferences for roomId:', roomId);
|
this.log.d('Fetching room config for roomId:', roomId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const path = `${this.ROOMS_API}/${roomId}/preferences`;
|
const path = `${this.ROOMS_API}/${roomId}/config`;
|
||||||
const headers = this.participantService.getParticipantRoleHeader();
|
const headers = this.participantService.getParticipantRoleHeader();
|
||||||
const preferences = await this.httpService.getRequest<MeetRoomPreferences>(path, headers);
|
const config = await this.httpService.getRequest<MeetRoomConfig>(path, headers);
|
||||||
return preferences;
|
return config;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.log.e('Error fetching room preferences', error);
|
this.log.e('Error fetching room config', error);
|
||||||
throw new Error(`Failed to fetch room preferences for roomId: ${roomId}`);
|
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
|
* @param roomId - The unique identifier of the room
|
||||||
*/
|
*/
|
||||||
async loadRoomPreferences(roomId: string): Promise<void> {
|
async loadRoomConfig(roomId: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const preferences = await this.getRoomPreferences(roomId);
|
const config = await this.getRoomConfig(roomId);
|
||||||
this.featureConfService.setRoomPreferences(preferences);
|
this.featureConfService.setRoomConfig(config);
|
||||||
console.log('Room preferences loaded:', preferences);
|
console.log('Room config loaded:', config);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.log.e('Error loading room preferences', error);
|
this.log.e('Error loading room config', error);
|
||||||
throw new Error('Failed to load room preferences');
|
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 roomId - The unique identifier of the room
|
||||||
* @param preferences - The room preferences to be saved.
|
* @param config - The room config to be saved.
|
||||||
* @returns A promise that resolves when the preferences have been saved.
|
* @returns A promise that resolves when the config have been saved.
|
||||||
*/
|
*/
|
||||||
async updateRoomPreferences(roomId: string, preferences: MeetRoomPreferences): Promise<void> {
|
async updateRoomConfig(roomId: string, config: MeetRoomConfig): Promise<void> {
|
||||||
this.log.d('Saving room preferences', preferences);
|
this.log.d('Saving room config', config);
|
||||||
const path = `${this.ROOMS_API}/${roomId}/preferences`;
|
const path = `${this.ROOMS_API}/${roomId}/config`;
|
||||||
await this.httpService.putRequest(path, { preferences });
|
await this.httpService.putRequest(path, { config });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,20 +3,20 @@ import { AbstractControl, FormBuilder, ValidationErrors, Validators } from '@ang
|
|||||||
import { WizardNavigationConfig, WizardStep } from '@lib/models';
|
import { WizardNavigationConfig, WizardStep } from '@lib/models';
|
||||||
import {
|
import {
|
||||||
MeetRecordingAccess,
|
MeetRecordingAccess,
|
||||||
|
MeetRoomConfig,
|
||||||
MeetRoomDeletionPolicyWithMeeting,
|
MeetRoomDeletionPolicyWithMeeting,
|
||||||
MeetRoomDeletionPolicyWithRecordings,
|
MeetRoomDeletionPolicyWithRecordings,
|
||||||
MeetRoomOptions,
|
MeetRoomOptions
|
||||||
MeetRoomPreferences
|
|
||||||
} from '@lib/typings/ce';
|
} from '@lib/typings/ce';
|
||||||
|
|
||||||
// Default room preferences following the app's defaults
|
// Default room config following the app's defaults
|
||||||
const DEFAULT_PREFERENCES: MeetRoomPreferences = {
|
const DEFAULT_CONFIG: MeetRoomConfig = {
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,7 +32,7 @@ export class RoomWizardStateService {
|
|||||||
private _visibleSteps = computed(() => this._steps().filter((step) => step.isVisible));
|
private _visibleSteps = computed(() => this._steps().filter((step) => step.isVisible));
|
||||||
private _currentStepIndex = signal<number>(0);
|
private _currentStepIndex = signal<number>(0);
|
||||||
private _roomOptions = signal<MeetRoomOptions>({
|
private _roomOptions = signal<MeetRoomOptions>({
|
||||||
preferences: DEFAULT_PREFERENCES
|
config: DEFAULT_CONFIG
|
||||||
});
|
});
|
||||||
|
|
||||||
public readonly steps = computed(() => this._steps());
|
public readonly steps = computed(() => this._steps());
|
||||||
@ -60,9 +60,9 @@ export class RoomWizardStateService {
|
|||||||
// Initialize room options with defaults merged with existing data
|
// Initialize room options with defaults merged with existing data
|
||||||
const initialRoomOptions: MeetRoomOptions = {
|
const initialRoomOptions: MeetRoomOptions = {
|
||||||
...existingData,
|
...existingData,
|
||||||
preferences: {
|
config: {
|
||||||
...DEFAULT_PREFERENCES,
|
...DEFAULT_CONFIG,
|
||||||
...(existingData?.preferences || {})
|
...(existingData?.config || {})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -156,10 +156,8 @@ export class RoomWizardStateService {
|
|||||||
isActive: editMode, // Only active in edit mode
|
isActive: editMode, // Only active in edit mode
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
formGroup: this.formBuilder.group({
|
formGroup: this.formBuilder.group({
|
||||||
recordingEnabled: initialRoomOptions.preferences!.recordingPreferences.enabled
|
recordingEnabled: initialRoomOptions.config!.recordingConfig.enabled ? 'enabled' : 'disabled',
|
||||||
? 'enabled'
|
allowAccessTo: initialRoomOptions.config!.recordingConfig.allowAccessTo
|
||||||
: 'disabled',
|
|
||||||
allowAccessTo: initialRoomOptions.preferences!.recordingPreferences.allowAccessTo
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -183,14 +181,14 @@ export class RoomWizardStateService {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'preferences',
|
id: 'config',
|
||||||
label: 'Room Features',
|
label: 'Room Features',
|
||||||
isCompleted: editMode, // In edit mode, all editable steps are completed
|
isCompleted: editMode, // In edit mode, all editable steps are completed
|
||||||
isActive: false,
|
isActive: false,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
formGroup: this.formBuilder.group({
|
formGroup: this.formBuilder.group({
|
||||||
chatEnabled: initialRoomOptions.preferences!.chatPreferences.enabled,
|
chatEnabled: initialRoomOptions.config!.chatConfig.enabled,
|
||||||
virtualBackgroundsEnabled: initialRoomOptions.preferences!.virtualBackgroundPreferences.enabled
|
virtualBackgroundsEnabled: initialRoomOptions.config!.virtualBackgroundConfig.enabled
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -234,13 +232,13 @@ export class RoomWizardStateService {
|
|||||||
case 'recording':
|
case 'recording':
|
||||||
updatedOptions = {
|
updatedOptions = {
|
||||||
...currentOptions,
|
...currentOptions,
|
||||||
preferences: {
|
config: {
|
||||||
...currentOptions.preferences,
|
...currentOptions.config,
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
...currentOptions.preferences?.recordingPreferences,
|
...currentOptions.config?.recordingConfig,
|
||||||
...stepData.preferences?.recordingPreferences
|
...stepData.config?.recordingConfig
|
||||||
}
|
}
|
||||||
} as MeetRoomPreferences
|
} as MeetRoomConfig
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'recordingTrigger':
|
case 'recordingTrigger':
|
||||||
@ -248,24 +246,24 @@ export class RoomWizardStateService {
|
|||||||
// These steps don't update room options
|
// These steps don't update room options
|
||||||
updatedOptions = { ...currentOptions };
|
updatedOptions = { ...currentOptions };
|
||||||
break;
|
break;
|
||||||
case 'preferences':
|
case 'config':
|
||||||
updatedOptions = {
|
updatedOptions = {
|
||||||
...currentOptions,
|
...currentOptions,
|
||||||
preferences: {
|
config: {
|
||||||
...currentOptions.preferences,
|
...currentOptions.config,
|
||||||
chatPreferences: {
|
chatConfig: {
|
||||||
...currentOptions.preferences?.chatPreferences,
|
...currentOptions.config?.chatConfig,
|
||||||
...stepData.preferences?.chatPreferences
|
...stepData.config?.chatConfig
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: {
|
virtualBackgroundConfig: {
|
||||||
...currentOptions.preferences?.virtualBackgroundPreferences,
|
...currentOptions.config?.virtualBackgroundConfig,
|
||||||
...stepData.preferences?.virtualBackgroundPreferences
|
...stepData.config?.virtualBackgroundConfig
|
||||||
},
|
},
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
...currentOptions.preferences?.recordingPreferences,
|
...currentOptions.config?.recordingConfig,
|
||||||
...stepData.preferences?.recordingPreferences
|
...stepData.config?.recordingConfig
|
||||||
}
|
}
|
||||||
} as MeetRoomPreferences
|
} as MeetRoomConfig
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -284,8 +282,8 @@ export class RoomWizardStateService {
|
|||||||
private updateStepsVisibility(): void {
|
private updateStepsVisibility(): void {
|
||||||
const currentSteps = this._steps();
|
const currentSteps = this._steps();
|
||||||
const currentOptions = this._roomOptions();
|
const currentOptions = this._roomOptions();
|
||||||
// TODO: Uncomment when recording preferences are implemented
|
// TODO: Uncomment when recording config is fully implemented
|
||||||
const recordingEnabled = false; // currentOptions.preferences?.recordingPreferences.enabled ?? false;
|
const recordingEnabled = false; // currentOptions.config?.recordingConfig.enabled ?? false;
|
||||||
|
|
||||||
// Update recording steps visibility based on recordingEnabled
|
// Update recording steps visibility based on recordingEnabled
|
||||||
const updatedSteps = currentSteps.map((step) => {
|
const updatedSteps = currentSteps.map((step) => {
|
||||||
@ -414,7 +412,7 @@ export class RoomWizardStateService {
|
|||||||
*/
|
*/
|
||||||
resetWizard(): void {
|
resetWizard(): void {
|
||||||
const defaultOptions: MeetRoomOptions = {
|
const defaultOptions: MeetRoomOptions = {
|
||||||
preferences: DEFAULT_PREFERENCES
|
config: DEFAULT_CONFIG
|
||||||
};
|
};
|
||||||
this._roomOptions.set(defaultOptions);
|
this._roomOptions.set(defaultOptions);
|
||||||
this._steps.set([]);
|
this._steps.set([]);
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
"test:e2e-core-room": "playwright test tests/e2e/core/room.test.ts",
|
"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-events": "playwright test tests/e2e/core/events.test.ts",
|
||||||
"test:e2e-core-webhooks": "playwright test tests/e2e/core/webhooks.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",
|
"test:e2e-recording-access": "playwright test tests/e2e/recording-access.test.ts",
|
||||||
"lint": "eslint 'src/**/*.ts'"
|
"lint": "eslint 'src/**/*.ts'"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { test } from '@playwright/test';
|
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 { MEET_TESTAPP_URL } from '../config';
|
||||||
import {
|
import {
|
||||||
accessRoomAs,
|
accessRoomAs,
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
loginAsAdmin,
|
loginAsAdmin,
|
||||||
prepareForJoiningRoom,
|
prepareForJoiningRoom,
|
||||||
startStopRecording,
|
startStopRecording,
|
||||||
updateRoomPreferences,
|
updateRoomConfig,
|
||||||
viewRecordingsAs,
|
viewRecordingsAs,
|
||||||
waitForElementInIframe
|
waitForElementInIframe
|
||||||
} from '../helpers/function-helpers';
|
} 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 }) => {
|
test('should moderator not be able to access recording when access level is set to admin', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN
|
allowAccessTo: MeetRecordingAccess.ADMIN
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
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 }) => {
|
test('should speaker not be able to access recording when access level is set to admin', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN
|
allowAccessTo: MeetRecordingAccess.ADMIN
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
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 }) => {
|
test('should allow moderator to access recording when access level is set to moderator', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
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 }) => {
|
test('should speaker not be able to access recording when access level is set to moderator', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
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 }) => {
|
test('should allow moderators to access recording when access level is set to speaker', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
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 }) => {
|
test('should allow speaker to access recording when access level is set to speaker', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
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 { MEET_TESTAPP_URL } from '../config';
|
||||||
import {
|
import {
|
||||||
applyVirtualBackground,
|
applyVirtualBackground,
|
||||||
@ -14,14 +14,14 @@ import {
|
|||||||
loginAsAdmin,
|
loginAsAdmin,
|
||||||
openMoreOptionsMenu,
|
openMoreOptionsMenu,
|
||||||
prepareForJoiningRoom,
|
prepareForJoiningRoom,
|
||||||
updateRoomPreferences,
|
updateRoomConfig,
|
||||||
waitForElementInIframe,
|
waitForElementInIframe,
|
||||||
waitForVirtualBackgroundToApply
|
waitForVirtualBackgroundToApply
|
||||||
} from '../helpers/function-helpers';
|
} from '../helpers/function-helpers';
|
||||||
|
|
||||||
let subscribedToAppErrors = false;
|
let subscribedToAppErrors = false;
|
||||||
|
|
||||||
test.describe('UI Feature Preferences Tests', () => {
|
test.describe('UI Feature Config Tests', () => {
|
||||||
let roomId: string;
|
let roomId: string;
|
||||||
let participantName: string;
|
let participantName: string;
|
||||||
let adminCookie: 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 }) => {
|
test('should show chat button when chat is enabled', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -97,15 +97,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
test('should hide chat button when chat is disabled', async ({ page }) => {
|
test('should hide chat button when chat is disabled', async ({ page }) => {
|
||||||
// Disable chat via API
|
// Disable chat via API
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: false },
|
chatConfig: { enabled: false },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -126,15 +126,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
test.describe('Recording Feature', () => {
|
test.describe('Recording Feature', () => {
|
||||||
test('should show recording button for moderators', async ({ page }) => {
|
test('should show recording button for moderators', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -160,15 +160,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should not show recording button for speaker', async ({ page }) => {
|
test('should not show recording button for speaker', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
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 }) => {
|
test('should not show recording button for moderators when recording is disabled', async ({ page }) => {
|
||||||
// Disable recording via API
|
// Disable recording via API
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -226,15 +226,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
});
|
});
|
||||||
test('should show virtual background button when enabled', async ({ page }) => {
|
test('should show virtual background button when enabled', async ({ page }) => {
|
||||||
// Ensure virtual backgrounds are enabled
|
// Ensure virtual backgrounds are enabled
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -255,15 +255,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
test('should hide virtual background button when disabled', async ({ page }) => {
|
test('should hide virtual background button when disabled', async ({ page }) => {
|
||||||
// Disable virtual backgrounds via API
|
// Disable virtual backgrounds via API
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundConfig: { enabled: false }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -284,15 +284,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
page
|
page
|
||||||
}) => {
|
}) => {
|
||||||
// Ensure virtual backgrounds are enabled
|
// Ensure virtual backgrounds are enabled
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -305,15 +305,15 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
await waitForVirtualBackgroundToApply(page);
|
await waitForVirtualBackgroundToApply(page);
|
||||||
|
|
||||||
// Now disable virtual backgrounds
|
// Now disable virtual backgrounds
|
||||||
await updateRoomPreferences(
|
await updateRoomConfig(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundConfig: { enabled: false }
|
||||||
},
|
},
|
||||||
adminCookie
|
adminCookie
|
||||||
);
|
);
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { expect, FrameLocator, Locator, Page } from '@playwright/test';
|
import { expect, FrameLocator, Locator, Page } from '@playwright/test';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { PNG } from 'pngjs';
|
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';
|
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
|
// Helper function to get default room config
|
||||||
const getDefaultRoomPreferences = (): MeetRoomPreferences => ({
|
const getDefaultRoomConfig = (): MeetRoomConfig => ({
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatConfig: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundConfig: { enabled: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Helper function to create a room for testing
|
// Helper function to create a room for testing
|
||||||
export const createTestRoom = async (
|
export const createTestRoom = async (roomName: string, config: MeetRoomConfig = getDefaultRoomConfig()) => {
|
||||||
roomName: string,
|
|
||||||
preferences: MeetRoomPreferences = getDefaultRoomPreferences()
|
|
||||||
) => {
|
|
||||||
const response = await fetch(`${MEET_API_URL}/api/v1/rooms`, {
|
const response = await fetch(`${MEET_API_URL}/api/v1/rooms`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -112,7 +109,7 @@ export const createTestRoom = async (
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
roomName,
|
roomName,
|
||||||
autoDeletionDate: new Date(Date.now() + 61 * 60 * 1000).getTime(), // 1 hour from now
|
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;
|
return room.roomId;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper function to update room preferences via REST API
|
// Helper function to update room config via REST API
|
||||||
export const updateRoomPreferences = async (roomId: string, preferences: any, adminCookie: string) => {
|
export const updateRoomConfig = async (roomId: string, config: any, adminCookie: string) => {
|
||||||
const response = await fetch(`${MEET_API_URL}/api/v1/rooms/${roomId}/preferences`, {
|
const response = await fetch(`${MEET_API_URL}/api/v1/rooms/${roomId}/config`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Cookie: adminCookie
|
Cookie: adminCookie
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ preferences })
|
body: JSON.stringify({ config })
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
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();
|
return response.json();
|
||||||
|
|||||||
@ -62,7 +62,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Collapsible sections for room creation form */
|
/* Collapsible sections for room creation form */
|
||||||
.preferences-accordion {
|
.config-accordion {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -181,10 +181,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Preferences Accordion -->
|
<!-- Config Accordion -->
|
||||||
<div class="preferences-accordion">
|
<div class="config-accordion">
|
||||||
<div class="accordion" id="preferencesAccordion">
|
<div class="accordion" id="configAccordion">
|
||||||
<!-- Chat Preferences -->
|
<!-- Chat Config -->
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header">
|
<h2 class="accordion-header">
|
||||||
<button
|
<button
|
||||||
@ -194,7 +194,7 @@
|
|||||||
data-bs-target="#chatCollapse"
|
data-bs-target="#chatCollapse"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="chatCollapse"
|
aria-controls="chatCollapse"
|
||||||
data-testid="chat-preferences-toggle"
|
data-testid="chat-config-toggle"
|
||||||
>
|
>
|
||||||
Chat Settings
|
Chat Settings
|
||||||
</button>
|
</button>
|
||||||
@ -202,13 +202,13 @@
|
|||||||
<div
|
<div
|
||||||
id="chatCollapse"
|
id="chatCollapse"
|
||||||
class="accordion-collapse collapse show"
|
class="accordion-collapse collapse show"
|
||||||
data-bs-parent="#preferencesAccordion"
|
data-bs-parent="#configAccordion"
|
||||||
>
|
>
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="preferences.chatPreferences.enabled"
|
name="config.chatConfig.enabled"
|
||||||
id="chat-enabled"
|
id="chat-enabled"
|
||||||
class="form-check-input"
|
class="form-check-input"
|
||||||
checked
|
checked
|
||||||
@ -222,7 +222,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Recording Preferences -->
|
<!-- Recording Config -->
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header">
|
<h2 class="accordion-header">
|
||||||
<button
|
<button
|
||||||
@ -232,7 +232,7 @@
|
|||||||
data-bs-target="#recordingCollapse"
|
data-bs-target="#recordingCollapse"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-controls="recordingCollapse"
|
aria-controls="recordingCollapse"
|
||||||
data-testid="recording-preferences-toggle"
|
data-testid="recording-config-toggle"
|
||||||
>
|
>
|
||||||
Recording Settings
|
Recording Settings
|
||||||
</button>
|
</button>
|
||||||
@ -240,13 +240,13 @@
|
|||||||
<div
|
<div
|
||||||
id="recordingCollapse"
|
id="recordingCollapse"
|
||||||
class="accordion-collapse collapse"
|
class="accordion-collapse collapse"
|
||||||
data-bs-parent="#preferencesAccordion"
|
data-bs-parent="#configAccordion"
|
||||||
>
|
>
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="form-check mb-2">
|
<div class="form-check mb-2">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="preferences.recordingPreferences.enabled"
|
name="config.recordingConfig.enabled"
|
||||||
id="recording-enabled"
|
id="recording-enabled"
|
||||||
class="form-check-input"
|
class="form-check-input"
|
||||||
checked
|
checked
|
||||||
@ -262,7 +262,7 @@
|
|||||||
>Recording Access Level</label
|
>Recording Access Level</label
|
||||||
>
|
>
|
||||||
<select
|
<select
|
||||||
name="preferences.recordingPreferences.allowAccessTo"
|
name="config.recordingConfig.allowAccessTo"
|
||||||
id="recording-access"
|
id="recording-access"
|
||||||
class="form-select"
|
class="form-select"
|
||||||
data-testid="recording-access-select"
|
data-testid="recording-access-select"
|
||||||
@ -280,7 +280,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Virtual Background Preferences -->
|
<!-- Virtual Background Config -->
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header">
|
<h2 class="accordion-header">
|
||||||
<button
|
<button
|
||||||
@ -290,7 +290,7 @@
|
|||||||
data-bs-target="#backgroundCollapse"
|
data-bs-target="#backgroundCollapse"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-controls="backgroundCollapse"
|
aria-controls="backgroundCollapse"
|
||||||
data-testid="background-preferences-toggle"
|
data-testid="background-config-toggle"
|
||||||
>
|
>
|
||||||
Virtual Background Settings
|
Virtual Background Settings
|
||||||
</button>
|
</button>
|
||||||
@ -298,13 +298,13 @@
|
|||||||
<div
|
<div
|
||||||
id="backgroundCollapse"
|
id="backgroundCollapse"
|
||||||
class="accordion-collapse collapse"
|
class="accordion-collapse collapse"
|
||||||
data-bs-parent="#preferencesAccordion"
|
data-bs-parent="#configAccordion"
|
||||||
>
|
>
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="preferences.virtualBackgroundPreferences.enabled"
|
name="config.virtualBackgroundConfig.enabled"
|
||||||
id="virtual-background-enabled"
|
id="virtual-background-enabled"
|
||||||
class="form-check-input"
|
class="form-check-input"
|
||||||
checked
|
checked
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { getAllRooms, createRoom, deleteRoom, deleteAllRooms } from '../services/roomService';
|
|
||||||
import { deleteAllRecordings, getAllRecordings } from '../services/recordingService';
|
import { deleteAllRecordings, getAllRecordings } from '../services/recordingService';
|
||||||
|
import { createRoom, deleteAllRooms, deleteRoom, getAllRooms } from '../services/roomService';
|
||||||
|
|
||||||
export const getHome = async (_req: Request, res: Response) => {
|
export const getHome = async (_req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
@ -38,12 +38,12 @@ export const postCreateRoom = async (req: Request, res: Response) => {
|
|||||||
try {
|
try {
|
||||||
console.log('Creating room with body:', JSON.stringify(req.body, null, 2));
|
console.log('Creating room with body:', JSON.stringify(req.body, null, 2));
|
||||||
const { roomName, autoDeletionDate } = req.body;
|
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 });
|
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);
|
console.log('Room created successfully:', result);
|
||||||
res.redirect('/');
|
res.redirect('/');
|
||||||
} catch (error) {
|
} 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 processFormConfig = (body: any): any => {
|
||||||
const preferences = {
|
const config = {
|
||||||
chatPreferences: {
|
chatConfig: {
|
||||||
enabled: body['preferences.chatPreferences.enabled'] === 'on'
|
enabled: body['config.chatConfig.enabled'] === 'on'
|
||||||
},
|
},
|
||||||
recordingPreferences: {
|
recordingConfig: {
|
||||||
enabled: body['preferences.recordingPreferences.enabled'] === 'on',
|
enabled: body['config.recordingConfig.enabled'] === 'on',
|
||||||
// Only include allowAccessTo if recording is enabled
|
// Only include allowAccessTo if recording is enabled
|
||||||
...(body['preferences.recordingPreferences.enabled'] === 'on' && {
|
...(body['config.recordingConfig.enabled'] === 'on' && {
|
||||||
allowAccessTo: body['preferences.recordingPreferences.allowAccessTo'] || 'admin_moderator_speaker'
|
allowAccessTo: body['config.recordingConfig.allowAccessTo'] || 'admin_moderator_speaker'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: {
|
virtualBackgroundConfig: {
|
||||||
enabled: body['preferences.virtualBackgroundPreferences.enabled'] === 'on'
|
enabled: body['config.virtualBackgroundConfig.enabled'] === 'on'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return preferences;
|
return config;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { ParticipantRole } from './participant.js';
|
import { ParticipantRole } from './participant.js';
|
||||||
import { MeetRoomPreferences } from './room-preferences.js';
|
import { MeetRoomConfig } from './room-config.js';
|
||||||
|
|
||||||
export enum MeetSignalType {
|
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'
|
MEET_PARTICIPANT_ROLE_UPDATED = 'meet_participant_role_updated'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MeetRoomPreferencesUpdatedPayload {
|
export interface MeetRoomConfigUpdatedPayload {
|
||||||
roomId: string;
|
roomId: string;
|
||||||
preferences: MeetRoomPreferences;
|
config: MeetRoomConfig;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,4 +20,4 @@ export interface MeetParticipantRoleUpdatedPayload {
|
|||||||
timestamp: number;
|
timestamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MeetSignalPayload = MeetRoomPreferencesUpdatedPayload | MeetParticipantRoleUpdatedPayload;
|
export type MeetSignalPayload = MeetRoomConfigUpdatedPayload | MeetParticipantRoleUpdatedPayload;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ export * from './permissions/openvidu-permissions.js';
|
|||||||
export * from './participant.js';
|
export * from './participant.js';
|
||||||
export * from './user.js';
|
export * from './user.js';
|
||||||
|
|
||||||
export * from './room-preferences.js';
|
export * from './room-config.js';
|
||||||
export * from './room.js';
|
export * from './room.js';
|
||||||
export * from './recording.model.js';
|
export * from './recording.model.js';
|
||||||
export * from './webhook.model.js';
|
export * from './webhook.model.js';
|
||||||
|
|||||||
30
typings/src/room-config.ts
Normal file
30
typings/src/room-config.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import { ParticipantPermissions, ParticipantRole } from './participant.js';
|
import { ParticipantPermissions, ParticipantRole } from './participant.js';
|
||||||
import { MeetRoomPreferences } from './room-preferences.js';
|
import { MeetRoomConfig } from './room-config.js';
|
||||||
|
|
||||||
interface BaseRoomOptions {
|
interface BaseRoomOptions {
|
||||||
roomName?: string;
|
roomName?: string;
|
||||||
autoDeletionDate?: number;
|
autoDeletionDate?: number;
|
||||||
autoDeletionPolicy?: MeetRoomAutoDeletionPolicy;
|
autoDeletionPolicy?: MeetRoomAutoDeletionPolicy;
|
||||||
preferences?: MeetRoomPreferences;
|
config?: MeetRoomConfig;
|
||||||
// maxParticipants?: number | null;
|
// maxParticipants?: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ export interface MeetRoom extends BaseRoomOptions {
|
|||||||
roomId: string;
|
roomId: string;
|
||||||
roomName: string;
|
roomName: string;
|
||||||
creationDate: number;
|
creationDate: number;
|
||||||
preferences: MeetRoomPreferences;
|
config: MeetRoomConfig;
|
||||||
moderatorUrl: string;
|
moderatorUrl: string;
|
||||||
speakerUrl: string;
|
speakerUrl: string;
|
||||||
status: MeetRoomStatus;
|
status: MeetRoomStatus;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user