| | 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, |
| | }; |
| |
|