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