diff --git a/meet-ce/backend/src/helpers/room.helper.ts b/meet-ce/backend/src/helpers/room.helper.ts index c83b2c32..06535d5c 100644 --- a/meet-ce/backend/src/helpers/room.helper.ts +++ b/meet-ce/backend/src/helpers/room.helper.ts @@ -1,11 +1,12 @@ -import { MeetRoom, MeetRoomOptions } from '@openvidu-meet/typings'; +import { MeetRoom, MeetRoomMemberPermissions, MeetRoomOptions } from '@openvidu-meet/typings'; import { INTERNAL_CONFIG } from '../config/internal-config.js'; import { MEET_ENV } from '../environment.js'; import { MEET_ROOM_EXPANDABLE_FIELDS, MeetRoomCollapsibleProperties, MeetRoomExpandableProperties, - MeetRoomField + MeetRoomField, + SENSITIVE_ROOM_FIELDS_ENTRIES } from '../models/room-request.js'; export class MeetRoomHelper { @@ -219,4 +220,35 @@ export class MeetRoomHelper { return filteredRoom as unknown as MeetRoom; } + + /** + * Applies permission filtering to a MeetRoom object by removing sensitive fields based on the provided permissions. + * @param room + * @param permissions + * @returns + */ + static applyPermissionFiltering(room: MeetRoom, permissions: MeetRoomMemberPermissions): MeetRoom { + if (!room || !permissions || SENSITIVE_ROOM_FIELDS_ENTRIES.length === 0) { + return room; + } + + let filteredRoom: MeetRoom | undefined; + + for (const [permissionKey, fields] of SENSITIVE_ROOM_FIELDS_ENTRIES) { + if (!fields?.length) { + continue; + } + + if (permissions[permissionKey]) { + continue; + } + + filteredRoom ??= { ...room }; + fields.forEach((field) => { + delete (filteredRoom as Partial)[field]; + }); + } + + return filteredRoom ?? room; + } } diff --git a/meet-ce/backend/src/models/room-request.ts b/meet-ce/backend/src/models/room-request.ts index 4f0c6f3c..c323ac4a 100644 --- a/meet-ce/backend/src/models/room-request.ts +++ b/meet-ce/backend/src/models/room-request.ts @@ -1,4 +1,4 @@ -import { MeetRoom, MeetRoomStatus, SortAndPagination } from '@openvidu-meet/typings'; +import { MeetRoom, MeetRoomMemberPermissions, MeetRoomStatus, SortAndPagination } from '@openvidu-meet/typings'; /** * List of all valid fields that can be selected from a MeetRoom. @@ -42,6 +42,18 @@ export type MeetRoomCollapsibleProperties = MeetRoomExpandableProperties; */ export type MeetRoomField = (typeof MEET_ROOM_FIELDS)[number]; +/** + * Sensitive fields of a MeetRoom that require specific permissions to be viewed. + */ +export const SENSITIVE_ROOM_FIELDS_BY_PERMISSION: Partial> = { + canShareAccessLinks: ['anonymous'] +}; + +export const SENSITIVE_ROOM_FIELDS_ENTRIES = Object.entries(SENSITIVE_ROOM_FIELDS_BY_PERMISSION) as ReadonlyArray<[ + keyof MeetRoomMemberPermissions, + MeetRoomField[] +]>; + /** * Filters for querying rooms with pagination, sorting, field selection, and expand support. */ diff --git a/meet-ce/backend/src/services/room.service.ts b/meet-ce/backend/src/services/room.service.ts index 9280ed83..6a37c6ea 100644 --- a/meet-ce/backend/src/services/room.service.ts +++ b/meet-ce/backend/src/services/room.service.ts @@ -34,7 +34,10 @@ import { internalError, OpenViduMeetError } from '../models/error.model.js'; -import { MeetRoomFilters, MeetRoomResponseOptions } from '../models/room-request.js'; +import { + MeetRoomFilters, + MeetRoomResponseOptions +} from '../models/room-request.js'; import { RoomMemberRepository } from '../repositories/room-member.repository.js'; import { RoomRepository } from '../repositories/room.repository.js'; import { FrontendEventService } from './frontend-event.service.js'; @@ -422,7 +425,7 @@ export class RoomService { */ async getMeetRoom(roomId: string, responseOpts?: MeetRoomResponseOptions): Promise { const { collapse, applyPermissionFiltering, fields } = responseOpts || {}; - const room = await this.roomRepository.findByRoomId(roomId, fields); + let room = await this.roomRepository.findByRoomId(roomId, fields); if (!room) { this.logger.error(`Meet room with ID ${roomId} not found.`); @@ -430,12 +433,8 @@ export class RoomService { } if (applyPermissionFiltering) { - // Remove anonymous access info if the authenticated room member does not have permission to share access links const permissions = await this.getAuthenticatedRoomMemberPermissions(roomId); - - if (room.anonymous && !permissions.canShareAccessLinks) { - delete (room as Partial).anonymous; - } + room = MeetRoomHelper.applyPermissionFiltering(room, permissions); } return MeetRoomHelper.applyCollapseProperties(room, collapse);