From 44fbb25841a80ae2463c8604bbea1a61dab9f123 Mon Sep 17 00:00:00 2001 From: juancarmore Date: Fri, 16 May 2025 19:07:03 +0200 Subject: [PATCH] backend: update security preferences to allow optional requireAuthentication; enhance validation for room creation and recording preferences --- .../security-preferences.controller.ts | 8 +++++++- .../src/middlewares/recording.middleware.ts | 2 +- .../preferences-validator.middleware.ts | 19 +++++++++++++++---- .../room-validator.middleware.ts | 19 +++++++++++++++---- backend/src/middlewares/room.middleware.ts | 4 ++-- .../lib/services/context/context.service.ts | 3 ++- typings/src/global-preferences.ts | 2 +- typings/src/room-preferences.ts | 2 +- 8 files changed, 44 insertions(+), 15 deletions(-) diff --git a/backend/src/controllers/global-preferences/security-preferences.controller.ts b/backend/src/controllers/global-preferences/security-preferences.controller.ts index 1ab7f2a..50a1927 100644 --- a/backend/src/controllers/global-preferences/security-preferences.controller.ts +++ b/backend/src/controllers/global-preferences/security-preferences.controller.ts @@ -15,7 +15,13 @@ export const updateSecurityPreferences = async (req: Request, res: Response) => const globalPreferences = await globalPrefService.getGlobalPreferences(); if (securityPreferences.roomCreationPolicy) { - globalPreferences.securityPreferences.roomCreationPolicy = securityPreferences.roomCreationPolicy; + globalPreferences.securityPreferences.roomCreationPolicy = { + allowRoomCreation: securityPreferences.roomCreationPolicy.allowRoomCreation, + requireAuthentication: + securityPreferences.roomCreationPolicy.requireAuthentication === undefined + ? globalPreferences.securityPreferences.roomCreationPolicy.requireAuthentication + : securityPreferences.roomCreationPolicy.requireAuthentication + }; } if (securityPreferences.authentication) { diff --git a/backend/src/middlewares/recording.middleware.ts b/backend/src/middlewares/recording.middleware.ts index de70c7a..dff1ad0 100644 --- a/backend/src/middlewares/recording.middleware.ts +++ b/backend/src/middlewares/recording.middleware.ts @@ -116,7 +116,7 @@ export const withCanDeleteRecordingsPermission = async (req: Request, res: Respo export const configureRecordingMediaAuth = async (req: Request, res: Response, next: NextFunction) => { const storageService = container.get(MeetStorageService); - let recordingAccess: MeetRecordingAccess; + let recordingAccess: MeetRecordingAccess | undefined; try { const roomId = extractRoomIdFromRequest(req); diff --git a/backend/src/middlewares/request-validators/preferences-validator.middleware.ts b/backend/src/middlewares/request-validators/preferences-validator.middleware.ts index 7665d18..f2ae982 100644 --- a/backend/src/middlewares/request-validators/preferences-validator.middleware.ts +++ b/backend/src/middlewares/request-validators/preferences-validator.middleware.ts @@ -47,10 +47,21 @@ const AuthenticationPreferencesDTOSchema: z.ZodType = z.object({ - allowRoomCreation: z.boolean(), - requireAuthentication: z.boolean() -}); +const RoomCreationPolicySchema: z.ZodType = z + .object({ + allowRoomCreation: z.boolean(), + requireAuthentication: z.boolean().optional() + }) + .refine( + (data) => { + // If allowRoomCreation is true, requireAuthentication must be provided + return !data.allowRoomCreation || data.requireAuthentication !== undefined; + }, + { + message: 'requireAuthentication is required when allowRoomCreation is true', + path: ['requireAuthentication'] + } + ); const UpdateSecurityPreferencesDTOSchema: z.ZodType = z .object({ diff --git a/backend/src/middlewares/request-validators/room-validator.middleware.ts b/backend/src/middlewares/request-validators/room-validator.middleware.ts index 3f0b7a3..9d06653 100644 --- a/backend/src/middlewares/request-validators/room-validator.middleware.ts +++ b/backend/src/middlewares/request-validators/room-validator.middleware.ts @@ -64,10 +64,21 @@ const RecordingAccessSchema: z.ZodType = z.enum([ MeetRecordingAccess.PUBLIC ]); -const RecordingPreferencesSchema: z.ZodType = z.object({ - enabled: z.boolean(), - allowAccessTo: RecordingAccessSchema -}); +const RecordingPreferencesSchema: z.ZodType = z + .object({ + enabled: z.boolean(), + allowAccessTo: RecordingAccessSchema.optional() + }) + .refine( + (data) => { + // If recording is enabled, allowAccessTo must be provided + return !data.enabled || data.allowAccessTo !== undefined; + }, + { + message: 'allowAccessTo is required when recording is enabled', + path: ['allowAccessTo'] + } + ); const ChatPreferencesSchema: z.ZodType = z.object({ enabled: z.boolean() diff --git a/backend/src/middlewares/room.middleware.ts b/backend/src/middlewares/room.middleware.ts index f73d021..5a2f402 100644 --- a/backend/src/middlewares/room.middleware.ts +++ b/backend/src/middlewares/room.middleware.ts @@ -20,7 +20,7 @@ import { allowAnonymous, apiKeyValidator, tokenAndRoleValidator, withAuth } from export const configureCreateRoomAuth = async (req: Request, res: Response, next: NextFunction) => { const globalPrefService = container.get(MeetStorageService); let allowRoomCreation: boolean; - let requireAuthentication: boolean; + let requireAuthentication: boolean | undefined; try { const { securityPreferences } = await globalPrefService.getGlobalPreferences(); @@ -104,7 +104,7 @@ export const configureRecordingTokenAuth = async (req: Request, res: Response, n const recordingAccess = room.preferences!.recordingPreferences.allowAccessTo; - if (recordingAccess === MeetRecordingAccess.ADMIN) { + if (!recordingAccess || recordingAccess === MeetRecordingAccess.ADMIN) { // Deny request if the room is configured to allow access to recordings only for admins throw errorInsufficientPermissions(); } diff --git a/frontend/projects/shared-meet-components/src/lib/services/context/context.service.ts b/frontend/projects/shared-meet-components/src/lib/services/context/context.service.ts index 643618c..bc203b6 100644 --- a/frontend/projects/shared-meet-components/src/lib/services/context/context.service.ts +++ b/frontend/projects/shared-meet-components/src/lib/services/context/context.service.ts @@ -173,7 +173,8 @@ export class ContextService { async isAuthRequiredToCreateRooms(): Promise { await this.getSecurityPreferences(); - return this.context.securityPreferences!.roomCreationPolicy.requireAuthentication; + const requireAuthentication = this.context.securityPreferences!.roomCreationPolicy.requireAuthentication; + return requireAuthentication !== undefined && requireAuthentication; } async getAuthModeToEnterRoom(): Promise { diff --git a/typings/src/global-preferences.ts b/typings/src/global-preferences.ts index b73a544..6b7416d 100644 --- a/typings/src/global-preferences.ts +++ b/typings/src/global-preferences.ts @@ -24,7 +24,7 @@ export interface SecurityPreferences { export interface RoomCreationPolicy { allowRoomCreation: boolean; - requireAuthentication: boolean; + requireAuthentication?: boolean; } // DTOs diff --git a/typings/src/room-preferences.ts b/typings/src/room-preferences.ts index 130c741..9aca289 100644 --- a/typings/src/room-preferences.ts +++ b/typings/src/room-preferences.ts @@ -12,7 +12,7 @@ export interface MeetRoomPreferences { */ export interface MeetRecordingPreferences { enabled: boolean; - allowAccessTo: MeetRecordingAccess; + allowAccessTo?: MeetRecordingAccess; } export const enum MeetRecordingAccess {