diff --git a/meet-ce/backend/openapi/paths/internal/ai-assistant.yaml b/meet-ce/backend/openapi/paths/internal/ai-assistant.yaml index 5454791c..9a310859 100644 --- a/meet-ce/backend/openapi/paths/internal/ai-assistant.yaml +++ b/meet-ce/backend/openapi/paths/internal/ai-assistant.yaml @@ -50,6 +50,8 @@ description: AI assistant canceled successfully. '401': $ref: '../../components/responses/unauthorized-error.yaml' + '403': + $ref: '../../components/responses/forbidden-error.yaml' '422': $ref: '../../components/responses/validation-error.yaml' '500': diff --git a/meet-ce/backend/src/controllers/ai-assistant.controller.ts b/meet-ce/backend/src/controllers/ai-assistant.controller.ts index f27d77a3..eaebba7f 100644 --- a/meet-ce/backend/src/controllers/ai-assistant.controller.ts +++ b/meet-ce/backend/src/controllers/ai-assistant.controller.ts @@ -1,42 +1,26 @@ import { Request, Response } from 'express'; import { container } from '../config/dependency-injector.config.js'; -import { handleError } from '../models/error.model.js'; +import { errorInsufficientPermissions, handleError, rejectRequestFromMeetError } from '../models/error.model.js'; import { AiAssistantService } from '../services/ai-assistant.service.js'; import { LoggerService } from '../services/logger.service.js'; import { RequestSessionService } from '../services/request-session.service.js'; -import { TokenService } from '../services/token.service.js'; -import { getRoomMemberToken } from '../utils/token.utils.js'; - -const getRoomMemberIdentityFromRequest = async (req: Request): Promise => { - const tokenService = container.get(TokenService); - const token = getRoomMemberToken(req); - - if (!token) { - throw new Error('Room member token not found'); - } - - const claims = await tokenService.verifyToken(token); - - if (!claims.sub) { - throw new Error('Room member token does not include participant identity'); - } - - return claims.sub; -}; export const createAssistant = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const requestSessionService = container.get(RequestSessionService); const aiAssistantService = container.get(AiAssistantService); // const payload: MeetCreateAssistantRequest = req.body; - const roomId = requestSessionService.getRoomIdFromToken(); - if (!roomId) { - return handleError(res, new Error('Could not resolve room from token'), 'creating assistant'); + const roomId = requestSessionService.getRoomIdFromMember(); + const participantIdentity = requestSessionService.getParticipantIdentity(); + + if (!roomId || !participantIdentity) { + logger.warn('Could not resolve room or participant identity from token when creating assistant'); + const error = errorInsufficientPermissions(); + return rejectRequestFromMeetError(res, error); } try { - const participantIdentity = await getRoomMemberIdentityFromRequest(req); logger.verbose(`Creating assistant for participant '${participantIdentity}' in room '${roomId}'`); const assistant = await aiAssistantService.createLiveCaptionsAssistant(roomId, participantIdentity); return res.status(200).json(assistant); @@ -50,14 +34,17 @@ export const cancelAssistant = async (req: Request, res: Response) => { const requestSessionService = container.get(RequestSessionService); const aiAssistantService = container.get(AiAssistantService); const { assistantId } = req.params; - const roomId = requestSessionService.getRoomIdFromToken(); - if (!roomId) { - return handleError(res, new Error('Could not resolve room from token'), 'canceling assistant'); + const roomId = requestSessionService.getRoomIdFromMember(); + const participantIdentity = requestSessionService.getParticipantIdentity(); + + if (!roomId || !participantIdentity) { + logger.warn('Could not resolve room or participant identity from token when canceling assistant'); + const error = errorInsufficientPermissions(); + return rejectRequestFromMeetError(res, error); } try { - const participantIdentity = await getRoomMemberIdentityFromRequest(req); logger.verbose( `Canceling assistant '${assistantId}' for participant '${participantIdentity}' in room '${roomId}'` ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 936211ab..463cea31 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -703,8 +703,8 @@ importers: specifier: 20.3.15 version: 20.3.15(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@livekit/track-processors': - specifier: 0.7.2 - version: 0.7.2(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.16.1(@types/dom-mediacapture-record@1.0.22)) + specifier: 0.7.0 + version: 0.7.0(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.16.1(@types/dom-mediacapture-record@1.0.22)) '@openvidu-meet/shared-components': specifier: workspace:* version: link:../../meet-ce/frontend/projects/shared-meet-components @@ -2968,6 +2968,12 @@ packages: '@livekit/protocol@1.43.4': resolution: {integrity: sha512-mJDFt/p+G2OKmIGizYiACK7Jb06wd42m9Pe7Y9cAOfdYpvwCqHlw4yul5Z7iRU3VKPsYJ27WL3oeHEoiu+HuAA==} + '@livekit/track-processors@0.7.0': + resolution: {integrity: sha512-ERdByDrHPLA8xzZNFcqWiLt5ZJs4AZo1RjDlYplb//xeaWURaJdulqrds5EHSMHmELmTzlEOSgvSrzFlatlJQQ==} + peerDependencies: + '@types/dom-mediacapture-transform': ^0.1.9 + livekit-client: 2.16.1 + '@livekit/track-processors@0.7.2': resolution: {integrity: sha512-lzARBKTbBwqycdR/SwTu6//N0l20BzfDd7grxCXl07676SwRApNtZAK1GJjL1m3dCM3KBqH1aVxjMpNcbOw5uQ==} peerDependencies: @@ -13580,6 +13586,12 @@ snapshots: dependencies: '@bufbuild/protobuf': 1.10.1 + '@livekit/track-processors@0.7.0(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.16.1(@types/dom-mediacapture-record@1.0.22))': + dependencies: + '@mediapipe/tasks-vision': 0.10.14 + '@types/dom-mediacapture-transform': 0.1.11 + livekit-client: 2.16.1(@types/dom-mediacapture-record@1.0.22) + '@livekit/track-processors@0.7.2(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.16.1(@types/dom-mediacapture-record@1.0.22))': dependencies: '@mediapipe/tasks-vision': 0.10.14