mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-21 01:44:09 +01:00
✍️ fix: Validation for Conversation Title Updates (#11099)
* ✍️ fix: Validation for Conversation Title Updates
* fix: Add validateConvoAccess middleware mock in tests
This commit is contained in:
parent
b7ea340769
commit
bfc981d736
3 changed files with 40 additions and 7 deletions
|
|
@ -6,6 +6,15 @@ const { logViolation, getLogStores } = require('~/cache');
|
||||||
|
|
||||||
const { USE_REDIS, CONVO_ACCESS_VIOLATION_SCORE: score = 0 } = process.env ?? {};
|
const { USE_REDIS, CONVO_ACCESS_VIOLATION_SCORE: score = 0 } = process.env ?? {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to get conversationId from different request body structures.
|
||||||
|
* @param {Object} body - The request body.
|
||||||
|
* @returns {string|undefined} The conversationId.
|
||||||
|
*/
|
||||||
|
const getConversationId = (body) => {
|
||||||
|
return body.conversationId ?? body.arg?.conversationId;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware to validate user's authorization for a conversation.
|
* Middleware to validate user's authorization for a conversation.
|
||||||
*
|
*
|
||||||
|
|
@ -24,7 +33,7 @@ const validateConvoAccess = async (req, res, next) => {
|
||||||
const namespace = ViolationTypes.CONVO_ACCESS;
|
const namespace = ViolationTypes.CONVO_ACCESS;
|
||||||
const cache = getLogStores(namespace);
|
const cache = getLogStores(namespace);
|
||||||
|
|
||||||
const conversationId = req.body.conversationId;
|
const conversationId = getConversationId(req.body);
|
||||||
|
|
||||||
if (!conversationId || conversationId === Constants.NEW_CONVO) {
|
if (!conversationId || conversationId === Constants.NEW_CONVO) {
|
||||||
return next();
|
return next();
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ jest.mock('~/server/middleware', () => ({
|
||||||
forkUserLimiter: (req, res, next) => next(),
|
forkUserLimiter: (req, res, next) => next(),
|
||||||
})),
|
})),
|
||||||
configMiddleware: (req, res, next) => next(),
|
configMiddleware: (req, res, next) => next(),
|
||||||
|
validateConvoAccess: (req, res, next) => next(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('~/server/utils/import/fork', () => ({
|
jest.mock('~/server/utils/import/fork', () => ({
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const { logger } = require('@librechat/data-schemas');
|
||||||
const { CacheKeys, EModelEndpoint } = require('librechat-data-provider');
|
const { CacheKeys, EModelEndpoint } = require('librechat-data-provider');
|
||||||
const {
|
const {
|
||||||
createImportLimiters,
|
createImportLimiters,
|
||||||
|
validateConvoAccess,
|
||||||
createForkLimiters,
|
createForkLimiters,
|
||||||
configMiddleware,
|
configMiddleware,
|
||||||
} = require('~/server/middleware');
|
} = require('~/server/middleware');
|
||||||
|
|
@ -151,17 +152,39 @@ router.delete('/all', async (req, res) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/update', async (req, res) => {
|
/** Maximum allowed length for conversation titles */
|
||||||
const update = req.body.arg;
|
const MAX_CONVO_TITLE_LENGTH = 1024;
|
||||||
|
|
||||||
if (!update.conversationId) {
|
/**
|
||||||
|
* Updates a conversation's title.
|
||||||
|
* @route POST /update
|
||||||
|
* @param {string} req.body.arg.conversationId - The conversation ID to update.
|
||||||
|
* @param {string} req.body.arg.title - The new title for the conversation.
|
||||||
|
* @returns {object} 201 - The updated conversation object.
|
||||||
|
*/
|
||||||
|
router.post('/update', validateConvoAccess, async (req, res) => {
|
||||||
|
const { conversationId, title } = req.body.arg ?? {};
|
||||||
|
|
||||||
|
if (!conversationId) {
|
||||||
return res.status(400).json({ error: 'conversationId is required' });
|
return res.status(400).json({ error: 'conversationId is required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (title === undefined) {
|
||||||
|
return res.status(400).json({ error: 'title is required' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof title !== 'string') {
|
||||||
|
return res.status(400).json({ error: 'title must be a string' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const sanitizedTitle = title.trim().slice(0, MAX_CONVO_TITLE_LENGTH);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dbResponse = await saveConvo(req, update, {
|
const dbResponse = await saveConvo(
|
||||||
context: `POST /api/convos/update ${update.conversationId}`,
|
req,
|
||||||
});
|
{ conversationId, title: sanitizedTitle },
|
||||||
|
{ context: `POST /api/convos/update ${conversationId}` },
|
||||||
|
);
|
||||||
res.status(201).json(dbResponse);
|
res.status(201).json(dbResponse);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error updating conversation', error);
|
logger.error('Error updating conversation', error);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue