diff --git a/meet-ce/backend/src/models/room-response.ts b/meet-ce/backend/src/models/room-response.ts new file mode 100644 index 00000000..8ef25d15 --- /dev/null +++ b/meet-ce/backend/src/models/room-response.ts @@ -0,0 +1,23 @@ +import { MeetRoomCollapsibleProperties, MeetRoomField } from '@openvidu-meet/typings'; + +/** + * Options for configuring the response MeetRoom REST API object + */ +export interface MeetRoomServerResponseOptions { + /** + * Array of fields to include in the response. + * If not specified, all fields are included. + */ + fields?: MeetRoomField[]; + /** + * Array of collapsed properties to expand in the response. + * If not specified, no collapsed properties are expanded. + * + */ + collapse?: MeetRoomCollapsibleProperties[]; + /** + * Whether to check permissions for the room. + * If true, sensitive properties will be removed from the response if the requester does not have permission to view them. + */ + applyPermissionFiltering?: boolean; +} diff --git a/meet-ce/backend/src/services/room.service.ts b/meet-ce/backend/src/services/room.service.ts index c3824e37..0e11130e 100644 --- a/meet-ce/backend/src/services/room.service.ts +++ b/meet-ce/backend/src/services/room.service.ts @@ -11,7 +11,6 @@ import { MeetRoomFilters, MeetRoomMemberPermissions, MeetRoomOptions, - MeetRoomResponseOptions, MeetRoomRoles, MeetRoomRolesConfig, MeetRoomStatus, @@ -37,6 +36,7 @@ import { OpenViduMeetError } from '../models/error.model.js'; +import { MeetRoomServerResponseOptions } from '../models/room-response.js'; import { RoomMemberRepository } from '../repositories/room-member.repository.js'; import { RoomRepository } from '../repositories/room.repository.js'; import { FrontendEventService } from './frontend-event.service.js'; @@ -73,13 +73,13 @@ export class RoomService { * Creates an OpenVidu Meet room with the specified options. * * @param {MeetRoomOptions} roomOptions - The options for creating the OpenVidu room. - * @param {MeetRoomResponseOptions} responseOpts - Options for controlling the response format (fields, collapse) + * @param {MeetRoomServerResponseOptions} responseOpts - Options for controlling the response format (fields, collapse) * @returns {Promise} A promise that resolves to the created OpenVidu room. * * @throws {Error} If the room creation fails. * */ - async createMeetRoom(roomOptions: MeetRoomOptions, responseOpts?: MeetRoomResponseOptions): Promise { + async createMeetRoom(roomOptions: MeetRoomOptions, responseOpts?: MeetRoomServerResponseOptions): Promise { const { roomName, autoDeletionDate, autoDeletionPolicy, config, roles, anonymous } = roomOptions; const { collapse, fields } = responseOpts || {}; @@ -422,7 +422,7 @@ export class RoomService { * - applyPermissionFiltering: Whether to check permissions for the room and remove sensitive properties if the requester doesn't have access * @returns A promise that resolves to an {@link MeetRoom} object */ - async getMeetRoom(roomId: string, responseOpts?: MeetRoomResponseOptions): Promise { + async getMeetRoom(roomId: string, responseOpts?: MeetRoomServerResponseOptions): Promise { const { collapse, applyPermissionFiltering, fields } = responseOpts || {}; let room = await this.roomRepository.findByRoomId(roomId, fields); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts index d4cb7390..ef063081 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts @@ -147,7 +147,10 @@ export class MeetingLobbyService { this._state.update((state) => ({ ...state, roomId })); const [room] = await Promise.all([ - this.roomService.getRoom(roomId), + this.roomService.getRoom(roomId, { + fields: ['roomName', 'status', 'config'], + expand: ['config'] + }), this.setBackButtonText(), this.checkForRecordings(), this.initializeParticipantName() diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts index 8501f1eb..cf727e56 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts @@ -20,7 +20,9 @@ export const checkEditableRoomGuard: CanActivateFn = async (route) => { } try { - const room = await roomService.getRoom(roomId); + const room = await roomService.getRoom(roomId, { + fields: ['status'] + }); if (room.status === MeetRoomStatus.ACTIVE_MEETING) { console.warn(`Cannot edit room ${roomId} - active meeting in progress`); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts new file mode 100644 index 00000000..215e58ce --- /dev/null +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts @@ -0,0 +1,17 @@ +import { MeetRoomExpandableProperties, MeetRoomField } from '@openvidu-meet/typings'; + +/** + * Options for configuring the response MeetRoom REST API object + */ +export interface MeetRoomClientResponseOptions { + /** + * Array of fields to include in the response. + * If not specified, all fields are included. + */ + fields?: MeetRoomField[]; + /** + * Array of expandable properties to expand in the response. + * If not specified, expandable properties will not be expanded. + */ + expand?: MeetRoomExpandableProperties[]; +} diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts index 25b573bd..69d44ca7 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts @@ -90,7 +90,10 @@ export class RoomWizardComponent implements OnInit { if (!this.roomId) return; try { - const { roomName, autoDeletionDate, config } = await this.roomService.getRoom(this.roomId); + const { roomName, autoDeletionDate, config } = await this.roomService.getRoom(this.roomId, { + fields: ['roomName', 'autoDeletionDate', 'config'], + expand: ['config'] + }); this.existingRoomData = { roomName, autoDeletionDate, config }; if (this.existingRoomData) { this.isBasicCreation.set(false); @@ -131,7 +134,7 @@ export class RoomWizardComponent implements OnInit { async createRoomBasic(roomName?: string) { try { // Create room with basic config including e2ee: false (default settings) - const { accessUrl } = await this.roomService.createRoom({ roomName }); + const { accessUrl } = await this.roomService.createRoom({ roomName }, { fields: ['accessUrl'] }); // Extract the path and query parameters from the moderator URL and navigate to it const url = new URL(accessUrl); @@ -162,7 +165,7 @@ export class RoomWizardComponent implements OnInit { this.notificationService.showSnackbar('Room updated successfully'); } else { // Create new room - const { accessUrl } = await this.roomService.createRoom(roomOptions); + const { accessUrl } = await this.roomService.createRoom(roomOptions, { fields: ['accessUrl'] }); // Extract the path and query parameters from the moderator URL and navigate to it const url = new URL(accessUrl); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts index abd24a61..32f6cb50 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts @@ -148,7 +148,8 @@ export class RoomsComponent implements OnInit { maxItems: 50, nextPageToken: !refresh ? this.nextPageToken : undefined, sortField: filters.sortField, - sortOrder: filters.sortOrder + sortOrder: filters.sortOrder, + fields: ['roomId', 'roomName', 'status', 'creationDate', 'accessUrl', 'autoDeletionDate'] }; // Apply room ID filter if provided diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts index 0625d944..8b44d8d3 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts @@ -14,6 +14,7 @@ import { import { ILogger, LoggerService } from 'openvidu-components-angular'; import { FeatureConfigurationService } from '../../../shared/services/feature-configuration.service'; import { HttpService } from '../../../shared/services/http.service'; +import { MeetRoomClientResponseOptions } from '../models/room-request'; @Injectable({ providedIn: 'root' @@ -36,8 +37,12 @@ export class RoomService { * @param options - The options for creating the room * @returns A promise that resolves to the created MeetRoom object */ - async createRoom(options?: MeetRoomOptions): Promise { - return this.httpService.postRequest(this.ROOMS_API, options); + async createRoom(options?: MeetRoomOptions, responseOptions?: MeetRoomClientResponseOptions): Promise { + const headers: Record = { + 'X-Fields': responseOptions?.fields ? responseOptions.fields.join(',') : '', + 'X-Expand': responseOptions?.expand ? responseOptions.expand.join(',') : '' + }; + return this.httpService.postRequest(this.ROOMS_API, options, headers); } /** @@ -80,8 +85,17 @@ export class RoomService { * @param roomId - The unique identifier of the room * @return A promise that resolves to the MeetRoom object */ - async getRoom(roomId: string): Promise { - const path = `${this.ROOMS_API}/${roomId}`; + async getRoom(roomId: string, responseOptions?: MeetRoomClientResponseOptions): Promise { + const queryParams = new URLSearchParams(); + if (responseOptions?.fields) { + queryParams.set('fields', responseOptions.fields.join(',')); + } + if (responseOptions?.expand) { + queryParams.set('expand', responseOptions.expand.join(',')); + } + const queryString = queryParams.toString(); + const path = `${this.ROOMS_API}/${roomId}${queryString ? `?${queryString}` : ''}`; + return this.httpService.getRequest(path); } diff --git a/meet-ce/typings/src/room-response.ts b/meet-ce/typings/src/room-response.ts index 092de4e4..02c665ab 100644 --- a/meet-ce/typings/src/room-response.ts +++ b/meet-ce/typings/src/room-response.ts @@ -77,27 +77,6 @@ export interface MeetRoomFilters extends SortAndPagination { expand?: MeetRoomExpandableProperties[]; } -/** - * Options for configuring the response MeetRoom REST API object - */ -export interface MeetRoomResponseOptions { - /** - * Array of fields to include in the response. - * If not specified, all fields are included. - */ - fields?: MeetRoomField[]; - /** - * Array of collapsed properties to expand in the response. - * If not specified, no collapsed properties are expanded. - */ - collapse?: MeetRoomCollapsibleProperties[]; - /** - * Whether to check permissions for the room. - * If true, sensitive properties will be removed from the response if the requester does not have permission to view them. - */ - applyPermissionFiltering?: boolean; -} - /** * Stub that indicates a property can be expanded. */