diff --git a/api/server/routes/files/files.js b/api/server/routes/files/files.js index 7ac1d55e53..e640a0ee16 100644 --- a/api/server/routes/files/files.js +++ b/api/server/routes/files/files.js @@ -220,14 +220,16 @@ router.delete('/', async (req, res) => { const agentFiles = files .filter((f) => toolResourceFiles.includes(f.file_id)) .map((file) => ({ tool_resource: req.body.tool_resource, file_id: file.file_id })); - const accessMap = await hasAccessToFilesViaAgent({ - userId: req.user.id, - role: req.user.role, - fileIds: agentFiles.map((file) => file.file_id), - agentId: req.body.agent_id, - isDelete: true, - }); - const unauthorizedFiles = agentFiles.filter((file) => !accessMap.get(file.file_id)); + const hasAgentEditAccess = + agent.author?.toString() === req.user.id.toString() || + (await checkPermission({ + userId: req.user.id, + role: req.user.role, + resourceType: ResourceType.AGENT, + resourceId: agent._id, + requiredPermission: PermissionBits.EDIT, + })); + const unauthorizedFiles = hasAgentEditAccess ? [] : agentFiles; if (unauthorizedFiles.length > 0) { return res.status(403).json({ message: 'You can only delete files you have access to', @@ -519,7 +521,10 @@ router.get('/download/:userId/:file_id', fileAccess, async (req, res) => { const setHeaders = () => { res.setHeader('Content-Disposition', getContentDisposition(file.filename)); res.setHeader('Content-Type', 'application/octet-stream'); - res.setHeader('X-File-Metadata', JSON.stringify(getDownloadFileMetadata(file))); + res.setHeader( + 'X-File-Metadata', + encodeURIComponent(JSON.stringify(getDownloadFileMetadata(file))), + ); }; if (checkOpenAIStorage(file.source)) { diff --git a/api/server/routes/files/files.test.js b/api/server/routes/files/files.test.js index b7c4772890..1998a0375c 100644 --- a/api/server/routes/files/files.test.js +++ b/api/server/routes/files/files.test.js @@ -685,7 +685,7 @@ describe('File Routes - Delete with Agent Access', () => { expect(response.status).toBe(200); expect(response.body.toString()).toBe('file content'); expect(response.headers.location).toBeUndefined(); - const metadata = JSON.parse(response.headers['x-file-metadata']); + const metadata = JSON.parse(decodeURIComponent(response.headers['x-file-metadata'])); expect(metadata).toMatchObject({ file_id: userFileId, filename: 'file.pdf', diff --git a/client/src/data-provider/Files/queries.ts b/client/src/data-provider/Files/queries.ts index db02bfb64b..b287a1efba 100644 --- a/client/src/data-provider/Files/queries.ts +++ b/client/src/data-provider/Files/queries.ts @@ -96,7 +96,9 @@ export const useFileDownload = ( const blob = response.data; const downloadURL = window.URL.createObjectURL(blob); try { - const metadata: t.TFile | undefined = JSON.parse(response.headers['x-file-metadata']); + const metadata: t.TFile | undefined = JSON.parse( + decodeURIComponent(response.headers['x-file-metadata']), + ); if (!metadata) { console.warn('No metadata found for file download', response.headers); return downloadURL;