backend: Implement configureRecordingTokenAuth middleware and update room route
This commit is contained in:
parent
8bbbee731b
commit
66f2a10406
@ -1,7 +1,12 @@
|
||||
import { AuthMode, ParticipantRole, UserRole } from '@typings-ce';
|
||||
import { AuthMode, MeetRecordingAccess, MeetRoom, ParticipantRole, UserRole } from '@typings-ce';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { container } from '../config/index.js';
|
||||
import { LoggerService, MeetStorageService } from '../services/index.js';
|
||||
import {
|
||||
errorInsufficientPermissions,
|
||||
errorRoomNotFoundOrEmptyRecordings,
|
||||
OpenViduMeetError
|
||||
} from '../models/error.model.js';
|
||||
import { LoggerService, MeetStorageService, RoomService } from '../services/index.js';
|
||||
import { allowAnonymous, apiKeyValidator, tokenAndRoleValidator, withAuth } from './auth.middleware.js';
|
||||
|
||||
/**
|
||||
@ -93,3 +98,77 @@ export const configureRoomAuthorization = async (req: Request, res: Response, ne
|
||||
// If the user is not a moderator, it is not allowed to access the resource
|
||||
return res.status(403).json({ message: 'Insufficient permissions to access this resource' });
|
||||
};
|
||||
|
||||
/**
|
||||
* Middleware to configure authentication based on participant role and authentication mode
|
||||
* for generating a token for retrieving/deleting recordings.
|
||||
*
|
||||
* - If the authentication mode is MODERATORS_ONLY and the participant role is MODERATOR, configure user authentication.
|
||||
* - If the authentication mode is ALL_USERS, configure user authentication.
|
||||
* - Otherwise, allow anonymous access.
|
||||
*/
|
||||
export const configureRecordingTokenAuth = async (req: Request, res: Response, next: NextFunction) => {
|
||||
const logger = container.get(LoggerService);
|
||||
const storageService = container.get(MeetStorageService);
|
||||
const roomService = container.get(RoomService);
|
||||
|
||||
let role: ParticipantRole;
|
||||
|
||||
try {
|
||||
const roomId = req.params.roomId;
|
||||
const { secret } = req.body;
|
||||
const room = await storageService.getArchivedRoomMetadata(roomId);
|
||||
|
||||
if (!room) {
|
||||
// If the room is not found, it means that there are no recordings for that room or the room doesn't exist
|
||||
throw errorRoomNotFoundOrEmptyRecordings(roomId);
|
||||
}
|
||||
|
||||
const recordingAccess = room.preferences!.recordingPreferences.allowAccessTo;
|
||||
|
||||
if (recordingAccess === MeetRecordingAccess.ADMIN) {
|
||||
// Deny request if the room is configured to allow access to recordings only for admins
|
||||
throw errorInsufficientPermissions();
|
||||
}
|
||||
|
||||
role = roomService.getRoomRoleBySecretFromRoom(room as MeetRoom, secret);
|
||||
} catch (error) {
|
||||
logger.error('Error getting room role by secret', error);
|
||||
|
||||
if (error instanceof OpenViduMeetError) {
|
||||
return res.status(error.statusCode).json({ name: error.name, message: error.message });
|
||||
} else {
|
||||
return res.status(500).json({
|
||||
name: 'Room Error',
|
||||
message: 'Internal server error. Room operation failed'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let authMode: AuthMode;
|
||||
|
||||
try {
|
||||
const { securityPreferences } = await storageService.getGlobalPreferences();
|
||||
authMode = securityPreferences.authentication.authMode;
|
||||
} catch (error) {
|
||||
logger.error('Error checking authentication preferences', error);
|
||||
return res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
|
||||
const authValidators = [];
|
||||
|
||||
if (authMode === AuthMode.NONE) {
|
||||
authValidators.push(allowAnonymous);
|
||||
} else {
|
||||
const isModeratorsOnlyMode = authMode === AuthMode.MODERATORS_ONLY && role === ParticipantRole.MODERATOR;
|
||||
const isAllUsersMode = authMode === AuthMode.ALL_USERS;
|
||||
|
||||
if (isModeratorsOnlyMode || isAllUsersMode) {
|
||||
authValidators.push(tokenAndRoleValidator(UserRole.USER));
|
||||
} else {
|
||||
authValidators.push(allowAnonymous);
|
||||
}
|
||||
}
|
||||
|
||||
return withAuth(...authValidators)(req, res, next);
|
||||
};
|
||||
|
||||
@ -5,6 +5,7 @@ import * as roomCtrl from '../controllers/room.controller.js';
|
||||
import {
|
||||
apiKeyValidator,
|
||||
configureCreateRoomAuth,
|
||||
configureRecordingTokenAuth,
|
||||
configureRoomAuthorization,
|
||||
participantTokenValidator,
|
||||
tokenAndRoleValidator,
|
||||
@ -66,7 +67,7 @@ internalRoomRouter.put(
|
||||
|
||||
internalRoomRouter.post(
|
||||
'/:roomId/recording-token',
|
||||
configureCreateRoomAuth,
|
||||
configureRecordingTokenAuth,
|
||||
withValidRoomSecret,
|
||||
roomCtrl.generateRecordingToken
|
||||
);
|
||||
|
||||
@ -249,7 +249,7 @@ export class RoomService {
|
||||
return this.getRoomRoleBySecretFromRoom(room, secret);
|
||||
}
|
||||
|
||||
protected getRoomRoleBySecretFromRoom(room: MeetRoom, secret: string): ParticipantRole {
|
||||
getRoomRoleBySecretFromRoom(room: MeetRoom, secret: string): ParticipantRole {
|
||||
const { moderatorSecret, publisherSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
|
||||
|
||||
switch (secret) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user