| const { logger } = require('@librechat/data-schemas'); |
| const { PermissionBits, hasPermissions, ResourceType } = require('librechat-data-provider'); |
| const { getEffectivePermissions } = require('~/server/services/PermissionService'); |
| const { getAgents } = require('~/models/Agent'); |
| const { getFiles } = require('~/models/File'); |
|
|
| |
| |
| |
| |
| const checkAgentBasedFileAccess = async ({ userId, role, fileId }) => { |
| try { |
| |
| const agentsWithFile = await getAgents({ |
| $or: [ |
| { 'tool_resources.execute_code.file_ids': fileId }, |
| { 'tool_resources.file_search.file_ids': fileId }, |
| { 'tool_resources.context.file_ids': fileId }, |
| { 'tool_resources.ocr.file_ids': fileId }, |
| ], |
| }); |
|
|
| if (!agentsWithFile || agentsWithFile.length === 0) { |
| return false; |
| } |
|
|
| |
| for (const agent of agentsWithFile) { |
| |
| if (agent.author && agent.author.toString() === userId) { |
| logger.debug(`[fileAccess] User is author of agent ${agent.id}`); |
| return true; |
| } |
|
|
| |
| try { |
| const permissions = await getEffectivePermissions({ |
| userId, |
| role, |
| resourceType: ResourceType.AGENT, |
| resourceId: agent._id || agent.id, |
| }); |
|
|
| if (hasPermissions(permissions, PermissionBits.VIEW)) { |
| logger.debug(`[fileAccess] User ${userId} has VIEW permissions on agent ${agent.id}`); |
| return true; |
| } |
| } catch (permissionError) { |
| logger.warn( |
| `[fileAccess] Permission check failed for agent ${agent.id}:`, |
| permissionError.message, |
| ); |
| |
| } |
| } |
|
|
| return false; |
| } catch (error) { |
| logger.error('[fileAccess] Error checking agent-based access:', error); |
| return false; |
| } |
| }; |
|
|
| |
| |
| |
| |
| const fileAccess = async (req, res, next) => { |
| try { |
| const fileId = req.params.file_id; |
| const userId = req.user?.id; |
| const userRole = req.user?.role; |
| if (!fileId) { |
| return res.status(400).json({ |
| error: 'Bad Request', |
| message: 'file_id is required', |
| }); |
| } |
|
|
| if (!userId) { |
| return res.status(401).json({ |
| error: 'Unauthorized', |
| message: 'Authentication required', |
| }); |
| } |
|
|
| const [file] = await getFiles({ file_id: fileId }); |
| if (!file) { |
| return res.status(404).json({ |
| error: 'Not Found', |
| message: 'File not found', |
| }); |
| } |
|
|
| if (file.user && file.user.toString() === userId) { |
| req.fileAccess = { file }; |
| return next(); |
| } |
|
|
| |
| const hasAgentAccess = await checkAgentBasedFileAccess({ userId, role: userRole, fileId }); |
| if (hasAgentAccess) { |
| req.fileAccess = { file }; |
| return next(); |
| } |
|
|
| logger.warn(`[fileAccess] User ${userId} denied access to file ${fileId}`); |
| return res.status(403).json({ |
| error: 'Forbidden', |
| message: 'Insufficient permissions to access this file', |
| }); |
| } catch (error) { |
| logger.error('[fileAccess] Error checking file access:', error); |
| return res.status(500).json({ |
| error: 'Internal Server Error', |
| message: 'Failed to check file access permissions', |
| }); |
| } |
| }; |
|
|
| module.exports = { |
| fileAccess, |
| }; |
|
|