diff --git a/api/server/controllers/agents/v1.js b/api/server/controllers/agents/v1.js index 2aa416f840..bc92a4b663 100644 --- a/api/server/controllers/agents/v1.js +++ b/api/server/controllers/agents/v1.js @@ -226,8 +226,6 @@ const uploadAgentAvatarHandler = async (req, res) => { return res.status(400).json({ message: 'Agent ID is required' }); } - let { avatar: _avatar = '{}' } = req.body; - const image = await uploadImageBuffer({ req, context: FileContext.avatar, @@ -236,10 +234,12 @@ const uploadAgentAvatarHandler = async (req, res) => { }, }); + let _avatar; try { - _avatar = JSON.parse(_avatar); + const agent = await getAgent({ id: agent_id }); + _avatar = agent.avatar; } catch (error) { - logger.error('[/avatar/:agent_id] Error parsing avatar', error); + logger.error('[/avatar/:agent_id] Error fetching agent', error); _avatar = {}; } @@ -247,7 +247,7 @@ const uploadAgentAvatarHandler = async (req, res) => { const { deleteFile } = getStrategyFunctions(_avatar.source); try { await deleteFile(req, { filepath: _avatar.filepath }); - await deleteFileByFilter({ filepath: _avatar.filepath }); + await deleteFileByFilter({ user: req.user.id, filepath: _avatar.filepath }); } catch (error) { logger.error('[/avatar/:agent_id] Error deleting old avatar', error); } diff --git a/api/server/controllers/assistants/v1.js b/api/server/controllers/assistants/v1.js index 5a922cec6b..982e212b7e 100644 --- a/api/server/controllers/assistants/v1.js +++ b/api/server/controllers/assistants/v1.js @@ -241,7 +241,6 @@ const getAssistantDocuments = async (req, res) => { * @param {string} req.params.assistant_id - The ID of the assistant. * @param {Express.Multer.File} req.file - The avatar image file. * @param {object} req.body - Request body - * @param {string} [req.body.metadata] - Optional metadata for the assistant's avatar. * @returns {Object} 200 - success response - application/json */ const uploadAssistantAvatar = async (req, res) => { @@ -251,7 +250,6 @@ const uploadAssistantAvatar = async (req, res) => { return res.status(400).json({ message: 'Assistant ID is required' }); } - let { metadata: _metadata = '{}' } = req.body; const { openai } = await getOpenAIClient({ req, res }); await validateAuthor({ req, openai }); @@ -263,10 +261,15 @@ const uploadAssistantAvatar = async (req, res) => { }, }); + let _metadata; + try { - _metadata = JSON.parse(_metadata); + const assistant = await openai.beta.assistants.retrieve(assistant_id); + if (assistant) { + _metadata = assistant.metadata; + } } catch (error) { - logger.error('[/avatar/:assistant_id] Error parsing metadata', error); + logger.error('[/avatar/:assistant_id] Error fetching assistant', error); _metadata = {}; } @@ -274,7 +277,7 @@ const uploadAssistantAvatar = async (req, res) => { const { deleteFile } = getStrategyFunctions(_metadata.avatar_source); try { await deleteFile(req, { filepath: _metadata.avatar }); - await deleteFileByFilter({ filepath: _metadata.avatar }); + await deleteFileByFilter({ user: req.user.id, filepath: _metadata.avatar }); } catch (error) { logger.error('[/avatar/:assistant_id] Error deleting old avatar', error); } diff --git a/api/server/services/Files/Local/crud.js b/api/server/services/Files/Local/crud.js index 18bf5127fd..12b7738828 100644 --- a/api/server/services/Files/Local/crud.js +++ b/api/server/services/Files/Local/crud.js @@ -202,8 +202,20 @@ const deleteLocalFile = async (req, file) => { } if (file.filepath.startsWith(`/uploads/${req.user.id}`)) { - const basePath = file.filepath.split('/uploads/')[1]; - const filepath = path.join(uploads, basePath); + const userUploadDir = path.join(uploads, req.user.id); + const basePath = file.filepath.split(`/uploads/${req.user.id}/`)[1]; + + if (!basePath) { + throw new Error(`Invalid file path: ${file.filepath}`); + } + + const filepath = path.join(userUploadDir, basePath); + + const rel = path.relative(userUploadDir, filepath); + if (rel.startsWith('..') || path.isAbsolute(rel) || rel.includes(`..${path.sep}`)) { + throw new Error(`Invalid file path: ${file.filepath}`); + } + await fs.promises.unlink(filepath); return; } diff --git a/client/src/components/SidePanel/Agents/AgentAvatar.tsx b/client/src/components/SidePanel/Agents/AgentAvatar.tsx index 983044308b..aa0ca44f04 100644 --- a/client/src/components/SidePanel/Agents/AgentAvatar.tsx +++ b/client/src/components/SidePanel/Agents/AgentAvatar.tsx @@ -135,10 +135,6 @@ function Avatar({ formData.append('file', input, input.name); formData.append('agent_id', createMutation.data.id); - if (typeof createMutation.data.avatar === 'object') { - formData.append('avatar', JSON.stringify(createMutation.data.avatar)); - } - uploadAvatar({ agent_id: createMutation.data.id, postCreation: true, diff --git a/client/src/components/SidePanel/Builder/AssistantAvatar.tsx b/client/src/components/SidePanel/Builder/AssistantAvatar.tsx index c94c1c956b..dc0f5fbd24 100644 --- a/client/src/components/SidePanel/Builder/AssistantAvatar.tsx +++ b/client/src/components/SidePanel/Builder/AssistantAvatar.tsx @@ -68,7 +68,7 @@ function Avatar({ setInput(null); setPreviewUrl(data.metadata?.avatar as string | null); - const res = queryClient.getQueryData([ + const res = queryClient.getQueryData([ QueryKeys.assistants, endpoint, defaultOrderQuery, @@ -78,16 +78,15 @@ function Avatar({ return; } - const assistants = - res.data.map((assistant) => { - if (assistant.id === assistant_id) { - return { - ...assistant, - ...data, - }; - } - return assistant; - }) ?? []; + const assistants = res.data.map((assistant) => { + if (assistant.id === assistant_id) { + return { + ...assistant, + ...data, + }; + } + return assistant; + }); queryClient.setQueryData( [QueryKeys.assistants, endpoint, defaultOrderQuery], @@ -149,10 +148,6 @@ function Avatar({ formData.append('file', input, input.name); formData.append('assistant_id', createMutation.data.id); - if (typeof createMutation.data.metadata === 'object') { - formData.append('metadata', JSON.stringify(createMutation.data.metadata)); - } - uploadAvatar({ assistant_id: createMutation.data.id, model: activeModel, @@ -195,10 +190,6 @@ function Avatar({ formData.append('file', file, file.name); formData.append('assistant_id', assistant_id); - if (typeof metadata === 'object') { - formData.append('metadata', JSON.stringify(metadata)); - } - uploadAvatar({ assistant_id, model: activeModel,