backend: enhance bulk room and recording deletion logic to check for permissions on each item to delete

This commit is contained in:
juancarmore 2026-01-09 13:36:10 +01:00
parent 5fe71482f7
commit f2a84717e5
2 changed files with 31 additions and 3 deletions

View File

@ -4,6 +4,7 @@ import { EgressStatus, EncodedFileOutput, EncodedFileType, RoomCompositeOptions
import ms from 'ms';
import { Readable } from 'stream';
import { uid } from 'uid';
import { container } from '../config/dependency-injector.config.js';
import { INTERNAL_CONFIG } from '../config/internal-config.js';
import { MEET_ENV } from '../environment.js';
import { RecordingHelper } from '../helpers/recording.helper.js';
@ -32,6 +33,7 @@ import { LiveKitService } from './livekit.service.js';
import { LoggerService } from './logger.service.js';
import { MutexService, RedisLock } from './mutex.service.js';
import { RequestSessionService } from './request-session.service.js';
import { RoomService } from './room.service.js';
import { BlobStorageService } from './storage/blob-storage.service.js';
@injectable()
@ -282,15 +284,17 @@ export class RecordingService {
recordingIds: string[],
roomId?: string
): Promise<{ deleted: string[]; failed: { recordingId: string; error: string }[] }> {
const roomService = container.get(RoomService);
const validRecordingIds: Set<string> = new Set<string>();
const deletedRecordings: Set<string> = new Set<string>();
const failedRecordings: Set<{ recordingId: string; error: string }> = new Set();
for (const recordingId of recordingIds) {
const { roomId: recRoomId } = RecordingHelper.extractInfoFromRecordingId(recordingId);
// If a roomId is provided, only process recordings from that room
if (roomId) {
const { roomId: recRoomId } = RecordingHelper.extractInfoFromRecordingId(recordingId);
if (recRoomId !== roomId) {
this.logger.warn(`Skipping recording '${recordingId}' as it does not belong to room '${roomId}'`);
failedRecordings.add({
@ -299,6 +303,18 @@ export class RecordingService {
});
continue;
}
} else {
// Check room member permissions for each recording if no roomId filter is applied
const permissions = await roomService.getAuthenticatedRoomMemberPermissions(recRoomId);
if (!permissions.canDeleteRecordings) {
this.logger.warn(`Insufficient permissions to delete recording '${recordingId}'`);
failedRecordings.add({
recordingId,
error: `Insufficient permissions to delete recording '${recordingId}'`
});
continue;
}
}
try {

View File

@ -27,6 +27,7 @@ import { MEET_ENV } from '../environment.js';
import { MeetRoomHelper } from '../helpers/room.helper.js';
import {
errorDeletingRoom,
errorInsufficientPermissions,
errorRoomActiveMeeting,
errorRoomNotFound,
internalError,
@ -328,7 +329,7 @@ export class RoomService {
/**
* Retrieves a list of rooms based on the provided filtering, pagination, and sorting options.
*
*
* If the request is made by an authenticated user, access is determined by the user's role:
* - ADMIN: Can see all rooms
* - USER: Can see rooms they own or are members of
@ -716,6 +717,17 @@ export class RoomService {
const roomId = typeof room === 'string' ? room : room.roomId;
try {
const user = this.requestSessionService.getAuthenticatedUser();
// Check permissions if user is authenticated and not an admin
if (user && user.role !== MeetUserRole.ADMIN) {
const isOwner = await this.isRoomOwner(roomId, user.userId);
if (!isOwner) {
throw errorInsufficientPermissions();
}
}
let result;
if (typeof room === 'string') {