| | const { isEnabled } = require('@librechat/api'); |
| | const { Constants, ViolationTypes, Time } = require('librechat-data-provider'); |
| | const { searchConversation } = require('~/models/Conversation'); |
| | const denyRequest = require('~/server/middleware/denyRequest'); |
| | const { logViolation, getLogStores } = require('~/cache'); |
| |
|
| | const { USE_REDIS, CONVO_ACCESS_VIOLATION_SCORE: score = 0 } = process.env ?? {}; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const validateConvoAccess = async (req, res, next) => { |
| | const namespace = ViolationTypes.CONVO_ACCESS; |
| | const cache = getLogStores(namespace); |
| |
|
| | const conversationId = req.body.conversationId; |
| |
|
| | if (!conversationId || conversationId === Constants.NEW_CONVO) { |
| | return next(); |
| | } |
| |
|
| | const userId = req.user?.id ?? req.user?._id ?? ''; |
| | const type = ViolationTypes.CONVO_ACCESS; |
| | const key = `${isEnabled(USE_REDIS) ? namespace : ''}:${userId}:${conversationId}`; |
| |
|
| | try { |
| | if (cache) { |
| | const cachedAccess = await cache.get(key); |
| | if (cachedAccess === 'authorized') { |
| | return next(); |
| | } |
| | } |
| |
|
| | const conversation = await searchConversation(conversationId); |
| |
|
| | if (!conversation) { |
| | return next(); |
| | } |
| |
|
| | if (conversation.user !== userId) { |
| | const errorMessage = { |
| | type, |
| | error: 'User not authorized for this conversation', |
| | }; |
| |
|
| | if (cache) { |
| | await logViolation(req, res, type, errorMessage, score); |
| | } |
| | return await denyRequest(req, res, errorMessage); |
| | } |
| |
|
| | if (cache) { |
| | await cache.set(key, 'authorized', Time.TEN_MINUTES); |
| | } |
| | next(); |
| | } catch (error) { |
| | console.error('Error validating conversation access:', error); |
| | res.status(500).json({ error: 'Internal server error' }); |
| | } |
| | }; |
| |
|
| | module.exports = validateConvoAccess; |
| |
|