backend: Saved room secrets under recording directory when they do not exist

This commit is contained in:
Carlos Santos 2025-04-10 11:33:38 +02:00
parent 11dad40a0b
commit 5345963628
2 changed files with 64 additions and 2 deletions

View File

@ -19,4 +19,26 @@ export class MeetRoomHelper {
roomIdPrefix: room.roomIdPrefix
};
}
/**
* Extracts publisher and moderator secrets from a MeetRoom object's URLs.
*
* This method parses the 'secret' query parameter from both publisher and moderator
* room URLs associated with the meeting room.
*
* @param room - The MeetRoom object containing publisherRoomUrl and moderatorRoomUrl properties
* @returns An object containing the extracted secrets with the following properties:
* - publisherSecret: The secret extracted from the publisher room URL
* - moderatorSecret: The secret extracted from the moderator room URL
*/
static extractSecretsFromRoom(room: MeetRoom): { publisherSecret: string; moderatorSecret: string } {
const { publisherRoomUrl, moderatorRoomUrl } = room;
const publisherUrl = new URL(publisherRoomUrl);
const publisherSecret = publisherUrl.searchParams.get('secret') || '';
const moderatorUrl = new URL(moderatorRoomUrl);
const moderatorSecret = moderatorUrl.searchParams.get('secret') || '';
return { publisherSecret, moderatorSecret };
}
}

View File

@ -12,6 +12,7 @@ import { OpenViduWebhookService } from './openvidu-webhook.service.js';
import { MutexService } from './mutex.service.js';
import { SystemEventService } from './system-event.service.js';
import { SystemEventType } from '../models/system-event.model.js';
import { MeetRoomHelper } from '../helpers/room.helper.js';
@injectable()
export class LivekitWebhookService {
@ -154,7 +155,9 @@ export class LivekitWebhookService {
if (meetRoom.markedForDeletion) {
// If the room is marked for deletion, we need to delete it
this.logger.info(`Deleting room ${room.name} after meeting finished because it was marked for deletion`);
this.logger.info(
`Deleting room ${room.name} after meeting finished because it was marked for deletion`
);
this.roomService.bulkDeleteRooms([room.name], true);
}
} catch (error) {
@ -195,7 +198,10 @@ export class LivekitWebhookService {
// Send webhook notification
switch (webhookAction) {
case 'started':
tasks.push(this.openViduWebhookService.sendRecordingStartedWebhook(recordingInfo));
tasks.push(
this.saveRoomSecretsIfNeeded(roomId),
this.openViduWebhookService.sendRecordingStartedWebhook(recordingInfo)
);
break;
case 'updated':
tasks.push(this.openViduWebhookService.sendRecordingUpdatedWebhook(recordingInfo));
@ -229,6 +235,40 @@ export class LivekitWebhookService {
}
}
/**
* Saves room secrets to an S3 bucket if they haven't been saved already.
*
* This method checks if secrets for the specified room exist in the S3 storage.
* If they don't exist, it retrieves the room information, extracts the publisher
* and moderator secrets, and saves them to an S3 bucket under the path
* `${MEET_S3_RECORDINGS_PREFIX}/.metadata/${roomId}/secrets.json`.
*/
protected async saveRoomSecretsIfNeeded(roomId: string): Promise<void> {
try {
const filePath = `${MEET_S3_RECORDINGS_PREFIX}/.metadata/${roomId}/secrets.json`;
const fileExists = await this.s3Service.exists(filePath);
if (fileExists) {
this.logger.debug(`Room secrets already saved for room ${roomId}`);
return;
}
const room = await this.roomService.getMeetRoom(roomId);
if (room) {
const { publisherSecret, moderatorSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
const secrets = {
publisherSecret,
moderatorSecret
};
await this.s3Service.saveObject(filePath, secrets);
this.logger.debug(`Room secrets saved for room ${roomId}`);
}
} catch (error) {
this.logger.error(`Error saving room secrets for room ${roomId}: ${error}`);
}
}
protected buildMetadataFilePath(recordingId: string): string {
const { roomId, egressId, uid } = RecordingHelper.extractInfoFromRecordingId(recordingId);