mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 18:00:15 +01:00
refactor: original changes
This commit is contained in:
parent
fa9177180f
commit
f9c0e9853f
83 changed files with 413 additions and 505 deletions
|
|
@ -21,25 +21,6 @@ jest.mock('~/lib/db/connectDb', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
jest.mock('@librechat/data-schemas', () => {
|
|
||||||
const userModelMock = {
|
|
||||||
createUser: jest.fn(() => mockUser),
|
|
||||||
findUser: jest.fn(),
|
|
||||||
updateUser: jest.fn(),
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
registerModels: jest.fn().mockReturnValue({
|
|
||||||
User: userModelMock,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('~/models/Message', () => ({
|
|
||||||
Message: jest.fn(),
|
|
||||||
}));
|
|
||||||
jest.mock('~/models/Conversation', () => ({
|
|
||||||
Conversation: jest.fn(),
|
|
||||||
}));
|
|
||||||
jest.mock('~/models/File', () => ({
|
jest.mock('~/models/File', () => ({
|
||||||
File: jest.fn(),
|
File: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
@ -63,9 +44,6 @@ describe('Tool Handlers', () => {
|
||||||
const mainPlugin = availableTools.find((tool) => tool.pluginKey === pluginKey);
|
const mainPlugin = availableTools.find((tool) => tool.pluginKey === pluginKey);
|
||||||
const authConfigs = mainPlugin.authConfig;
|
const authConfigs = mainPlugin.authConfig;
|
||||||
|
|
||||||
const { registerModels } = require('@librechat/data-schemas');
|
|
||||||
let User = registerModels().User;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mockUser.save.mockResolvedValue(undefined);
|
mockUser.save.mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
|
|
||||||
4
api/cache/banViolation.js
vendored
4
api/cache/banViolation.js
vendored
|
|
@ -1,8 +1,8 @@
|
||||||
const { ViolationTypes } = require('librechat-data-provider');
|
const { ViolationTypes } = require('librechat-data-provider');
|
||||||
|
const { deleteAllUserSessions } = require('@librechat/data-schemas');
|
||||||
const { isEnabled, math, removePorts } = require('~/server/utils');
|
const { isEnabled, math, removePorts } = require('~/server/utils');
|
||||||
const getLogStores = require('./getLogStores');
|
const getLogStores = require('./getLogStores');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const { BAN_VIOLATIONS, BAN_INTERVAL } = process.env ?? {};
|
const { BAN_VIOLATIONS, BAN_INTERVAL } = process.env ?? {};
|
||||||
const interval = math(BAN_INTERVAL, 20);
|
const interval = math(BAN_INTERVAL, 20);
|
||||||
|
|
@ -45,7 +45,7 @@ const banViolation = async (req, res, errorMessage) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.models.Session.deleteAllUserSessions({ userId: user_id });
|
await deleteAllUserSessions({ userId: user_id });
|
||||||
res.clearCookie('refreshToken');
|
res.clearCookie('refreshToken');
|
||||||
|
|
||||||
const banLogs = getLogStores(ViolationTypes.BAN);
|
const banLogs = getLogStores(ViolationTypes.BAN);
|
||||||
|
|
|
||||||
12
api/cache/banViolation.spec.js
vendored
12
api/cache/banViolation.spec.js
vendored
|
|
@ -1,17 +1,5 @@
|
||||||
const banViolation = require('./banViolation');
|
const banViolation = require('./banViolation');
|
||||||
|
|
||||||
jest.mock('@librechat/data-schemas', () => {
|
|
||||||
const sessionModelMock = {
|
|
||||||
deleteAllUserSessions: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
registerModels: jest.fn().mockReturnValue({
|
|
||||||
Session: sessionModelMock,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockModels = {
|
const mockModels = {
|
||||||
Session: {
|
Session: {
|
||||||
deleteAllUserSessions: jest.fn(),
|
deleteAllUserSessions: jest.fn(),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const { registerModels } = require('@librechat/data-schemas');
|
|
||||||
|
|
||||||
if (!process.env.MONGO_URI) {
|
if (!process.env.MONGO_URI) {
|
||||||
throw new Error('Please define the MONGO_URI environment variable');
|
throw new Error('Please define the MONGO_URI environment variable');
|
||||||
|
|
@ -40,11 +39,6 @@ async function connectDb(mongoUri = process.env.MONGO_URI) {
|
||||||
}
|
}
|
||||||
cached.conn = await cached.promise;
|
cached.conn = await cached.promise;
|
||||||
|
|
||||||
// Register models once
|
|
||||||
if (!cached.models) {
|
|
||||||
cached.models = registerModels(mongoose);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cached.conn;
|
return cached.conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
const { MeiliSearch } = require('meilisearch');
|
const { MeiliSearch } = require('meilisearch');
|
||||||
|
const { Message, Conversation, logger } = require('@librechat/data-schemas');
|
||||||
const { isEnabled } = require('~/server/utils');
|
const { isEnabled } = require('~/server/utils');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const searchEnabled = isEnabled(process.env.SEARCH);
|
const searchEnabled = isEnabled(process.env.SEARCH);
|
||||||
const indexingDisabled = isEnabled(process.env.MEILI_NO_SYNC);
|
const indexingDisabled = isEnabled(process.env.MEILI_NO_SYNC);
|
||||||
|
|
@ -28,7 +27,6 @@ async function indexSync() {
|
||||||
if (!searchEnabled) {
|
if (!searchEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { Message, Conversation } = db.models;
|
|
||||||
try {
|
try {
|
||||||
const client = MeiliSearchClient.getInstance();
|
const client = MeiliSearchClient.getInstance();
|
||||||
|
|
||||||
|
|
@ -42,6 +40,8 @@ async function indexSync() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info('[indexSync] Starting index sync...');
|
||||||
|
|
||||||
const messageCount = await Message.countDocuments();
|
const messageCount = await Message.countDocuments();
|
||||||
const convoCount = await Conversation.countDocuments();
|
const convoCount = await Conversation.countDocuments();
|
||||||
const messages = await client.index('messages').getStats();
|
const messages = await client.index('messages').getStats();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const crypto = require('node:crypto');
|
const crypto = require('node:crypto');
|
||||||
|
const { Agent } = require('@librechat/data-schemas');
|
||||||
const { SystemRoles, Tools, actionDelimiter } = require('librechat-data-provider');
|
const { SystemRoles, Tools, actionDelimiter } = require('librechat-data-provider');
|
||||||
const { GLOBAL_PROJECT_NAME, EPHEMERAL_AGENT_ID, mcp_delimiter } =
|
const { GLOBAL_PROJECT_NAME, EPHEMERAL_AGENT_ID, mcp_delimiter } =
|
||||||
require('librechat-data-provider').Constants;
|
require('librechat-data-provider').Constants;
|
||||||
|
|
@ -14,8 +15,6 @@ const getLogStores = require('~/cache/getLogStores');
|
||||||
const { getActions } = require('./Action');
|
const { getActions } = require('./Action');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an agent with the provided data.
|
* Create an agent with the provided data.
|
||||||
* @param {Object} agentData - The agent data to create.
|
* @param {Object} agentData - The agent data to create.
|
||||||
|
|
@ -35,7 +34,7 @@ const createAgent = async (agentData) => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
return (await db.models.Agent.create(initialAgentData)).toObject();
|
return (await Agent.create(initialAgentData)).toObject();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,7 +45,7 @@ const createAgent = async (agentData) => {
|
||||||
* @param {string} searchParameter.author - The user ID of the agent's author.
|
* @param {string} searchParameter.author - The user ID of the agent's author.
|
||||||
* @returns {Promise<Agent|null>} The agent document as a plain object, or null if not found.
|
* @returns {Promise<Agent|null>} The agent document as a plain object, or null if not found.
|
||||||
*/
|
*/
|
||||||
const getAgent = async (searchParameter) => await db.models.Agent.findOne(searchParameter).lean();
|
const getAgent = async (searchParameter) => await Agent.findOne(searchParameter).lean();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load an agent based on the provided ID
|
* Load an agent based on the provided ID
|
||||||
|
|
@ -268,7 +267,6 @@ const updateAgent = async (searchParameter, updateData, options = {}) => {
|
||||||
const { updatingUserId = null, forceVersion = false } = options;
|
const { updatingUserId = null, forceVersion = false } = options;
|
||||||
const mongoOptions = { new: true, upsert: false };
|
const mongoOptions = { new: true, upsert: false };
|
||||||
|
|
||||||
const Agent = db.models?.Agent;
|
|
||||||
const currentAgent = await Agent.findOne(searchParameter);
|
const currentAgent = await Agent.findOne(searchParameter);
|
||||||
if (currentAgent) {
|
if (currentAgent) {
|
||||||
const { __v, _id, id, versions, author, ...versionData } = currentAgent.toObject();
|
const { __v, _id, id, versions, author, ...versionData } = currentAgent.toObject();
|
||||||
|
|
@ -362,7 +360,6 @@ const updateAgent = async (searchParameter, updateData, options = {}) => {
|
||||||
* @returns {Promise<Agent>} The updated agent.
|
* @returns {Promise<Agent>} The updated agent.
|
||||||
*/
|
*/
|
||||||
const addAgentResourceFile = async ({ req, agent_id, tool_resource, file_id }) => {
|
const addAgentResourceFile = async ({ req, agent_id, tool_resource, file_id }) => {
|
||||||
const Agent = db.models?.Agent;
|
|
||||||
const searchParameter = { id: agent_id };
|
const searchParameter = { id: agent_id };
|
||||||
let agent = await getAgent(searchParameter);
|
let agent = await getAgent(searchParameter);
|
||||||
if (!agent) {
|
if (!agent) {
|
||||||
|
|
@ -428,7 +425,7 @@ const removeAgentResourceFiles = async ({ agent_id, files }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatePullData = { $pull: pullOps };
|
const updatePullData = { $pull: pullOps };
|
||||||
const agentAfterPull = await db.models.Agent.findOneAndUpdate(searchParameter, updatePullData, {
|
const agentAfterPull = await Agent.findOneAndUpdate(searchParameter, updatePullData, {
|
||||||
new: true,
|
new: true,
|
||||||
}).lean();
|
}).lean();
|
||||||
|
|
||||||
|
|
@ -458,7 +455,7 @@ const removeAgentResourceFiles = async ({ agent_id, files }) => {
|
||||||
* @returns {Promise<void>} Resolves when the agent has been successfully deleted.
|
* @returns {Promise<void>} Resolves when the agent has been successfully deleted.
|
||||||
*/
|
*/
|
||||||
const deleteAgent = async (searchParameter) => {
|
const deleteAgent = async (searchParameter) => {
|
||||||
const agent = await db.models.Agent.findOneAndDelete(searchParameter);
|
const agent = await Agent.findOneAndDelete(searchParameter);
|
||||||
if (agent) {
|
if (agent) {
|
||||||
await removeAgentFromAllProjects(agent.id);
|
await removeAgentFromAllProjects(agent.id);
|
||||||
}
|
}
|
||||||
|
|
@ -483,7 +480,7 @@ const getListAgents = async (searchParameter) => {
|
||||||
query = { $or: [globalQuery, query] };
|
query = { $or: [globalQuery, query] };
|
||||||
}
|
}
|
||||||
const agents = (
|
const agents = (
|
||||||
await db.models.Agent.find(query, {
|
await Agent.find(query, {
|
||||||
id: 1,
|
id: 1,
|
||||||
_id: 0,
|
_id: 0,
|
||||||
name: 1,
|
name: 1,
|
||||||
|
|
@ -580,7 +577,6 @@ const updateAgentProjects = async ({ user, agentId, projectIds, removeProjectIds
|
||||||
* @throws {Error} If the agent is not found or the specified version does not exist.
|
* @throws {Error} If the agent is not found or the specified version does not exist.
|
||||||
*/
|
*/
|
||||||
const revertAgentVersion = async (searchParameter, versionIndex) => {
|
const revertAgentVersion = async (searchParameter, versionIndex) => {
|
||||||
const Agent = db.models?.Agent;
|
|
||||||
const agent = await Agent.findOne(searchParameter);
|
const agent = await Agent.findOne(searchParameter);
|
||||||
if (!agent) {
|
if (!agent) {
|
||||||
throw new Error('Agent not found');
|
throw new Error('Agent not found');
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ process.env.CREDS_IV = '0123456789abcdef';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
const { Agent } = require('@librechat/data-schemas');
|
||||||
const { MongoMemoryServer } = require('mongodb-memory-server');
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
const {
|
const {
|
||||||
addAgentResourceFile,
|
addAgentResourceFile,
|
||||||
|
|
@ -19,9 +20,6 @@ const {
|
||||||
getListAgents,
|
getListAgents,
|
||||||
updateAgentProjects,
|
updateAgentProjects,
|
||||||
} = require('./Agent');
|
} = require('./Agent');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
let Agent;
|
|
||||||
|
|
||||||
describe('Agent Resource File Operations', () => {
|
describe('Agent Resource File Operations', () => {
|
||||||
let mongoServer;
|
let mongoServer;
|
||||||
|
|
@ -29,9 +27,7 @@ describe('Agent Resource File Operations', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mongoServer = await MongoMemoryServer.create();
|
mongoServer = await MongoMemoryServer.create();
|
||||||
const mongoUri = mongoServer.getUri();
|
const mongoUri = mongoServer.getUri();
|
||||||
await db.connectDb(mongoUri);
|
await mongoose.connect(mongoUri);
|
||||||
|
|
||||||
Agent = db.models.Agent;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const db = require('~/lib/db/connectDb');
|
const { Assistant } = require('@librechat/data-schemas');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an assistant with new data without overwriting existing properties,
|
* Update an assistant with new data without overwriting existing properties,
|
||||||
|
|
@ -12,7 +12,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
*/
|
*/
|
||||||
const updateAssistantDoc = async (searchParams, updateData) => {
|
const updateAssistantDoc = async (searchParams, updateData) => {
|
||||||
const options = { new: true, upsert: true };
|
const options = { new: true, upsert: true };
|
||||||
return await db.models.Assistant.findOneAndUpdate(searchParams, updateData, options).lean();
|
return await Assistant.findOneAndUpdate(searchParams, updateData, options).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -23,7 +23,7 @@ const updateAssistantDoc = async (searchParams, updateData) => {
|
||||||
* @param {string} searchParams.user - The user ID of the assistant's author.
|
* @param {string} searchParams.user - The user ID of the assistant's author.
|
||||||
* @returns {Promise<AssistantDocument|null>} The assistant document as a plain object, or null if not found.
|
* @returns {Promise<AssistantDocument|null>} The assistant document as a plain object, or null if not found.
|
||||||
*/
|
*/
|
||||||
const getAssistant = async (searchParams) => await db.models.Assistant.findOne(searchParams).lean();
|
const getAssistant = async (searchParams) => await Assistant.findOne(searchParams).lean();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all assistants that match the given search parameters.
|
* Retrieves all assistants that match the given search parameters.
|
||||||
|
|
@ -33,7 +33,7 @@ const getAssistant = async (searchParams) => await db.models.Assistant.findOne(s
|
||||||
* @returns {Promise<Array<AssistantDocument>>} A promise that resolves to an array of assistant documents as plain objects.
|
* @returns {Promise<Array<AssistantDocument>>} A promise that resolves to an array of assistant documents as plain objects.
|
||||||
*/
|
*/
|
||||||
const getAssistants = async (searchParams, select = null) => {
|
const getAssistants = async (searchParams, select = null) => {
|
||||||
let query = db.models.Assistant.find(searchParams);
|
let query = Assistant.find(searchParams);
|
||||||
|
|
||||||
if (select) {
|
if (select) {
|
||||||
query = query.select(select);
|
query = query.select(select);
|
||||||
|
|
@ -51,7 +51,7 @@ const getAssistants = async (searchParams, select = null) => {
|
||||||
* @returns {Promise<void>} Resolves when the assistant has been successfully deleted.
|
* @returns {Promise<void>} Resolves when the assistant has been successfully deleted.
|
||||||
*/
|
*/
|
||||||
const deleteAssistant = async (searchParams) => {
|
const deleteAssistant = async (searchParams) => {
|
||||||
return await db.models.Assistant.findOneAndDelete(searchParams);
|
return await Assistant.findOneAndDelete(searchParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
const logger = require('~/config/winston');
|
const { Banner, logger } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current active banner.
|
* Retrieves the current active banner.
|
||||||
|
|
@ -8,7 +7,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
const getBanner = async (user) => {
|
const getBanner = async (user) => {
|
||||||
try {
|
try {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const banner = await db.models.Banner.findOne({
|
const banner = await Banner.findOne({
|
||||||
displayFrom: { $lte: now },
|
displayFrom: { $lte: now },
|
||||||
$or: [{ displayTo: { $gte: now } }, { displayTo: null }],
|
$or: [{ displayTo: { $gte: now } }, { displayTo: null }],
|
||||||
type: 'banner',
|
type: 'banner',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
|
const { Conversation, logger } = require('@librechat/data-schemas');
|
||||||
const { getMessages, deleteMessages } = require('./Message');
|
const { getMessages, deleteMessages } = require('./Message');
|
||||||
const logger = require('~/config/winston');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
/**
|
/**
|
||||||
* Searches for a conversation by conversationId and returns a lean document with only conversationId and user.
|
* Searches for a conversation by conversationId and returns a lean document with only conversationId and user.
|
||||||
* @param {string} conversationId - The conversation's ID.
|
* @param {string} conversationId - The conversation's ID.
|
||||||
|
|
@ -8,7 +7,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
*/
|
*/
|
||||||
const searchConversation = async (conversationId) => {
|
const searchConversation = async (conversationId) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.Conversation.findOne({ conversationId }, 'conversationId user').lean();
|
return await Conversation.findOne({ conversationId }, 'conversationId user').lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[searchConversation] Error searching conversation', error);
|
logger.error('[searchConversation] Error searching conversation', error);
|
||||||
throw new Error('Error searching conversation');
|
throw new Error('Error searching conversation');
|
||||||
|
|
@ -23,7 +22,7 @@ const searchConversation = async (conversationId) => {
|
||||||
*/
|
*/
|
||||||
const getConvo = async (user, conversationId) => {
|
const getConvo = async (user, conversationId) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.Conversation.findOne({ user, conversationId }).lean();
|
return await Conversation.findOne({ user, conversationId }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[getConvo] Error getting single conversation', error);
|
logger.error('[getConvo] Error getting single conversation', error);
|
||||||
return { message: 'Error getting single conversation' };
|
return { message: 'Error getting single conversation' };
|
||||||
|
|
@ -40,7 +39,7 @@ const deleteNullOrEmptyConversations = async () => {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await db.models.Conversation.deleteMany(filter);
|
const result = await Conversation.deleteMany(filter);
|
||||||
|
|
||||||
// Delete associated messages
|
// Delete associated messages
|
||||||
const messageDeleteResult = await deleteMessages(filter);
|
const messageDeleteResult = await deleteMessages(filter);
|
||||||
|
|
@ -66,7 +65,7 @@ const deleteNullOrEmptyConversations = async () => {
|
||||||
*/
|
*/
|
||||||
const getConvoFiles = async (conversationId) => {
|
const getConvoFiles = async (conversationId) => {
|
||||||
try {
|
try {
|
||||||
return (await db.models.Conversation.findOne({ conversationId }, 'files').lean())?.files ?? [];
|
return (await Conversation.findOne({ conversationId }, 'files').lean())?.files ?? [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[getConvoFiles] Error getting conversation files', error);
|
logger.error('[getConvoFiles] Error getting conversation files', error);
|
||||||
throw new Error('Error getting conversation files');
|
throw new Error('Error getting conversation files');
|
||||||
|
|
@ -112,7 +111,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Note: the resulting Model object is necessary for Meilisearch operations */
|
/** Note: the resulting Model object is necessary for Meilisearch operations */
|
||||||
const conversation = await db.models.Conversation.findOneAndUpdate(
|
const conversation = await Conversation.findOneAndUpdate(
|
||||||
{ conversationId, user: req.user.id },
|
{ conversationId, user: req.user.id },
|
||||||
updateOperation,
|
updateOperation,
|
||||||
{
|
{
|
||||||
|
|
@ -141,7 +140,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const result = await db.models.Conversation.bulkWrite(bulkOps);
|
const result = await Conversation.bulkWrite(bulkOps);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[saveBulkConversations] Error saving conversations in bulk', error);
|
logger.error('[saveBulkConversations] Error saving conversations in bulk', error);
|
||||||
|
|
@ -153,7 +152,6 @@ module.exports = {
|
||||||
{ cursor, limit = 25, isArchived = false, tags, search, order = 'desc' } = {},
|
{ cursor, limit = 25, isArchived = false, tags, search, order = 'desc' } = {},
|
||||||
) => {
|
) => {
|
||||||
const filters = [{ user }];
|
const filters = [{ user }];
|
||||||
const { Conversation } = db.models;
|
|
||||||
if (isArchived) {
|
if (isArchived) {
|
||||||
filters.push({ isArchived: true });
|
filters.push({ isArchived: true });
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -217,7 +215,7 @@ module.exports = {
|
||||||
|
|
||||||
const conversationIds = convoIds.map((convo) => convo.conversationId);
|
const conversationIds = convoIds.map((convo) => convo.conversationId);
|
||||||
|
|
||||||
const results = await db.models.Conversation.find({
|
const results = await Conversation.find({
|
||||||
user,
|
user,
|
||||||
conversationId: { $in: conversationIds },
|
conversationId: { $in: conversationIds },
|
||||||
$or: [{ expiredAt: { $exists: false } }, { expiredAt: null }],
|
$or: [{ expiredAt: { $exists: false } }, { expiredAt: null }],
|
||||||
|
|
@ -286,7 +284,6 @@ module.exports = {
|
||||||
deleteConvos: async (user, filter) => {
|
deleteConvos: async (user, filter) => {
|
||||||
try {
|
try {
|
||||||
const userFilter = { ...filter, user };
|
const userFilter = { ...filter, user };
|
||||||
const { Conversation } = db.models;
|
|
||||||
const conversations = await Conversation.find(userFilter).select('conversationId');
|
const conversations = await Conversation.find(userFilter).select('conversationId');
|
||||||
const conversationIds = conversations.map((c) => c.conversationId);
|
const conversationIds = conversations.map((c) => c.conversationId);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
const logger = require('~/config/winston');
|
const { ConversationTag, Conversation, logger } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all conversation tags for a user.
|
* Retrieves all conversation tags for a user.
|
||||||
|
|
@ -8,7 +7,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
*/
|
*/
|
||||||
const getConversationTags = async (user) => {
|
const getConversationTags = async (user) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.ConversationTag.find({ user }).sort({ position: 1 }).lean();
|
return await ConversationTag.find({ user }).sort({ position: 1 }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[getConversationTags] Error getting conversation tags', error);
|
logger.error('[getConversationTags] Error getting conversation tags', error);
|
||||||
throw new Error('Error getting conversation tags');
|
throw new Error('Error getting conversation tags');
|
||||||
|
|
@ -29,7 +28,6 @@ const createConversationTag = async (user, data) => {
|
||||||
try {
|
try {
|
||||||
const { tag, description, addToConversation, conversationId } = data;
|
const { tag, description, addToConversation, conversationId } = data;
|
||||||
|
|
||||||
const { ConversationTag, Conversation } = db.models;
|
|
||||||
const existingTag = await ConversationTag.findOne({ user, tag }).lean();
|
const existingTag = await ConversationTag.findOne({ user, tag }).lean();
|
||||||
if (existingTag) {
|
if (existingTag) {
|
||||||
return existingTag;
|
return existingTag;
|
||||||
|
|
@ -84,7 +82,6 @@ const updateConversationTag = async (user, oldTag, data) => {
|
||||||
try {
|
try {
|
||||||
const { tag: newTag, description, position } = data;
|
const { tag: newTag, description, position } = data;
|
||||||
|
|
||||||
const { ConversationTag, Conversation } = db.models;
|
|
||||||
const existingTag = await ConversationTag.findOne({ user, tag: oldTag }).lean();
|
const existingTag = await ConversationTag.findOne({ user, tag: oldTag }).lean();
|
||||||
if (!existingTag) {
|
if (!existingTag) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -145,7 +142,7 @@ const adjustPositions = async (user, oldPosition, newPosition) => {
|
||||||
$lt: Math.max(oldPosition, newPosition),
|
$lt: Math.max(oldPosition, newPosition),
|
||||||
};
|
};
|
||||||
|
|
||||||
await db.models.ConversationTag.updateMany(
|
await ConversationTag.updateMany(
|
||||||
{
|
{
|
||||||
user,
|
user,
|
||||||
position,
|
position,
|
||||||
|
|
@ -162,7 +159,6 @@ const adjustPositions = async (user, oldPosition, newPosition) => {
|
||||||
*/
|
*/
|
||||||
const deleteConversationTag = async (user, tag) => {
|
const deleteConversationTag = async (user, tag) => {
|
||||||
try {
|
try {
|
||||||
const { ConversationTag, Conversation } = db.models;
|
|
||||||
const deletedTag = await ConversationTag.findOneAndDelete({ user, tag }).lean();
|
const deletedTag = await ConversationTag.findOneAndDelete({ user, tag }).lean();
|
||||||
if (!deletedTag) {
|
if (!deletedTag) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -191,7 +187,6 @@ const deleteConversationTag = async (user, tag) => {
|
||||||
*/
|
*/
|
||||||
const updateTagsForConversation = async (user, conversationId, tags) => {
|
const updateTagsForConversation = async (user, conversationId, tags) => {
|
||||||
try {
|
try {
|
||||||
const { ConversationTag, Conversation } = db.models;
|
|
||||||
const conversation = await Conversation.findOne({ user, conversationId }).lean();
|
const conversation = await Conversation.findOne({ user, conversationId }).lean();
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
throw new Error('Conversation not found');
|
throw new Error('Conversation not found');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const { File } = require('@librechat/data-schemas');
|
||||||
const { EToolResources } = require('librechat-data-provider');
|
const { EToolResources } = require('librechat-data-provider');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a file by its file_id with additional query options.
|
* Finds a file by its file_id with additional query options.
|
||||||
|
|
@ -10,7 +10,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
* @returns {Promise<MongoFile>} A promise that resolves to the file document or null.
|
* @returns {Promise<MongoFile>} A promise that resolves to the file document or null.
|
||||||
*/
|
*/
|
||||||
const findFileById = async (file_id, options = {}) => {
|
const findFileById = async (file_id, options = {}) => {
|
||||||
return await db.models.File.findOne({ file_id, ...options }).lean();
|
return await File.findOne({ file_id, ...options }).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -23,7 +23,7 @@ const findFileById = async (file_id, options = {}) => {
|
||||||
*/
|
*/
|
||||||
const getFiles = async (filter, _sortOptions, selectFields = { text: 0 }) => {
|
const getFiles = async (filter, _sortOptions, selectFields = { text: 0 }) => {
|
||||||
const sortOptions = { updatedAt: -1, ..._sortOptions };
|
const sortOptions = { updatedAt: -1, ..._sortOptions };
|
||||||
return await db.models.File.find(filter).select(selectFields).sort(sortOptions).lean();
|
return await File.find(filter).select(selectFields).sort(sortOptions).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -79,7 +79,7 @@ const createFile = async (data, disableTTL) => {
|
||||||
delete fileData.expiresAt;
|
delete fileData.expiresAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await db.models.File.findOneAndUpdate({ file_id: data.file_id }, fileData, {
|
return await File.findOneAndUpdate({ file_id: data.file_id }, fileData, {
|
||||||
new: true,
|
new: true,
|
||||||
upsert: true,
|
upsert: true,
|
||||||
}).lean();
|
}).lean();
|
||||||
|
|
@ -96,7 +96,7 @@ const updateFile = async (data) => {
|
||||||
$set: update,
|
$set: update,
|
||||||
$unset: { expiresAt: '' }, // Remove the expiresAt field to prevent TTL
|
$unset: { expiresAt: '' }, // Remove the expiresAt field to prevent TTL
|
||||||
};
|
};
|
||||||
return await db.models.File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
|
return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -110,7 +110,7 @@ const updateFileUsage = async (data) => {
|
||||||
$inc: { usage: inc },
|
$inc: { usage: inc },
|
||||||
$unset: { expiresAt: '', temp_file_id: '' },
|
$unset: { expiresAt: '', temp_file_id: '' },
|
||||||
};
|
};
|
||||||
return await db.models.File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
|
return await File.findOneAndUpdate({ file_id }, updateOperation, { new: true }).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -119,7 +119,7 @@ const updateFileUsage = async (data) => {
|
||||||
* @returns {Promise<MongoFile>} A promise that resolves to the deleted file document or null.
|
* @returns {Promise<MongoFile>} A promise that resolves to the deleted file document or null.
|
||||||
*/
|
*/
|
||||||
const deleteFile = async (file_id) => {
|
const deleteFile = async (file_id) => {
|
||||||
return await db.models.File.findOneAndDelete({ file_id }).lean();
|
return await File.findOneAndDelete({ file_id }).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -128,7 +128,7 @@ const deleteFile = async (file_id) => {
|
||||||
* @returns {Promise<MongoFile>} A promise that resolves to the deleted file document or null.
|
* @returns {Promise<MongoFile>} A promise that resolves to the deleted file document or null.
|
||||||
*/
|
*/
|
||||||
const deleteFileByFilter = async (filter) => {
|
const deleteFileByFilter = async (filter) => {
|
||||||
return await db.models.File.findOneAndDelete(filter).lean();
|
return await File.findOneAndDelete(filter).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -141,7 +141,7 @@ const deleteFiles = async (file_ids, user) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
deleteQuery = { user: user };
|
deleteQuery = { user: user };
|
||||||
}
|
}
|
||||||
return await db.models.File.deleteMany(deleteQuery);
|
return await File.deleteMany(deleteQuery);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
const { z } = require('zod');
|
const { z } = require('zod');
|
||||||
const { logger } = require('~/config');
|
const { Message, logger } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const idSchema = z.string().uuid();
|
const idSchema = z.string().uuid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -67,7 +66,7 @@ async function saveMessage(req, params, metadata) {
|
||||||
logger.info(`---\`saveMessage\` context: ${metadata?.context}`);
|
logger.info(`---\`saveMessage\` context: ${metadata?.context}`);
|
||||||
update.tokenCount = 0;
|
update.tokenCount = 0;
|
||||||
}
|
}
|
||||||
const message = await db.models.Message.findOneAndUpdate(
|
const message = await Message.findOneAndUpdate(
|
||||||
{ messageId: params.messageId, user: req.user.id },
|
{ messageId: params.messageId, user: req.user.id },
|
||||||
update,
|
update,
|
||||||
{ upsert: true, new: true },
|
{ upsert: true, new: true },
|
||||||
|
|
@ -85,7 +84,7 @@ async function saveMessage(req, params, metadata) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to find the existing message with this ID
|
// Try to find the existing message with this ID
|
||||||
const existingMessage = await db.models.Message.findOne({
|
const existingMessage = await Message.findOne({
|
||||||
messageId: params.messageId,
|
messageId: params.messageId,
|
||||||
user: req.user.id,
|
user: req.user.id,
|
||||||
});
|
});
|
||||||
|
|
@ -138,7 +137,7 @@ async function bulkSaveMessages(messages, overrideTimestamp = false) {
|
||||||
upsert: true,
|
upsert: true,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
const result = await db.models.Message.bulkWrite(bulkOps);
|
const result = await Message.bulkWrite(bulkOps);
|
||||||
return result;
|
return result;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Error saving messages in bulk:', err);
|
logger.error('Error saving messages in bulk:', err);
|
||||||
|
|
@ -180,7 +179,7 @@ async function recordMessage({
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
|
|
||||||
return await db.models.Message.findOneAndUpdate({ user, messageId }, message, {
|
return await Message.findOneAndUpdate({ user, messageId }, message, {
|
||||||
upsert: true,
|
upsert: true,
|
||||||
new: true,
|
new: true,
|
||||||
});
|
});
|
||||||
|
|
@ -204,7 +203,7 @@ async function recordMessage({
|
||||||
*/
|
*/
|
||||||
async function updateMessageText(req, { messageId, text }) {
|
async function updateMessageText(req, { messageId, text }) {
|
||||||
try {
|
try {
|
||||||
await db.models?.Message.updateOne({ messageId, user: req.user.id }, { text });
|
await Message.updateOne({ messageId, user: req.user.id }, { text });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Error updating message text:', err);
|
logger.error('Error updating message text:', err);
|
||||||
throw err;
|
throw err;
|
||||||
|
|
@ -232,7 +231,7 @@ async function updateMessageText(req, { messageId, text }) {
|
||||||
async function updateMessage(req, message, metadata) {
|
async function updateMessage(req, message, metadata) {
|
||||||
try {
|
try {
|
||||||
const { messageId, ...update } = message;
|
const { messageId, ...update } = message;
|
||||||
const updatedMessage = await db.models.Message.findOneAndUpdate(
|
const updatedMessage = await Message.findOneAndUpdate(
|
||||||
{ messageId, user: req.user.id },
|
{ messageId, user: req.user.id },
|
||||||
update,
|
update,
|
||||||
{
|
{
|
||||||
|
|
@ -276,10 +275,10 @@ async function updateMessage(req, message, metadata) {
|
||||||
*/
|
*/
|
||||||
async function deleteMessagesSince(req, { messageId, conversationId }) {
|
async function deleteMessagesSince(req, { messageId, conversationId }) {
|
||||||
try {
|
try {
|
||||||
const message = await db.models.Message.findOne({ messageId, user: req.user.id }).lean();
|
const message = await Message.findOne({ messageId, user: req.user.id }).lean();
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
const query = db.models.Message.find({ conversationId, user: req.user.id });
|
const query = Message.find({ conversationId, user: req.user.id });
|
||||||
return await query.deleteMany({
|
return await query.deleteMany({
|
||||||
createdAt: { $gt: message.createdAt },
|
createdAt: { $gt: message.createdAt },
|
||||||
});
|
});
|
||||||
|
|
@ -303,10 +302,10 @@ async function deleteMessagesSince(req, { messageId, conversationId }) {
|
||||||
async function getMessages(filter, select) {
|
async function getMessages(filter, select) {
|
||||||
try {
|
try {
|
||||||
if (select) {
|
if (select) {
|
||||||
return await db.models.Message.find(filter).select(select).sort({ createdAt: 1 }).lean();
|
return await Message.find(filter).select(select).sort({ createdAt: 1 }).lean();
|
||||||
}
|
}
|
||||||
|
|
||||||
return await db.models.Message.find(filter).sort({ createdAt: 1 }).lean();
|
return await Message.find(filter).sort({ createdAt: 1 }).lean();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Error getting messages:', err);
|
logger.error('Error getting messages:', err);
|
||||||
throw err;
|
throw err;
|
||||||
|
|
@ -323,7 +322,7 @@ async function getMessages(filter, select) {
|
||||||
*/
|
*/
|
||||||
async function getMessage({ user, messageId }) {
|
async function getMessage({ user, messageId }) {
|
||||||
try {
|
try {
|
||||||
return await db.models.Message.findOne({
|
return await Message.findOne({
|
||||||
user,
|
user,
|
||||||
messageId,
|
messageId,
|
||||||
}).lean();
|
}).lean();
|
||||||
|
|
@ -344,7 +343,7 @@ async function getMessage({ user, messageId }) {
|
||||||
*/
|
*/
|
||||||
async function deleteMessages(filter) {
|
async function deleteMessages(filter) {
|
||||||
try {
|
try {
|
||||||
return await db.models.Message.deleteMany(filter);
|
return await Message.deleteMany(filter);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Error deleting messages:', err);
|
logger.error('Error deleting messages:', err);
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
const { logger } = require('~/config');
|
const { Preset, logger } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const getPreset = async (user, presetId) => {
|
const getPreset = async (user, presetId) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.Preset.findOne({ user, presetId }).lean();
|
return await Preset.findOne({ user, presetId }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[getPreset] Error getting single preset', error);
|
logger.error('[getPreset] Error getting single preset', error);
|
||||||
return { message: 'Error getting single preset' };
|
return { message: 'Error getting single preset' };
|
||||||
|
|
@ -14,7 +13,7 @@ module.exports = {
|
||||||
getPreset,
|
getPreset,
|
||||||
getPresets: async (user, filter) => {
|
getPresets: async (user, filter) => {
|
||||||
try {
|
try {
|
||||||
const presets = await db.models.Preset.find({ ...filter, user }).lean();
|
const presets = await Preset.find({ ...filter, user }).lean();
|
||||||
const defaultValue = 10000;
|
const defaultValue = 10000;
|
||||||
|
|
||||||
presets.sort((a, b) => {
|
presets.sort((a, b) => {
|
||||||
|
|
@ -39,7 +38,6 @@ module.exports = {
|
||||||
const setter = { $set: {} };
|
const setter = { $set: {} };
|
||||||
const { user: _, ...cleanPreset } = preset;
|
const { user: _, ...cleanPreset } = preset;
|
||||||
const update = { presetId, ...cleanPreset };
|
const update = { presetId, ...cleanPreset };
|
||||||
const Preset = db.models.Preset;
|
|
||||||
if (preset.tools && Array.isArray(preset.tools)) {
|
if (preset.tools && Array.isArray(preset.tools)) {
|
||||||
update.tools =
|
update.tools =
|
||||||
preset.tools
|
preset.tools
|
||||||
|
|
@ -77,7 +75,7 @@ module.exports = {
|
||||||
deletePresets: async (user, filter) => {
|
deletePresets: async (user, filter) => {
|
||||||
// let toRemove = await Preset.find({ ...filter, user }).select('presetId');
|
// let toRemove = await Preset.find({ ...filter, user }).select('presetId');
|
||||||
// const ids = toRemove.map((instance) => instance.presetId);
|
// const ids = toRemove.map((instance) => instance.presetId);
|
||||||
let deleteCount = await db.models.Preset.deleteMany({ ...filter, user });
|
let deleteCount = await Preset.deleteMany({ ...filter, user });
|
||||||
return deleteCount;
|
return deleteCount;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
const { Project } = require('@librechat/data-schemas');
|
||||||
const { GLOBAL_PROJECT_NAME } = require('librechat-data-provider').Constants;
|
const { GLOBAL_PROJECT_NAME } = require('librechat-data-provider').Constants;
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a project by ID and convert the found project document to a plain object.
|
* Retrieve a project by ID and convert the found project document to a plain object.
|
||||||
|
|
@ -9,7 +9,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
* @returns {Promise<IMongoProject>} A plain object representing the project document, or `null` if no project is found.
|
* @returns {Promise<IMongoProject>} A plain object representing the project document, or `null` if no project is found.
|
||||||
*/
|
*/
|
||||||
const getProjectById = async function (projectId, fieldsToSelect = null) {
|
const getProjectById = async function (projectId, fieldsToSelect = null) {
|
||||||
const query = db.models.Project.findById(projectId);
|
const query = Project.findById(projectId);
|
||||||
|
|
||||||
if (fieldsToSelect) {
|
if (fieldsToSelect) {
|
||||||
query.select(fieldsToSelect);
|
query.select(fieldsToSelect);
|
||||||
|
|
@ -36,7 +36,7 @@ const getProjectByName = async function (projectName, fieldsToSelect = null) {
|
||||||
select: fieldsToSelect,
|
select: fieldsToSelect,
|
||||||
};
|
};
|
||||||
|
|
||||||
return await db.models.Project.findOneAndUpdate(query, update, options);
|
return await Project.findOneAndUpdate(query, update, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,7 +47,7 @@ const getProjectByName = async function (projectName, fieldsToSelect = null) {
|
||||||
* @returns {Promise<IMongoProject>} The updated project document.
|
* @returns {Promise<IMongoProject>} The updated project document.
|
||||||
*/
|
*/
|
||||||
const addGroupIdsToProject = async function (projectId, promptGroupIds) {
|
const addGroupIdsToProject = async function (projectId, promptGroupIds) {
|
||||||
return await db.models.Project.findByIdAndUpdate(
|
return await Project.findByIdAndUpdate(
|
||||||
projectId,
|
projectId,
|
||||||
{ $addToSet: { promptGroupIds: { $each: promptGroupIds } } },
|
{ $addToSet: { promptGroupIds: { $each: promptGroupIds } } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
|
|
@ -62,7 +62,7 @@ const addGroupIdsToProject = async function (projectId, promptGroupIds) {
|
||||||
* @returns {Promise<IMongoProject>} The updated project document.
|
* @returns {Promise<IMongoProject>} The updated project document.
|
||||||
*/
|
*/
|
||||||
const removeGroupIdsFromProject = async function (projectId, promptGroupIds) {
|
const removeGroupIdsFromProject = async function (projectId, promptGroupIds) {
|
||||||
return await db.models.Project.findByIdAndUpdate(
|
return await Project.findByIdAndUpdate(
|
||||||
projectId,
|
projectId,
|
||||||
{ $pull: { promptGroupIds: { $in: promptGroupIds } } },
|
{ $pull: { promptGroupIds: { $in: promptGroupIds } } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
|
|
@ -76,7 +76,7 @@ const removeGroupIdsFromProject = async function (projectId, promptGroupIds) {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
const removeGroupFromAllProjects = async (promptGroupId) => {
|
const removeGroupFromAllProjects = async (promptGroupId) => {
|
||||||
await db.models.Project.updateMany({}, { $pull: { promptGroupIds: promptGroupId } });
|
await Project.updateMany({}, { $pull: { promptGroupIds: promptGroupId } });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -87,7 +87,7 @@ const removeGroupFromAllProjects = async (promptGroupId) => {
|
||||||
* @returns {Promise<IMongoProject>} The updated project document.
|
* @returns {Promise<IMongoProject>} The updated project document.
|
||||||
*/
|
*/
|
||||||
const addAgentIdsToProject = async function (projectId, agentIds) {
|
const addAgentIdsToProject = async function (projectId, agentIds) {
|
||||||
return await db.models.Project.findByIdAndUpdate(
|
return await Project.findByIdAndUpdate(
|
||||||
projectId,
|
projectId,
|
||||||
{ $addToSet: { agentIds: { $each: agentIds } } },
|
{ $addToSet: { agentIds: { $each: agentIds } } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
|
|
@ -102,7 +102,7 @@ const addAgentIdsToProject = async function (projectId, agentIds) {
|
||||||
* @returns {Promise<IMongoProject>} The updated project document.
|
* @returns {Promise<IMongoProject>} The updated project document.
|
||||||
*/
|
*/
|
||||||
const removeAgentIdsFromProject = async function (projectId, agentIds) {
|
const removeAgentIdsFromProject = async function (projectId, agentIds) {
|
||||||
return await db.models.Project.findByIdAndUpdate(
|
return await Project.findByIdAndUpdate(
|
||||||
projectId,
|
projectId,
|
||||||
{ $pull: { agentIds: { $in: agentIds } } },
|
{ $pull: { agentIds: { $in: agentIds } } },
|
||||||
{ new: true },
|
{ new: true },
|
||||||
|
|
@ -116,7 +116,7 @@ const removeAgentIdsFromProject = async function (projectId, agentIds) {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
const removeAgentFromAllProjects = async (agentId) => {
|
const removeAgentFromAllProjects = async (agentId) => {
|
||||||
await db.models.Project.updateMany({}, { $pull: { agentIds: agentId } });
|
await Project.updateMany({}, { $pull: { agentIds: agentId } });
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const { ObjectId } = require('mongodb');
|
const { ObjectId } = require('mongodb');
|
||||||
|
const { Prompt, PromptGroup, logger } = require('@librechat/data-schemas');
|
||||||
const { SystemRoles, SystemCategories, Constants } = require('librechat-data-provider');
|
const { SystemRoles, SystemCategories, Constants } = require('librechat-data-provider');
|
||||||
const {
|
const {
|
||||||
getProjectByName,
|
getProjectByName,
|
||||||
|
|
@ -7,8 +8,6 @@ const {
|
||||||
removeGroupFromAllProjects,
|
removeGroupFromAllProjects,
|
||||||
} = require('./Project');
|
} = require('./Project');
|
||||||
const { escapeRegExp } = require('~/server/utils');
|
const { escapeRegExp } = require('~/server/utils');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a pipeline for the aggregation to get prompt groups
|
* Create a pipeline for the aggregation to get prompt groups
|
||||||
|
|
@ -133,7 +132,7 @@ const getAllPromptGroups = async (req, filter) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const promptGroupsPipeline = createAllGroupsPipeline(combinedQuery);
|
const promptGroupsPipeline = createAllGroupsPipeline(combinedQuery);
|
||||||
return await db.models.PromptGroup.aggregate(promptGroupsPipeline).exec();
|
return await PromptGroup.aggregate(promptGroupsPipeline).exec();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting all prompt groups', error);
|
console.error('Error getting all prompt groups', error);
|
||||||
return { message: 'Error getting all prompt groups' };
|
return { message: 'Error getting all prompt groups' };
|
||||||
|
|
@ -233,7 +232,7 @@ const deletePromptGroup = async ({ _id, author, role }) => {
|
||||||
throw new Error('Prompt group not found');
|
throw new Error('Prompt group not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.models.Prompt.deleteMany(groupQuery);
|
await Prompt.deleteMany(groupQuery);
|
||||||
await removeGroupFromAllProjects(_id);
|
await removeGroupFromAllProjects(_id);
|
||||||
return { message: 'Prompt group deleted successfully' };
|
return { message: 'Prompt group deleted successfully' };
|
||||||
};
|
};
|
||||||
|
|
@ -250,7 +249,6 @@ module.exports = {
|
||||||
createPromptGroup: async (saveData) => {
|
createPromptGroup: async (saveData) => {
|
||||||
try {
|
try {
|
||||||
const { prompt, group, author, authorName } = saveData;
|
const { prompt, group, author, authorName } = saveData;
|
||||||
const { Prompt, PromptGroup } = db.models;
|
|
||||||
|
|
||||||
let newPromptGroup = await PromptGroup.findOneAndUpdate(
|
let newPromptGroup = await PromptGroup.findOneAndUpdate(
|
||||||
{ ...group, author, authorName, productionId: null },
|
{ ...group, author, authorName, productionId: null },
|
||||||
|
|
@ -306,7 +304,6 @@ module.exports = {
|
||||||
|
|
||||||
/** @type {TPrompt} */
|
/** @type {TPrompt} */
|
||||||
let newPrompt;
|
let newPrompt;
|
||||||
const { Prompt } = db.models;
|
|
||||||
try {
|
try {
|
||||||
newPrompt = await Prompt.create(newPromptData);
|
newPrompt = await Prompt.create(newPromptData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -326,7 +323,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
getPrompts: async (filter) => {
|
getPrompts: async (filter) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.Prompt.find(filter).sort({ createdAt: -1 }).lean();
|
return await Prompt.find(filter).sort({ createdAt: -1 }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error getting prompts', error);
|
logger.error('Error getting prompts', error);
|
||||||
return { message: 'Error getting prompts' };
|
return { message: 'Error getting prompts' };
|
||||||
|
|
@ -337,7 +334,7 @@ module.exports = {
|
||||||
if (filter.groupId) {
|
if (filter.groupId) {
|
||||||
filter.groupId = new ObjectId(filter.groupId);
|
filter.groupId = new ObjectId(filter.groupId);
|
||||||
}
|
}
|
||||||
return await db.models.Prompt.findOne(filter).lean();
|
return await Prompt.findOne(filter).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error getting prompt', error);
|
logger.error('Error getting prompt', error);
|
||||||
return { message: 'Error getting prompt' };
|
return { message: 'Error getting prompt' };
|
||||||
|
|
@ -350,7 +347,7 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
getRandomPromptGroups: async (filter) => {
|
getRandomPromptGroups: async (filter) => {
|
||||||
try {
|
try {
|
||||||
const result = await db.models.PromptGroup.aggregate([
|
const result = await PromptGroup.aggregate([
|
||||||
{
|
{
|
||||||
$match: {
|
$match: {
|
||||||
category: { $ne: '' },
|
category: { $ne: '' },
|
||||||
|
|
@ -383,7 +380,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
getPromptGroupsWithPrompts: async (filter) => {
|
getPromptGroupsWithPrompts: async (filter) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.PromptGroup.findOne(filter)
|
return await PromptGroup.findOne(filter)
|
||||||
.populate({
|
.populate({
|
||||||
path: 'prompts',
|
path: 'prompts',
|
||||||
select: '-_id -__v -user',
|
select: '-_id -__v -user',
|
||||||
|
|
@ -397,7 +394,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
getPromptGroup: async (filter) => {
|
getPromptGroup: async (filter) => {
|
||||||
try {
|
try {
|
||||||
return await db.models.PromptGroup.findOne(filter).lean();
|
return await PromptGroup.findOne(filter).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error getting prompt group', error);
|
logger.error('Error getting prompt group', error);
|
||||||
return { message: 'Error getting prompt group' };
|
return { message: 'Error getting prompt group' };
|
||||||
|
|
@ -418,7 +415,6 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
deletePrompt: async ({ promptId, groupId, author, role }) => {
|
deletePrompt: async ({ promptId, groupId, author, role }) => {
|
||||||
const query = { _id: promptId, groupId, author };
|
const query = { _id: promptId, groupId, author };
|
||||||
const { Prompt, PromptGroup } = db.models;
|
|
||||||
if (role === SystemRoles.ADMIN) {
|
if (role === SystemRoles.ADMIN) {
|
||||||
delete query.author;
|
delete query.author;
|
||||||
}
|
}
|
||||||
|
|
@ -483,7 +479,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateData = { ...data, ...updateOps };
|
const updateData = { ...data, ...updateOps };
|
||||||
const updatedDoc = await db.models.PromptGroup.findOneAndUpdate(filter, updateData, {
|
const updatedDoc = await PromptGroup.findOneAndUpdate(filter, updateData, {
|
||||||
new: true,
|
new: true,
|
||||||
upsert: false,
|
upsert: false,
|
||||||
});
|
});
|
||||||
|
|
@ -505,7 +501,6 @@ module.exports = {
|
||||||
*/
|
*/
|
||||||
makePromptProduction: async (promptId) => {
|
makePromptProduction: async (promptId) => {
|
||||||
try {
|
try {
|
||||||
const { Prompt, PromptGroup } = db.models;
|
|
||||||
const prompt = await Prompt.findById(promptId).lean();
|
const prompt = await Prompt.findById(promptId).lean();
|
||||||
|
|
||||||
if (!prompt) {
|
if (!prompt) {
|
||||||
|
|
@ -530,7 +525,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
updatePromptLabels: async (_id, labels) => {
|
updatePromptLabels: async (_id, labels) => {
|
||||||
try {
|
try {
|
||||||
const response = await db.models.Prompt.updateOne({ _id }, { $set: { labels } });
|
const response = await Prompt.updateOne({ _id }, { $set: { labels } });
|
||||||
if (response.matchedCount === 0) {
|
if (response.matchedCount === 0) {
|
||||||
return { message: 'Prompt not found' };
|
return { message: 'Prompt not found' };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,8 @@ const {
|
||||||
permissionsSchema,
|
permissionsSchema,
|
||||||
removeNullishValues,
|
removeNullishValues,
|
||||||
} = require('librechat-data-provider');
|
} = require('librechat-data-provider');
|
||||||
|
const { Role, logger } = require('@librechat/data-schemas');
|
||||||
const getLogStores = require('~/cache/getLogStores');
|
const getLogStores = require('~/cache/getLogStores');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a role by name and convert the found role document to a plain object.
|
* Retrieve a role by name and convert the found role document to a plain object.
|
||||||
|
|
@ -21,7 +20,6 @@ const db = require('~/lib/db/connectDb');
|
||||||
*/
|
*/
|
||||||
const getRoleByName = async function (roleName, fieldsToSelect = null) {
|
const getRoleByName = async function (roleName, fieldsToSelect = null) {
|
||||||
const cache = getLogStores(CacheKeys.ROLES);
|
const cache = getLogStores(CacheKeys.ROLES);
|
||||||
const { Role } = db.models;
|
|
||||||
try {
|
try {
|
||||||
const cachedRole = await cache.get(roleName);
|
const cachedRole = await cache.get(roleName);
|
||||||
if (cachedRole) {
|
if (cachedRole) {
|
||||||
|
|
@ -55,7 +53,7 @@ const getRoleByName = async function (roleName, fieldsToSelect = null) {
|
||||||
const updateRoleByName = async function (roleName, updates) {
|
const updateRoleByName = async function (roleName, updates) {
|
||||||
const cache = getLogStores(CacheKeys.ROLES);
|
const cache = getLogStores(CacheKeys.ROLES);
|
||||||
try {
|
try {
|
||||||
const role = await db.models.Role.findOneAndUpdate(
|
const role = await Role.findOneAndUpdate(
|
||||||
{ name: roleName },
|
{ name: roleName },
|
||||||
{ $set: updates },
|
{ $set: updates },
|
||||||
{ new: true, lean: true },
|
{ new: true, lean: true },
|
||||||
|
|
@ -76,7 +74,6 @@ const updateRoleByName = async function (roleName, updates) {
|
||||||
* @param {Object.<PermissionTypes, Object.<Permissions, boolean>>} permissionsUpdate - Permissions to update and their values.
|
* @param {Object.<PermissionTypes, Object.<Permissions, boolean>>} permissionsUpdate - Permissions to update and their values.
|
||||||
*/
|
*/
|
||||||
async function updateAccessPermissions(roleName, permissionsUpdate) {
|
async function updateAccessPermissions(roleName, permissionsUpdate) {
|
||||||
const { Role } = db.models;
|
|
||||||
// Filter and clean the permission updates based on our schema definition.
|
// Filter and clean the permission updates based on our schema definition.
|
||||||
const updates = {};
|
const updates = {};
|
||||||
for (const [permissionType, permissions] of Object.entries(permissionsUpdate)) {
|
for (const [permissionType, permissions] of Object.entries(permissionsUpdate)) {
|
||||||
|
|
@ -180,7 +177,6 @@ async function updateAccessPermissions(roleName, permissionsUpdate) {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
const initializeRoles = async function () {
|
const initializeRoles = async function () {
|
||||||
const { Role } = db.models;
|
|
||||||
for (const roleName of [SystemRoles.ADMIN, SystemRoles.USER]) {
|
for (const roleName of [SystemRoles.ADMIN, SystemRoles.USER]) {
|
||||||
let role = await Role.findOne({ name: roleName });
|
let role = await Role.findOne({ name: roleName });
|
||||||
const defaultPerms = roleDefaults[roleName].permissions;
|
const defaultPerms = roleDefaults[roleName].permissions;
|
||||||
|
|
@ -210,7 +206,6 @@ const initializeRoles = async function () {
|
||||||
* @returns {Promise<number>} Number of roles migrated.
|
* @returns {Promise<number>} Number of roles migrated.
|
||||||
*/
|
*/
|
||||||
const migrateRoleSchema = async function (roleName) {
|
const migrateRoleSchema = async function (roleName) {
|
||||||
const { Role } = db.models;
|
|
||||||
try {
|
try {
|
||||||
// Get roles to migrate
|
// Get roles to migrate
|
||||||
let roles;
|
let roles;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const { Role, logger } = require('@librechat/data-schemas');
|
||||||
const { MongoMemoryServer } = require('mongodb-memory-server');
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
const {
|
const {
|
||||||
SystemRoles,
|
SystemRoles,
|
||||||
|
|
@ -9,8 +10,6 @@ const {
|
||||||
const { getRoleByName, updateAccessPermissions, initializeRoles } = require('~/models/Role');
|
const { getRoleByName, updateAccessPermissions, initializeRoles } = require('~/models/Role');
|
||||||
const getLogStores = require('~/cache/getLogStores');
|
const getLogStores = require('~/cache/getLogStores');
|
||||||
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
// Mock the cache
|
// Mock the cache
|
||||||
jest.mock('~/cache/getLogStores', () =>
|
jest.mock('~/cache/getLogStores', () =>
|
||||||
jest.fn().mockReturnValue({
|
jest.fn().mockReturnValue({
|
||||||
|
|
@ -21,14 +20,11 @@ jest.mock('~/cache/getLogStores', () =>
|
||||||
);
|
);
|
||||||
|
|
||||||
let mongoServer;
|
let mongoServer;
|
||||||
let Role;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mongoServer = await MongoMemoryServer.create();
|
mongoServer = await MongoMemoryServer.create();
|
||||||
const mongoUri = mongoServer.getUri();
|
const mongoUri = mongoServer.getUri();
|
||||||
await db.connectDb(mongoUri);
|
await mongoose.connect(mongoUri);
|
||||||
|
|
||||||
Role = db.models.Role;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
const { nanoid } = require('nanoid');
|
const { nanoid } = require('nanoid');
|
||||||
const { Constants } = require('librechat-data-provider');
|
const { Constants } = require('librechat-data-provider');
|
||||||
const db = require('~/lib/db/connectDb');
|
const { SharedLink, Conversation, logger } = require('@librechat/data-schemas');
|
||||||
const { getMessages } = require('./Message');
|
const { getMessages } = require('./Message');
|
||||||
const logger = require('~/config/winston');
|
|
||||||
|
|
||||||
class ShareServiceError extends Error {
|
class ShareServiceError extends Error {
|
||||||
constructor(message, code) {
|
constructor(message, code) {
|
||||||
|
|
@ -73,7 +72,7 @@ function anonymizeMessages(messages, newConvoId) {
|
||||||
|
|
||||||
async function getSharedMessages(shareId) {
|
async function getSharedMessages(shareId) {
|
||||||
try {
|
try {
|
||||||
const share = await db.models.SharedLink.findOne({ shareId, isPublic: true })
|
const share = await SharedLink.findOne({ shareId, isPublic: true })
|
||||||
.populate({
|
.populate({
|
||||||
path: 'messages',
|
path: 'messages',
|
||||||
select: '-_id -__v -user',
|
select: '-_id -__v -user',
|
||||||
|
|
@ -148,7 +147,7 @@ async function getSharedLinks(user, pageParam, pageSize, isPublic, sortBy, sortD
|
||||||
query.conversationId = { $in: query.conversationId };
|
query.conversationId = { $in: query.conversationId };
|
||||||
}
|
}
|
||||||
|
|
||||||
const sharedLinks = await db.models.SharedLink.find(query)
|
const sharedLinks = await SharedLink.find(query)
|
||||||
.sort(sort)
|
.sort(sort)
|
||||||
.limit(pageSize + 1)
|
.limit(pageSize + 1)
|
||||||
.select('-__v -user')
|
.select('-__v -user')
|
||||||
|
|
@ -181,7 +180,7 @@ async function getSharedLinks(user, pageParam, pageSize, isPublic, sortBy, sortD
|
||||||
|
|
||||||
async function deleteAllSharedLinks(user) {
|
async function deleteAllSharedLinks(user) {
|
||||||
try {
|
try {
|
||||||
const result = await db.models.SharedLink.deleteMany({ user });
|
const result = await SharedLink.deleteMany({ user });
|
||||||
return {
|
return {
|
||||||
message: 'All shared links deleted successfully',
|
message: 'All shared links deleted successfully',
|
||||||
deletedCount: result.deletedCount,
|
deletedCount: result.deletedCount,
|
||||||
|
|
@ -199,7 +198,6 @@ async function createSharedLink(user, conversationId) {
|
||||||
if (!user || !conversationId) {
|
if (!user || !conversationId) {
|
||||||
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
|
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
|
||||||
}
|
}
|
||||||
const { SharedLink, Conversation } = db.models;
|
|
||||||
try {
|
try {
|
||||||
const [existingShare, conversationMessages] = await Promise.all([
|
const [existingShare, conversationMessages] = await Promise.all([
|
||||||
SharedLink.findOne({ conversationId, isPublic: true }).select('-_id -__v -user').lean(),
|
SharedLink.findOne({ conversationId, isPublic: true }).select('-_id -__v -user').lean(),
|
||||||
|
|
@ -241,7 +239,7 @@ async function getSharedLink(user, conversationId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const share = await db.models.SharedLink.findOne({ conversationId, user, isPublic: true })
|
const share = await SharedLink.findOne({ conversationId, user, isPublic: true })
|
||||||
.select('shareId -_id')
|
.select('shareId -_id')
|
||||||
.lean();
|
.lean();
|
||||||
|
|
||||||
|
|
@ -265,7 +263,6 @@ async function updateSharedLink(user, shareId) {
|
||||||
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
|
throw new ShareServiceError('Missing required parameters', 'INVALID_PARAMS');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { SharedLink } = db.models;
|
|
||||||
try {
|
try {
|
||||||
const share = await SharedLink.findOne({ shareId }).select('-_id -__v -user').lean();
|
const share = await SharedLink.findOne({ shareId }).select('-_id -__v -user').lean();
|
||||||
|
|
||||||
|
|
@ -316,7 +313,7 @@ async function deleteSharedLink(user, shareId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await db.models.SharedLink.findOneAndDelete({ shareId, user }).lean();
|
const result = await SharedLink.findOneAndDelete({ shareId, user }).lean();
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
const { Token } = require('@librechat/data-schemas');
|
||||||
const { encryptV2 } = require('~/server/utils/crypto');
|
const { encryptV2 } = require('~/server/utils/crypto');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the OAuth token by creating or updating the token.
|
* Handles the OAuth token by creating or updating the token.
|
||||||
|
|
@ -29,7 +29,6 @@ async function handleOAuthToken({
|
||||||
expiresIn: parseInt(expiresIn, 10) || 3600,
|
expiresIn: parseInt(expiresIn, 10) || 3600,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { Token } = db.models;
|
|
||||||
const existingToken = await Token.findToken({ userId, identifier });
|
const existingToken = await Token.findToken({ userId, identifier });
|
||||||
if (existingToken) {
|
if (existingToken) {
|
||||||
return await Token.updateToken({ identifier }, tokenData);
|
return await Token.updateToken({ identifier }, tokenData);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const db = require('~/lib/db/connectDb');
|
const { ToolCall } = require('@librechat/data-schemas');
|
||||||
/**
|
/**
|
||||||
* Create a new tool call
|
* Create a new tool call
|
||||||
* @param {IToolCallData} toolCallData - The tool call data
|
* @param {IToolCallData} toolCallData - The tool call data
|
||||||
|
|
@ -6,7 +6,7 @@ const db = require('~/lib/db/connectDb');
|
||||||
*/
|
*/
|
||||||
async function createToolCall(toolCallData) {
|
async function createToolCall(toolCallData) {
|
||||||
try {
|
try {
|
||||||
return await db.models.ToolCall.create(toolCallData);
|
return await ToolCall.create(toolCallData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error creating tool call: ${error.message}`);
|
throw new Error(`Error creating tool call: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ async function createToolCall(toolCallData) {
|
||||||
*/
|
*/
|
||||||
async function getToolCallById(id) {
|
async function getToolCallById(id) {
|
||||||
try {
|
try {
|
||||||
return await db.models.ToolCall.findById(id).lean();
|
return await ToolCall.findById(id).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error fetching tool call: ${error.message}`);
|
throw new Error(`Error fetching tool call: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ async function getToolCallById(id) {
|
||||||
*/
|
*/
|
||||||
async function getToolCallsByMessage(messageId, userId) {
|
async function getToolCallsByMessage(messageId, userId) {
|
||||||
try {
|
try {
|
||||||
return await db.models.ToolCall.find({ messageId, user: userId }).lean();
|
return await ToolCall.find({ messageId, user: userId }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error fetching tool calls: ${error.message}`);
|
throw new Error(`Error fetching tool calls: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ async function getToolCallsByMessage(messageId, userId) {
|
||||||
*/
|
*/
|
||||||
async function getToolCallsByConvo(conversationId, userId) {
|
async function getToolCallsByConvo(conversationId, userId) {
|
||||||
try {
|
try {
|
||||||
return await db.models.ToolCall.find({ conversationId, user: userId }).lean();
|
return await ToolCall.find({ conversationId, user: userId }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error fetching tool calls: ${error.message}`);
|
throw new Error(`Error fetching tool calls: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ async function getToolCallsByConvo(conversationId, userId) {
|
||||||
*/
|
*/
|
||||||
async function updateToolCall(id, updateData) {
|
async function updateToolCall(id, updateData) {
|
||||||
try {
|
try {
|
||||||
return await db.models.ToolCall.findByIdAndUpdate(id, updateData, { new: true }).lean();
|
return await ToolCall.findByIdAndUpdate(id, updateData, { new: true }).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error updating tool call: ${error.message}`);
|
throw new Error(`Error updating tool call: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ async function deleteToolCalls(userId, conversationId) {
|
||||||
if (conversationId) {
|
if (conversationId) {
|
||||||
query.conversationId = conversationId;
|
query.conversationId = conversationId;
|
||||||
}
|
}
|
||||||
return await db.models.ToolCall.deleteMany(query);
|
return await ToolCall.deleteMany(query);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error deleting tool call: ${error.message}`);
|
throw new Error(`Error deleting tool call: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const { transactionSchema } = require('@librechat/data-schemas');
|
const { Balance, Transaction, logger } = require('@librechat/data-schemas');
|
||||||
const { getBalanceConfig } = require('~/server/services/Config');
|
const { getBalanceConfig } = require('~/server/services/Config');
|
||||||
const { getMultiplier, getCacheMultiplier } = require('./tx');
|
const { getMultiplier, getCacheMultiplier } = require('./tx');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const cancelRate = 1.15;
|
const cancelRate = 1.15;
|
||||||
|
|
||||||
|
|
@ -23,7 +21,6 @@ const updateBalance = async ({ user, incrementValue, setValues }) => {
|
||||||
let maxRetries = 10; // Number of times to retry on conflict
|
let maxRetries = 10; // Number of times to retry on conflict
|
||||||
let delay = 50; // Initial retry delay in ms
|
let delay = 50; // Initial retry delay in ms
|
||||||
let lastError = null;
|
let lastError = null;
|
||||||
const { Balance } = db.models;
|
|
||||||
|
|
||||||
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
let currentBalanceDoc;
|
let currentBalanceDoc;
|
||||||
|
|
@ -165,7 +162,6 @@ function calculateTokenValue(txn) {
|
||||||
* @returns {Promise<object>} - The created transaction.
|
* @returns {Promise<object>} - The created transaction.
|
||||||
*/
|
*/
|
||||||
async function createAutoRefillTransaction(txData) {
|
async function createAutoRefillTransaction(txData) {
|
||||||
const Transaction = db.models.Transaction;
|
|
||||||
if (txData.rawAmount != null && isNaN(txData.rawAmount)) {
|
if (txData.rawAmount != null && isNaN(txData.rawAmount)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +194,7 @@ async function createTransaction(txData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transaction = new db.models.Transaction(txData);
|
const transaction = new Transaction(txData);
|
||||||
transaction.endpointTokenConfig = txData.endpointTokenConfig;
|
transaction.endpointTokenConfig = txData.endpointTokenConfig;
|
||||||
calculateTokenValue(transaction);
|
calculateTokenValue(transaction);
|
||||||
|
|
||||||
|
|
@ -228,7 +224,7 @@ async function createTransaction(txData) {
|
||||||
* @param {txData} txData - Transaction data.
|
* @param {txData} txData - Transaction data.
|
||||||
*/
|
*/
|
||||||
async function createStructuredTransaction(txData) {
|
async function createStructuredTransaction(txData) {
|
||||||
const transaction = new db.models.Transaction({
|
const transaction = new Transaction({
|
||||||
...txData,
|
...txData,
|
||||||
endpointTokenConfig: txData.endpointTokenConfig,
|
endpointTokenConfig: txData.endpointTokenConfig,
|
||||||
});
|
});
|
||||||
|
|
@ -329,7 +325,7 @@ function calculateStructuredTokenValue(txn) {
|
||||||
*/
|
*/
|
||||||
async function getTransactions(filter) {
|
async function getTransactions(filter) {
|
||||||
try {
|
try {
|
||||||
return await db.models.Transaction.find(filter).lean();
|
return await Transaction.find(filter).lean();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error querying transactions:', error);
|
logger.error('Error querying transactions:', error);
|
||||||
throw error;
|
throw error;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,19 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const { Balance } = require('@librechat/data-schemas');
|
||||||
const { MongoMemoryServer } = require('mongodb-memory-server');
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
const { spendTokens, spendStructuredTokens } = require('./spendTokens');
|
const { spendTokens, spendStructuredTokens } = require('./spendTokens');
|
||||||
const { getBalanceConfig } = require('~/server/services/Config');
|
const { getBalanceConfig } = require('~/server/services/Config');
|
||||||
const { getMultiplier, getCacheMultiplier } = require('./tx');
|
const { getMultiplier, getCacheMultiplier } = require('./tx');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const { createTransaction } = require('./Transaction');
|
const { createTransaction } = require('./Transaction');
|
||||||
|
|
||||||
// Mock the custom config module so we can control the balance flag.
|
// Mock the custom config module so we can control the balance flag.
|
||||||
jest.mock('~/server/services/Config');
|
jest.mock('~/server/services/Config');
|
||||||
|
|
||||||
let mongoServer;
|
let mongoServer;
|
||||||
let Balance;
|
|
||||||
let Transaction;
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mongoServer = await MongoMemoryServer.create();
|
mongoServer = await MongoMemoryServer.create();
|
||||||
const mongoUri = mongoServer.getUri();
|
const mongoUri = mongoServer.getUri();
|
||||||
await db.connectDb(mongoUri);
|
await mongoose.connect(mongoUri);
|
||||||
|
|
||||||
Balance = db.models.Balance;
|
|
||||||
Transaction = db.models.Transaction;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
const { Balance } = require('@librechat/data-schemas');
|
||||||
const { ViolationTypes } = require('librechat-data-provider');
|
const { ViolationTypes } = require('librechat-data-provider');
|
||||||
const { createAutoRefillTransaction } = require('./Transaction');
|
const { createAutoRefillTransaction } = require('./Transaction');
|
||||||
const { logViolation } = require('~/cache');
|
const { logViolation } = require('~/cache');
|
||||||
const { getMultiplier } = require('./tx');
|
const { getMultiplier } = require('./tx');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('~/config');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
function isInvalidDate(date) {
|
function isInvalidDate(date) {
|
||||||
return isNaN(date);
|
return isNaN(date);
|
||||||
|
|
@ -26,7 +26,7 @@ const checkBalanceRecord = async function ({
|
||||||
const tokenCost = amount * multiplier;
|
const tokenCost = amount * multiplier;
|
||||||
|
|
||||||
// Retrieve the balance record
|
// Retrieve the balance record
|
||||||
let record = await db.models.Balance.findOne({ user }).lean();
|
let record = await Balance.findOne({ user }).lean();
|
||||||
if (!record) {
|
if (!record) {
|
||||||
logger.debug('[Balance.check] No balance record found for user', { user });
|
logger.debug('[Balance.check] No balance record found for user', { user });
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const { Message } = require('@librechat/data-schemas');
|
||||||
const { MongoMemoryServer } = require('mongodb-memory-server');
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
const { getMessages, bulkSaveMessages } = require('./Message');
|
const { getMessages, bulkSaveMessages } = require('./Message');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
// Original version of buildTree function
|
// Original version of buildTree function
|
||||||
function buildTree({ messages, fileMap }) {
|
function buildTree({ messages, fileMap }) {
|
||||||
|
|
@ -43,13 +43,10 @@ function buildTree({ messages, fileMap }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mongod;
|
let mongod;
|
||||||
let Message;
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mongod = await MongoMemoryServer.create();
|
mongod = await MongoMemoryServer.create();
|
||||||
const uri = mongod.getUri();
|
const uri = mongod.getUri();
|
||||||
await db.connectDb(uri);
|
await mongoose.connect(uri);
|
||||||
|
|
||||||
Message = db.models.Message;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
const { Token, logger } = require('@librechat/data-schemas');
|
||||||
const { getRandomValues, hashToken } = require('~/server/utils/crypto');
|
const { getRandomValues, hashToken } = require('~/server/utils/crypto');
|
||||||
const logger = require('~/config/winston');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module inviteUser
|
* @module inviteUser
|
||||||
|
|
@ -23,7 +22,7 @@ const createInvite = async (email) => {
|
||||||
|
|
||||||
const fakeUserId = new mongoose.Types.ObjectId();
|
const fakeUserId = new mongoose.Types.ObjectId();
|
||||||
|
|
||||||
await db.models.Token.createToken({
|
await Token.createToken({
|
||||||
userId: fakeUserId,
|
userId: fakeUserId,
|
||||||
email,
|
email,
|
||||||
token: hash,
|
token: hash,
|
||||||
|
|
@ -50,7 +49,7 @@ const getInvite = async (encodedToken, email) => {
|
||||||
try {
|
try {
|
||||||
const token = decodeURIComponent(encodedToken);
|
const token = decodeURIComponent(encodedToken);
|
||||||
const hash = await hashToken(token);
|
const hash = await hashToken(token);
|
||||||
const invite = await db.models.Token.findToken({ token: hash, email });
|
const invite = await Token.findToken({ token: hash, email });
|
||||||
|
|
||||||
if (!invite) {
|
if (!invite) {
|
||||||
throw new Error('Invite not found or email does not match');
|
throw new Error('Invite not found or email does not match');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const { MongoMemoryServer } = require('mongodb-memory-server');
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
|
const { Transaction, Balance } = require('@librechat/data-schemas');
|
||||||
const { spendTokens, spendStructuredTokens } = require('./spendTokens');
|
const { spendTokens, spendStructuredTokens } = require('./spendTokens');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const { createTransaction, createAutoRefillTransaction } = require('./Transaction');
|
const { createTransaction, createAutoRefillTransaction } = require('./Transaction');
|
||||||
|
|
||||||
// Mock the logger to prevent console output during tests
|
// Mock the logger to prevent console output during tests
|
||||||
|
|
@ -20,15 +20,9 @@ describe('spendTokens', () => {
|
||||||
let mongoServer;
|
let mongoServer;
|
||||||
let userId;
|
let userId;
|
||||||
|
|
||||||
let Transaction;
|
|
||||||
let Balance;
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mongoServer = await MongoMemoryServer.create();
|
mongoServer = await MongoMemoryServer.create();
|
||||||
const mongoUri = mongoServer.getUri();
|
await mongoose.connect(mongoServer.getUri());
|
||||||
await db.connectDb(mongoUri);
|
|
||||||
|
|
||||||
Balance = db.models.Balance;
|
|
||||||
Transaction = db.models.Transaction;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const openIdClient = require('openid-client');
|
|
||||||
const cookies = require('cookie');
|
const cookies = require('cookie');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
|
const openIdClient = require('openid-client');
|
||||||
|
const { User, Session, logger } = require('@librechat/data-schemas');
|
||||||
const {
|
const {
|
||||||
registerUser,
|
registerUser,
|
||||||
resetPassword,
|
resetPassword,
|
||||||
|
|
@ -9,9 +10,7 @@ const {
|
||||||
setOpenIDAuthTokens,
|
setOpenIDAuthTokens,
|
||||||
} = require('~/server/services/AuthService');
|
} = require('~/server/services/AuthService');
|
||||||
const { getOpenIdConfig } = require('~/strategies');
|
const { getOpenIdConfig } = require('~/strategies');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const { isEnabled } = require('~/server/utils');
|
const { isEnabled } = require('~/server/utils');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const registrationController = async (req, res) => {
|
const registrationController = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -48,7 +47,7 @@ const resetPasswordController = async (req, res) => {
|
||||||
if (resetPasswordService instanceof Error) {
|
if (resetPasswordService instanceof Error) {
|
||||||
return res.status(400).json(resetPasswordService);
|
return res.status(400).json(resetPasswordService);
|
||||||
} else {
|
} else {
|
||||||
await db.models.Session.deleteAllUserSessions({ userId: req.body.userId });
|
await Session.deleteAllUserSessions({ userId: req.body.userId });
|
||||||
return res.status(200).json(resetPasswordService);
|
return res.status(200).json(resetPasswordService);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -70,7 +69,7 @@ const refreshController = async (req, res) => {
|
||||||
const openIdConfig = getOpenIdConfig();
|
const openIdConfig = getOpenIdConfig();
|
||||||
const tokenset = await openIdClient.refreshTokenGrant(openIdConfig, refreshToken);
|
const tokenset = await openIdClient.refreshTokenGrant(openIdConfig, refreshToken);
|
||||||
const claims = tokenset.claims();
|
const claims = tokenset.claims();
|
||||||
const user = await findUser({ email: claims.email });
|
const user = await User.findUser({ email: claims.email });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(401).redirect('/login');
|
return res.status(401).redirect('/login');
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +82,7 @@ const refreshController = async (req, res) => {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
|
const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
|
||||||
const user = await db.models.User.getUserById(payload.id, '-password -__v -totpSecret');
|
const user = await User.getUserById(payload.id, '-password -__v -totpSecret');
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(401).redirect('/login');
|
return res.status(401).redirect('/login');
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +95,7 @@ const refreshController = async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the session with the hashed refresh token
|
// Find the session with the hashed refresh token
|
||||||
const session = await db.models.Session.findSession({
|
const session = await Session.findSession({
|
||||||
userId: userId,
|
userId: userId,
|
||||||
refreshToken: refreshToken,
|
refreshToken: refreshToken,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
const db = require('~/lib/db/connectDb');
|
const { Balance } = require('@librechat/data-schemas');
|
||||||
async function balanceController(req, res) {
|
async function balanceController(req, res) {
|
||||||
const balanceData = await db.models.Balance.findOne(
|
const balanceData = await Balance.findOne(
|
||||||
{ user: req.user.id },
|
{ user: req.user.id },
|
||||||
'-_id tokenCredits autoRefillEnabled refillIntervalValue refillIntervalUnit lastRefill refillAmount',
|
'-_id tokenCredits autoRefillEnabled refillIntervalValue refillIntervalUnit lastRefill refillAmount',
|
||||||
).lean();
|
).lean();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
const {
|
const {
|
||||||
generateTOTPSecret,
|
generateTOTPSecret,
|
||||||
generateBackupCodes,
|
generateBackupCodes,
|
||||||
|
|
@ -5,9 +6,7 @@ const {
|
||||||
verifyBackupCode,
|
verifyBackupCode,
|
||||||
getTOTPSecret,
|
getTOTPSecret,
|
||||||
} = require('~/server/services/twoFactorService');
|
} = require('~/server/services/twoFactorService');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const { encryptV3 } = require('~/server/utils/crypto');
|
const { encryptV3 } = require('~/server/utils/crypto');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, '');
|
const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, '');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -24,7 +23,7 @@ const enable2FA = async (req, res) => {
|
||||||
const encryptedSecret = encryptV3(secret);
|
const encryptedSecret = encryptV3(secret);
|
||||||
|
|
||||||
// Update the user record: store the secret & backup codes and set twoFactorEnabled to false.
|
// Update the user record: store the secret & backup codes and set twoFactorEnabled to false.
|
||||||
const user = await db.models.User.updateUser(userId, {
|
const user = await User.updateUser(userId, {
|
||||||
totpSecret: encryptedSecret,
|
totpSecret: encryptedSecret,
|
||||||
backupCodes: codeObjects,
|
backupCodes: codeObjects,
|
||||||
twoFactorEnabled: false,
|
twoFactorEnabled: false,
|
||||||
|
|
@ -46,7 +45,7 @@ const verify2FA = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
const { token, backupCode } = req.body;
|
const { token, backupCode } = req.body;
|
||||||
const user = await db.models.User.getUserById(userId);
|
const user = await User.getUserById(userId);
|
||||||
|
|
||||||
if (!user || !user.totpSecret) {
|
if (!user || !user.totpSecret) {
|
||||||
return res.status(400).json({ message: '2FA not initiated' });
|
return res.status(400).json({ message: '2FA not initiated' });
|
||||||
|
|
@ -78,7 +77,6 @@ const confirm2FA = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
const { token } = req.body;
|
const { token } = req.body;
|
||||||
const { User } = db.models;
|
|
||||||
const user = await User.getUserById(userId);
|
const user = await User.getUserById(userId);
|
||||||
|
|
||||||
if (!user || !user.totpSecret) {
|
if (!user || !user.totpSecret) {
|
||||||
|
|
@ -103,7 +101,7 @@ const confirm2FA = async (req, res) => {
|
||||||
const disable2FA = async (req, res) => {
|
const disable2FA = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
await db.models.User.updateUser(userId, { totpSecret: null, backupCodes: [], twoFactorEnabled: false });
|
await User.updateUser(userId, { totpSecret: null, backupCodes: [], twoFactorEnabled: false });
|
||||||
return res.status(200).json();
|
return res.status(200).json();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('[disable2FA]', err);
|
logger.error('[disable2FA]', err);
|
||||||
|
|
@ -118,7 +116,7 @@ const regenerateBackupCodes = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
const { plainCodes, codeObjects } = await generateBackupCodes();
|
const { plainCodes, codeObjects } = await generateBackupCodes();
|
||||||
await db.models.User.updateUser(userId, { backupCodes: codeObjects });
|
await User.updateUser(userId, { backupCodes: codeObjects });
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
backupCodes: plainCodes,
|
backupCodes: plainCodes,
|
||||||
backupCodesHash: codeObjects,
|
backupCodesHash: codeObjects,
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,11 @@
|
||||||
const {
|
const {
|
||||||
Tools,
|
Tools,
|
||||||
Constants,
|
|
||||||
FileSources,
|
FileSources,
|
||||||
webSearchKeys,
|
webSearchKeys,
|
||||||
extractWebSearchEnvVars,
|
extractWebSearchEnvVars,
|
||||||
} = require('librechat-data-provider');
|
} = require('librechat-data-provider');
|
||||||
const {
|
const { User, Session, Transaction, Balance, logger } = require('@librechat/data-schemas');
|
||||||
Balance,
|
const { getFiles, deleteFiles, deleteConvos, deletePresets, deleteMessages } = require('~/models');
|
||||||
getFiles,
|
|
||||||
deleteFiles,
|
|
||||||
deleteConvos,
|
|
||||||
deletePresets,
|
|
||||||
deleteMessages,
|
|
||||||
} = require('~/models');
|
|
||||||
const { updateUserPluginAuth, deleteUserPluginAuth } = require('~/server/services/PluginService');
|
const { updateUserPluginAuth, deleteUserPluginAuth } = require('~/server/services/PluginService');
|
||||||
const { updateUserPluginsService, deleteUserKey } = require('~/server/services/UserService');
|
const { updateUserPluginsService, deleteUserKey } = require('~/server/services/UserService');
|
||||||
const { verifyEmail, resendVerificationEmail } = require('~/server/services/AuthService');
|
const { verifyEmail, resendVerificationEmail } = require('~/server/services/AuthService');
|
||||||
|
|
@ -20,9 +13,6 @@ const { needsRefresh, getNewS3URL } = require('~/server/services/Files/S3/crud')
|
||||||
const { processDeleteRequest } = require('~/server/services/Files/process');
|
const { processDeleteRequest } = require('~/server/services/Files/process');
|
||||||
const { deleteAllSharedLinks } = require('~/models/Share');
|
const { deleteAllSharedLinks } = require('~/models/Share');
|
||||||
const { deleteToolCalls } = require('~/models/ToolCall');
|
const { deleteToolCalls } = require('~/models/ToolCall');
|
||||||
const { Transaction } = require('~/models/Transaction');
|
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const getUserController = async (req, res) => {
|
const getUserController = async (req, res) => {
|
||||||
/** @type {MongoUser} */
|
/** @type {MongoUser} */
|
||||||
|
|
@ -36,7 +26,7 @@ const getUserController = async (req, res) => {
|
||||||
const originalAvatar = userData.avatar;
|
const originalAvatar = userData.avatar;
|
||||||
try {
|
try {
|
||||||
userData.avatar = await getNewS3URL(userData.avatar);
|
userData.avatar = await getNewS3URL(userData.avatar);
|
||||||
await db.models.User.updateUser(userData.id, { avatar: userData.avatar });
|
await User.updateUser(userData.id, { avatar: userData.avatar });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
userData.avatar = originalAvatar;
|
userData.avatar = originalAvatar;
|
||||||
logger.error('Error getting new S3 URL for avatar:', error);
|
logger.error('Error getting new S3 URL for avatar:', error);
|
||||||
|
|
@ -47,7 +37,7 @@ const getUserController = async (req, res) => {
|
||||||
|
|
||||||
const getTermsStatusController = async (req, res) => {
|
const getTermsStatusController = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const user = await db.models.User.findById(req.user.id);
|
const user = await User.findById(req.user.id);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(404).json({ message: 'User not found' });
|
return res.status(404).json({ message: 'User not found' });
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +50,7 @@ const getTermsStatusController = async (req, res) => {
|
||||||
|
|
||||||
const acceptTermsController = async (req, res) => {
|
const acceptTermsController = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const user = await db.models.User.findByIdAndUpdate(req.user.id, { termsAccepted: true }, { new: true });
|
const user = await User.findByIdAndUpdate(req.user.id, { termsAccepted: true }, { new: true });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(404).json({ message: 'User not found' });
|
return res.status(404).json({ message: 'User not found' });
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +147,7 @@ const deleteUserController = async (req, res) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await deleteMessages({ user: user.id }); // delete user messages
|
await deleteMessages({ user: user.id }); // delete user messages
|
||||||
await db.models.Session.deleteAllUserSessions({ userId: user.id }); // delete user sessions
|
await Session.deleteAllUserSessions({ userId: user.id }); // delete user sessions
|
||||||
await Transaction.deleteMany({ user: user.id }); // delete user transactions
|
await Transaction.deleteMany({ user: user.id }); // delete user transactions
|
||||||
await deleteUserKey({ userId: user.id, all: true }); // delete user keys
|
await deleteUserKey({ userId: user.id, all: true }); // delete user keys
|
||||||
await Balance.deleteMany({ user: user._id }); // delete user balances
|
await Balance.deleteMany({ user: user._id }); // delete user balances
|
||||||
|
|
@ -165,7 +155,7 @@ const deleteUserController = async (req, res) => {
|
||||||
/* TODO: Delete Assistant Threads */
|
/* TODO: Delete Assistant Threads */
|
||||||
await deleteConvos(user.id); // delete user convos
|
await deleteConvos(user.id); // delete user convos
|
||||||
await deleteUserPluginAuth(user.id, null, true); // delete user plugin auth
|
await deleteUserPluginAuth(user.id, null, true); // delete user plugin auth
|
||||||
await db.models.User.deleteUserById(user.id); // delete user
|
await User.deleteUserById(user.id); // delete user
|
||||||
await deleteAllSharedLinks(user.id); // delete user shared links
|
await deleteAllSharedLinks(user.id); // delete user shared links
|
||||||
await deleteUserFiles(req); // delete user files
|
await deleteUserFiles(req); // delete user files
|
||||||
await deleteFiles(null, user.id); // delete database files in case of orphaned files from previous steps
|
await deleteFiles(null, user.id); // delete database files in case of orphaned files from previous steps
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ const {
|
||||||
getTOTPSecret,
|
getTOTPSecret,
|
||||||
} = require('~/server/services/twoFactorService');
|
} = require('~/server/services/twoFactorService');
|
||||||
const { setAuthTokens } = require('~/server/services/AuthService');
|
const { setAuthTokens } = require('~/server/services/AuthService');
|
||||||
const { logger } = require('~/config');
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies the 2FA code during login using a temporary token.
|
* Verifies the 2FA code during login using a temporary token.
|
||||||
|
|
@ -25,7 +24,7 @@ const verify2FAWithTempToken = async (req, res) => {
|
||||||
return res.status(401).json({ message: 'Invalid or expired temporary token' });
|
return res.status(401).json({ message: 'Invalid or expired temporary token' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await db.models.User.getUserById(payload.userId);
|
const user = await User.getUserById(payload.userId);
|
||||||
if (!user || !user.twoFactorEnabled) {
|
if (!user || !user.twoFactorEnabled) {
|
||||||
return res.status(400).json({ message: '2FA is not enabled for this user' });
|
return res.status(400).json({ message: '2FA is not enabled for this user' });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@ const { isEnabled, removePorts } = require('~/server/utils');
|
||||||
const keyvMongo = require('~/cache/keyvMongo');
|
const keyvMongo = require('~/cache/keyvMongo');
|
||||||
const denyRequest = require('./denyRequest');
|
const denyRequest = require('./denyRequest');
|
||||||
const { getLogStores } = require('~/cache');
|
const { getLogStores } = require('~/cache');
|
||||||
const { logger } = require('~/config');
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
|
|
||||||
const banCache = new Keyv({ store: keyvMongo, namespace: ViolationTypes.BAN, ttl: 0 });
|
const banCache = new Keyv({ store: keyvMongo, namespace: ViolationTypes.BAN, ttl: 0 });
|
||||||
const message = 'Your account has been temporarily banned due to violations of our service.';
|
const message = 'Your account has been temporarily banned due to violations of our service.';
|
||||||
|
|
@ -58,7 +56,7 @@ const checkBan = async (req, res, next = () => {}) => {
|
||||||
let userId = req.user?.id ?? req.user?._id ?? null;
|
let userId = req.user?.id ?? req.user?._id ?? null;
|
||||||
|
|
||||||
if (!userId && req?.body?.email) {
|
if (!userId && req?.body?.email) {
|
||||||
const user = await db.models.User.findUser({ email: req.body.email }, '_id');
|
const user = await User.findUser({ email: req.body.email }, '_id');
|
||||||
userId = user?._id ? user._id.toString() : userId;
|
userId = user?._id ? user._id.toString() : userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
const { deleteTokens } = require('@librechat/data-schemas');
|
||||||
const { getInvite } = require('~/models/inviteUser');
|
const { getInvite } = require('~/models/inviteUser');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
async function checkInviteUser(req, res, next) {
|
async function checkInviteUser(req, res, next) {
|
||||||
const token = req.body.token;
|
const token = req.body.token;
|
||||||
|
|
@ -16,7 +16,7 @@ async function checkInviteUser(req, res, next) {
|
||||||
return res.status(400).json({ message: 'Invalid invite token' });
|
return res.status(400).json({ message: 'Invalid invite token' });
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.models.Token.deleteTokens({ token: invite.token });
|
await deleteTokens({ token: invite.token });
|
||||||
req.invite = invite;
|
req.invite = invite;
|
||||||
next();
|
next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
|
const { Balance, logger } = require('@librechat/data-schemas');
|
||||||
const { getBalanceConfig } = require('~/server/services/Config');
|
const { getBalanceConfig } = require('~/server/services/Config');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware to synchronize user balance settings with current balance configuration.
|
* Middleware to synchronize user balance settings with current balance configuration.
|
||||||
|
|
@ -20,14 +19,14 @@ const setBalanceConfig = async (req, res, next) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const userId = req.user._id;
|
const userId = req.user._id;
|
||||||
const userBalanceRecord = await db.models.Balance.findOne({ user: userId }).lean();
|
const userBalanceRecord = await Balance.findOne({ user: userId }).lean();
|
||||||
const updateFields = buildUpdateFields(balanceConfig, userBalanceRecord);
|
const updateFields = buildUpdateFields(balanceConfig, userBalanceRecord);
|
||||||
|
|
||||||
if (Object.keys(updateFields).length === 0) {
|
if (Object.keys(updateFields).length === 0) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.models.Balance.findOneAndUpdate(
|
await Balance.findOneAndUpdate(
|
||||||
{ user: userId },
|
{ user: userId },
|
||||||
{ $set: updateFields },
|
{ $set: updateFields },
|
||||||
{ upsert: true, new: true },
|
{ upsert: true, new: true },
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { ContentTypes } = require('librechat-data-provider');
|
const { ContentTypes } = require('librechat-data-provider');
|
||||||
|
const { Message, logger } = require('@librechat/data-schemas');
|
||||||
const {
|
const {
|
||||||
saveConvo,
|
saveConvo,
|
||||||
saveMessage,
|
saveMessage,
|
||||||
|
|
@ -13,8 +14,6 @@ const { requireJwtAuth, validateMessageReq } = require('~/server/middleware');
|
||||||
const { cleanUpPrimaryKeyValue } = require('~/lib/utils/misc');
|
const { cleanUpPrimaryKeyValue } = require('~/lib/utils/misc');
|
||||||
const { getConvosQueried } = require('~/models/Conversation');
|
const { getConvosQueried } = require('~/models/Conversation');
|
||||||
const { countTokens } = require('~/server/utils');
|
const { countTokens } = require('~/server/utils');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
router.use(requireJwtAuth);
|
router.use(requireJwtAuth);
|
||||||
|
|
@ -40,7 +39,7 @@ router.get('/', async (req, res) => {
|
||||||
const sortOrder = sortDirection === 'asc' ? 1 : -1;
|
const sortOrder = sortDirection === 'asc' ? 1 : -1;
|
||||||
|
|
||||||
if (conversationId && messageId) {
|
if (conversationId && messageId) {
|
||||||
const message = await db.models.Message.findOne({
|
const message = await Message.findOne({
|
||||||
conversationId,
|
conversationId,
|
||||||
messageId,
|
messageId,
|
||||||
user: user,
|
user: user,
|
||||||
|
|
@ -51,14 +50,14 @@ router.get('/', async (req, res) => {
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
filter[sortField] = sortOrder === 1 ? { $gt: cursor } : { $lt: cursor };
|
filter[sortField] = sortOrder === 1 ? { $gt: cursor } : { $lt: cursor };
|
||||||
}
|
}
|
||||||
const messages = await db.models.Message.find(filter)
|
const messages = await Message.find(filter)
|
||||||
.sort({ [sortField]: sortOrder })
|
.sort({ [sortField]: sortOrder })
|
||||||
.limit(pageSize + 1)
|
.limit(pageSize + 1)
|
||||||
.lean();
|
.lean();
|
||||||
const nextCursor = messages.length > pageSize ? messages.pop()[sortField] : null;
|
const nextCursor = messages.length > pageSize ? messages.pop()[sortField] : null;
|
||||||
response = { messages, nextCursor };
|
response = { messages, nextCursor };
|
||||||
} else if (search) {
|
} else if (search) {
|
||||||
const searchResults = await db.models.Message.meiliSearch(search, undefined, true);
|
const searchResults = await Message.meiliSearch(search, undefined, true);
|
||||||
|
|
||||||
const messages = searchResults.hits || [];
|
const messages = searchResults.hits || [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const { nanoid } = require('nanoid');
|
const { nanoid } = require('nanoid');
|
||||||
const { tool } = require('@langchain/core/tools');
|
const { tool } = require('@langchain/core/tools');
|
||||||
|
const { findToken } = require('@librechat/data-schemas');
|
||||||
const { GraphEvents, sleep } = require('@librechat/agents');
|
const { GraphEvents, sleep } = require('@librechat/agents');
|
||||||
const {
|
const {
|
||||||
Time,
|
Time,
|
||||||
|
|
@ -231,10 +232,9 @@ async function createActionTool({
|
||||||
};
|
};
|
||||||
|
|
||||||
const tokenPromises = [];
|
const tokenPromises = [];
|
||||||
const { Token } = db.models;
|
tokenPromises.push(findToken({ userId, type: 'oauth', identifier }));
|
||||||
tokenPromises.push(Token.findToken({ userId, type: 'oauth', identifier }));
|
|
||||||
tokenPromises.push(
|
tokenPromises.push(
|
||||||
Token.findToken({
|
findToken({
|
||||||
userId,
|
userId,
|
||||||
type: 'oauth_refresh',
|
type: 'oauth_refresh',
|
||||||
identifier: `${identifier}:refresh`,
|
identifier: `${identifier}:refresh`,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
|
const { updateUser, logger } = require('@librechat/data-schemas');
|
||||||
const { resizeImageBuffer } = require('../images/resize');
|
const { resizeImageBuffer } = require('../images/resize');
|
||||||
const { updateFile } = require('~/models/File');
|
const { updateFile } = require('~/models/File');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const { saveBufferToAzure } = require('./crud');
|
const { saveBufferToAzure } = require('./crud');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
/**
|
/**
|
||||||
* Uploads an image file to Azure Blob Storage.
|
* Uploads an image file to Azure Blob Storage.
|
||||||
* It resizes and converts the image similar to your Firebase implementation.
|
* It resizes and converts the image similar to your Firebase implementation.
|
||||||
|
|
@ -107,7 +107,7 @@ async function processAzureAvatar({ buffer, userId, manual, basePath = 'images',
|
||||||
const isManual = manual === 'true';
|
const isManual = manual === 'true';
|
||||||
const url = `${downloadURL}?manual=${isManual}`;
|
const url = `${downloadURL}?manual=${isManual}`;
|
||||||
if (isManual) {
|
if (isManual) {
|
||||||
await db.models?.User.updateUser(userId, { avatar: url });
|
await updateUser(userId, { avatar: url });
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ const sharp = require('sharp');
|
||||||
const { resizeImageBuffer } = require('../images/resize');
|
const { resizeImageBuffer } = require('../images/resize');
|
||||||
const { saveBufferToFirebase } = require('./crud');
|
const { saveBufferToFirebase } = require('./crud');
|
||||||
const { updateFile } = require('~/models/File');
|
const { updateFile } = require('~/models/File');
|
||||||
const { logger } = require('~/config');
|
const { logger, updateUser } = require('@librechat/data-schemas');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an image file to the target format. The function first resizes the image based on the specified
|
* Converts an image file to the target format. The function first resizes the image based on the specified
|
||||||
|
|
@ -99,7 +98,7 @@ async function processFirebaseAvatar({ buffer, userId, manual }) {
|
||||||
const url = `${downloadURL}?manual=${isManual}`;
|
const url = `${downloadURL}?manual=${isManual}`;
|
||||||
|
|
||||||
if (isManual) {
|
if (isManual) {
|
||||||
await db.models.User.updateUser(userId, { avatar: url });
|
await updateUser(userId, { avatar: url });
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
|
const { updateUser } = require('@librechat/data-schemas');
|
||||||
const { resizeImageBuffer } = require('../images/resize');
|
const { resizeImageBuffer } = require('../images/resize');
|
||||||
const { updateFile } = require('~/models/File');
|
const { updateFile } = require('~/models/File');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an image file to the target format. The function first resizes the image based on the specified
|
* Converts an image file to the target format. The function first resizes the image based on the specified
|
||||||
|
|
@ -141,7 +141,7 @@ async function processLocalAvatar({ buffer, userId, manual }) {
|
||||||
let url = `${urlRoute}?manual=${isManual}`;
|
let url = `${urlRoute}?manual=${isManual}`;
|
||||||
|
|
||||||
if (isManual) {
|
if (isManual) {
|
||||||
await db.models?.User.updateUser(userId, { avatar: url });
|
await updateUser(userId, { avatar: url });
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
|
const { logger, updateUser } = require('@librechat/data-schemas');
|
||||||
const { resizeImageBuffer } = require('../images/resize');
|
const { resizeImageBuffer } = require('../images/resize');
|
||||||
const { saveBufferToS3 } = require('./crud');
|
|
||||||
const { updateFile } = require('~/models/File');
|
const { updateFile } = require('~/models/File');
|
||||||
const { logger } = require('~/config');
|
const { saveBufferToS3 } = require('./crud');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const defaultBasePath = 'images';
|
const defaultBasePath = 'images';
|
||||||
|
|
||||||
|
|
@ -102,7 +101,7 @@ async function processS3Avatar({ buffer, userId, manual, basePath = defaultBaseP
|
||||||
try {
|
try {
|
||||||
const downloadURL = await saveBufferToS3({ userId, buffer, fileName: 'avatar.png', basePath });
|
const downloadURL = await saveBufferToS3({ userId, buffer, fileName: 'avatar.png', basePath });
|
||||||
if (manual === 'true') {
|
if (manual === 'true') {
|
||||||
await db.models?.User.updateUser(userId, { avatar: downloadURL });
|
await updateUser(userId, { avatar: downloadURL });
|
||||||
}
|
}
|
||||||
return downloadURL;
|
return downloadURL;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const { ErrorTypes } = require('librechat-data-provider');
|
const { ErrorTypes } = require('librechat-data-provider');
|
||||||
const { encrypt, decrypt } = require('~/server/utils');
|
const { Key, logger, updateUser } = require('@librechat/data-schemas');
|
||||||
const { logger } = require('~/config');
|
const { encrypt, decrypt } = require('~/server/utils/crypto');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
/**
|
/**
|
||||||
* Updates the plugins for a user based on the action specified (install/uninstall).
|
* Updates the plugins for a user based on the action specified (install/uninstall).
|
||||||
* @async
|
* @async
|
||||||
|
|
@ -16,11 +16,10 @@ const db = require('~/lib/db/connectDb');
|
||||||
const updateUserPluginsService = async (user, pluginKey, action) => {
|
const updateUserPluginsService = async (user, pluginKey, action) => {
|
||||||
try {
|
try {
|
||||||
const userPlugins = user.plugins || [];
|
const userPlugins = user.plugins || [];
|
||||||
const { User } = db.models;
|
|
||||||
if (action === 'install') {
|
if (action === 'install') {
|
||||||
return await User.updateUser(user._id, { plugins: [...userPlugins, pluginKey] });
|
return await updateUser(user._id, { plugins: [...userPlugins, pluginKey] });
|
||||||
} else if (action === 'uninstall') {
|
} else if (action === 'uninstall') {
|
||||||
return await User.updateUser(user._id, {
|
return await updateUser(user._id, {
|
||||||
plugins: userPlugins.filter((plugin) => plugin !== pluginKey),
|
plugins: userPlugins.filter((plugin) => plugin !== pluginKey),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +41,7 @@ const updateUserPluginsService = async (user, pluginKey, action) => {
|
||||||
* an error indicating that there is no user key available.
|
* an error indicating that there is no user key available.
|
||||||
*/
|
*/
|
||||||
const getUserKey = async ({ userId, name }) => {
|
const getUserKey = async ({ userId, name }) => {
|
||||||
const keyValue = await db.models.Key.findOne({ userId, name }).lean();
|
const keyValue = await Key.findOne({ userId, name }).lean();
|
||||||
if (!keyValue) {
|
if (!keyValue) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
|
@ -89,7 +88,7 @@ const getUserKeyValues = async ({ userId, name }) => {
|
||||||
* returns its expiry date. If the key is not found, it returns null for the expiry date.
|
* returns its expiry date. If the key is not found, it returns null for the expiry date.
|
||||||
*/
|
*/
|
||||||
const getUserKeyExpiry = async ({ userId, name }) => {
|
const getUserKeyExpiry = async ({ userId, name }) => {
|
||||||
const keyValue = await db.models.Key.findOne({ userId, name }).lean();
|
const keyValue = await Key.findOne({ userId, name }).lean();
|
||||||
if (!keyValue) {
|
if (!keyValue) {
|
||||||
return { expiresAt: null };
|
return { expiresAt: null };
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +122,7 @@ const updateUserKey = async ({ userId, name, value, expiresAt = null }) => {
|
||||||
// make sure to remove if already present
|
// make sure to remove if already present
|
||||||
updateQuery.$unset = { expiresAt };
|
updateQuery.$unset = { expiresAt };
|
||||||
}
|
}
|
||||||
return await db.models.Key.findOneAndUpdate({ userId, name }, updateQuery, {
|
return await Key.findOneAndUpdate({ userId, name }, updateQuery, {
|
||||||
upsert: true,
|
upsert: true,
|
||||||
new: true,
|
new: true,
|
||||||
}).lean();
|
}).lean();
|
||||||
|
|
@ -143,10 +142,10 @@ const updateUserKey = async ({ userId, name, value, expiresAt = null }) => {
|
||||||
*/
|
*/
|
||||||
const deleteUserKey = async ({ userId, name, all = false }) => {
|
const deleteUserKey = async ({ userId, name, all = false }) => {
|
||||||
if (all) {
|
if (all) {
|
||||||
return await db.models.Key.deleteMany({ userId });
|
return await Key.deleteMany({ userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.models.Key.findOneAndDelete({ userId, name }).lean();
|
await Key.findOneAndDelete({ userId, name }).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
const { webcrypto } = require('node:crypto');
|
const { webcrypto } = require('node:crypto');
|
||||||
const { decryptV3, decryptV2 } = require('../utils/crypto');
|
const { User } = require('@librechat/data-schemas');
|
||||||
const { hashBackupCode } = require('~/server/utils/crypto');
|
const { hashBackupCode, decryptV3, decryptV2 } = require('~/server/utils/crypto');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
// Base32 alphabet for TOTP secret encoding.
|
// Base32 alphabet for TOTP secret encoding.
|
||||||
const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
||||||
|
|
@ -173,7 +172,7 @@ const verifyBackupCode = async ({ user, backupCode }) => {
|
||||||
: codeObj,
|
: codeObj,
|
||||||
);
|
);
|
||||||
// Update the user record with the marked backup code.
|
// Update the user record with the marked backup code.
|
||||||
await db.models.User.updateUser(user._id, { backupCodes: updatedBackupCodes });
|
await User.updateUser(user._id, { backupCodes: updatedBackupCodes });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,9 @@ const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const { Strategy: AppleStrategy } = require('passport-apple');
|
const { Strategy: AppleStrategy } = require('passport-apple');
|
||||||
const socialLogin = require('./socialLogin');
|
const socialLogin = require('./socialLogin');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const { createSocialUser, handleExistingUser } = require('./process');
|
const { createSocialUser, handleExistingUser } = require('./process');
|
||||||
const { isEnabled } = require('~/server/utils');
|
const { isEnabled } = require('~/server/utils');
|
||||||
const db = require('~/lib/db/connectDb');
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
|
|
||||||
// Mocking external dependencies
|
// Mocking external dependencies
|
||||||
jest.mock('jsonwebtoken');
|
jest.mock('jsonwebtoken');
|
||||||
|
|
@ -29,14 +28,11 @@ describe('Apple Login Strategy', () => {
|
||||||
let appleStrategyInstance;
|
let appleStrategyInstance;
|
||||||
const OLD_ENV = process.env;
|
const OLD_ENV = process.env;
|
||||||
let getProfileDetails;
|
let getProfileDetails;
|
||||||
let User;
|
|
||||||
// Start and stop in-memory MongoDB
|
// Start and stop in-memory MongoDB
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mongoServer = await MongoMemoryServer.create();
|
mongoServer = await MongoMemoryServer.create();
|
||||||
const mongoUri = mongoServer.getUri();
|
const mongoUri = mongoServer.getUri();
|
||||||
await db.connectDb(mongoUri);
|
await mongoose.connect(mongoUri);
|
||||||
|
|
||||||
User = db.models.User;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
const { SystemRoles } = require('librechat-data-provider');
|
const { SystemRoles } = require('librechat-data-provider');
|
||||||
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
|
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
// JWT strategy
|
// JWT strategy
|
||||||
const jwtLogin = () =>
|
const jwtLogin = () =>
|
||||||
|
|
@ -12,7 +11,6 @@ const jwtLogin = () =>
|
||||||
},
|
},
|
||||||
async (payload, done) => {
|
async (payload, done) => {
|
||||||
try {
|
try {
|
||||||
const {User} = db.models;
|
|
||||||
const user = await User.getUserById(payload?.id, '-password -__v -totpSecret');
|
const user = await User.getUserById(payload?.id, '-password -__v -totpSecret');
|
||||||
if (user) {
|
if (user) {
|
||||||
user.id = user._id.toString();
|
user.id = user._id.toString();
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const LdapStrategy = require('passport-ldapauth');
|
const LdapStrategy = require('passport-ldapauth');
|
||||||
const { SystemRoles } = require('librechat-data-provider');
|
const { SystemRoles } = require('librechat-data-provider');
|
||||||
|
const { User, createUser, findUser, updateUser } = require('@librechat/data-schemas');
|
||||||
|
const { getBalanceConfig } = require('~/server/services/Config');
|
||||||
const { isEnabled } = require('~/server/utils');
|
const { isEnabled } = require('~/server/utils');
|
||||||
const logger = require('~/utils/logger');
|
const logger = require('~/utils/logger');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const { getBalanceConfig } = require('~/server/services/Config');
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
LDAP_URL,
|
LDAP_URL,
|
||||||
|
|
@ -81,7 +81,6 @@ const ldapOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
|
const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
|
||||||
const { User } = db.models;
|
|
||||||
if (!userinfo) {
|
if (!userinfo) {
|
||||||
return done(null, false, { message: 'Invalid credentials' });
|
return done(null, false, { message: 'Invalid credentials' });
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +89,7 @@ const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
|
||||||
const ldapId =
|
const ldapId =
|
||||||
(LDAP_ID && userinfo[LDAP_ID]) || userinfo.uid || userinfo.sAMAccountName || userinfo.mail;
|
(LDAP_ID && userinfo[LDAP_ID]) || userinfo.uid || userinfo.sAMAccountName || userinfo.mail;
|
||||||
|
|
||||||
let user = await User.findUser({ ldapId });
|
let user = await findUser({ ldapId });
|
||||||
|
|
||||||
const fullNameAttributes = LDAP_FULL_NAME && LDAP_FULL_NAME.split(',');
|
const fullNameAttributes = LDAP_FULL_NAME && LDAP_FULL_NAME.split(',');
|
||||||
const fullName =
|
const fullName =
|
||||||
|
|
@ -126,8 +125,7 @@ const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
|
||||||
role: isFirstRegisteredUser ? SystemRoles.ADMIN : SystemRoles.USER,
|
role: isFirstRegisteredUser ? SystemRoles.ADMIN : SystemRoles.USER,
|
||||||
};
|
};
|
||||||
const balanceConfig = await getBalanceConfig();
|
const balanceConfig = await getBalanceConfig();
|
||||||
|
const userId = await createUser(user, balanceConfig);
|
||||||
const userId = await User.createUser(user, balanceConfig);
|
|
||||||
user._id = userId;
|
user._id = userId;
|
||||||
} else {
|
} else {
|
||||||
// Users registered in LDAP are assumed to have their user information managed in LDAP,
|
// Users registered in LDAP are assumed to have their user information managed in LDAP,
|
||||||
|
|
@ -139,7 +137,7 @@ const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
|
||||||
user.name = fullName;
|
user.name = fullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
user = await User.updateUser(user._id, user);
|
user = await updateUser(user._id, user);
|
||||||
done(null, user);
|
done(null, user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('[ldapStrategy]', err);
|
logger.error('[ldapStrategy]', err);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
const { errorsToString } = require('librechat-data-provider');
|
const { errorsToString } = require('librechat-data-provider');
|
||||||
const { Strategy: PassportLocalStrategy } = require('passport-local');
|
const { Strategy: PassportLocalStrategy } = require('passport-local');
|
||||||
const { comparePassword } = require('~/models');
|
|
||||||
const { isEnabled, checkEmailConfig } = require('~/server/utils');
|
const { isEnabled, checkEmailConfig } = require('~/server/utils');
|
||||||
|
const { comparePassword } = require('~/models');
|
||||||
const { loginSchema } = require('./validators');
|
const { loginSchema } = require('./validators');
|
||||||
const logger = require('~/utils/logger');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
// Unix timestamp for 2024-06-07 15:20:18 Eastern Time
|
// Unix timestamp for 2024-06-07 15:20:18 Eastern Time
|
||||||
const verificationEnabledTimestamp = 1717788018;
|
const verificationEnabledTimestamp = 1717788018;
|
||||||
|
|
@ -15,7 +14,6 @@ async function validateLoginRequest(req) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function passportLogin(req, email, password, done) {
|
async function passportLogin(req, email, password, done) {
|
||||||
const {User} = db.models;
|
|
||||||
try {
|
try {
|
||||||
const validationError = await validateLoginRequest(req);
|
const validationError = await validateLoginRequest(req);
|
||||||
if (validationError) {
|
if (validationError) {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
const { CacheKeys } = require('librechat-data-provider');
|
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
const passport = require('passport');
|
const passport = require('passport');
|
||||||
const jwtDecode = require('jsonwebtoken/decode');
|
|
||||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
|
||||||
const client = require('openid-client');
|
const client = require('openid-client');
|
||||||
|
const jwtDecode = require('jsonwebtoken/decode');
|
||||||
|
const { CacheKeys } = require('librechat-data-provider');
|
||||||
|
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||||
|
const { User, logger } = require('@librechat/data-schemas');
|
||||||
const { Strategy: OpenIDStrategy } = require('openid-client/passport');
|
const { Strategy: OpenIDStrategy } = require('openid-client/passport');
|
||||||
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
|
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
|
||||||
const { isEnabled } = require('~/server/utils');
|
|
||||||
const { logger } = require('~/config');
|
|
||||||
const getLogStores = require('~/cache/getLogStores');
|
const getLogStores = require('~/cache/getLogStores');
|
||||||
|
const { isEnabled } = require('~/server/utils');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('openid-client').ClientMetadata} ClientMetadata
|
* @typedef {import('openid-client').ClientMetadata} ClientMetadata
|
||||||
|
|
@ -212,7 +212,6 @@ function convertToUsername(input, defaultValue = '') {
|
||||||
* @throws {Error} If an error occurs during the setup process.
|
* @throws {Error} If an error occurs during the setup process.
|
||||||
*/
|
*/
|
||||||
async function setupOpenId() {
|
async function setupOpenId() {
|
||||||
const { User } = db.models;
|
|
||||||
try {
|
try {
|
||||||
/** @type {ClientMetadata} */
|
/** @type {ClientMetadata} */
|
||||||
const clientMetadata = {
|
const clientMetadata = {
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,6 @@ const mockFindUser = jest.fn();
|
||||||
const mockUpdateUser = jest.fn();
|
const mockUpdateUser = jest.fn();
|
||||||
let User;
|
let User;
|
||||||
|
|
||||||
jest.mock('@librechat/data-schemas', () => {
|
|
||||||
return {
|
|
||||||
registerModels: jest.fn().mockReturnValue({
|
|
||||||
User: {
|
|
||||||
createUser: mockCreateUser,
|
|
||||||
findUser: mockFindUser,
|
|
||||||
updateUser: mockUpdateUser,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockModels = {
|
const mockModels = {
|
||||||
User: {
|
User: {
|
||||||
createUser: mockCreateUser,
|
createUser: mockCreateUser,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const { FileSources } = require('librechat-data-provider');
|
const { FileSources } = require('librechat-data-provider');
|
||||||
|
const { updateUser, createUser, getUserById } = require('@librechat/data-schemas');
|
||||||
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
|
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
|
||||||
const { resizeAvatar } = require('~/server/services/Files/images/avatar');
|
const { resizeAvatar } = require('~/server/services/Files/images/avatar');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const { getBalanceConfig } = require('~/server/services/Config');
|
const { getBalanceConfig } = require('~/server/services/Config');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,7 +35,7 @@ const handleExistingUser = async (oldUser, avatarUrl) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updatedAvatar) {
|
if (updatedAvatar) {
|
||||||
await db.models.User.updateUser(oldUser._id, { avatar: updatedAvatar });
|
await updateUser(oldUser._id, { avatar: updatedAvatar });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ const createSocialUser = async ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const balanceConfig = await getBalanceConfig();
|
const balanceConfig = await getBalanceConfig();
|
||||||
const newUserId = await db.models.User.createUser(update, balanceConfig);
|
const newUserId = await createUser(update, balanceConfig);
|
||||||
const fileStrategy = process.env.CDN_PROVIDER;
|
const fileStrategy = process.env.CDN_PROVIDER;
|
||||||
const isLocal = fileStrategy === FileSources.local;
|
const isLocal = fileStrategy === FileSources.local;
|
||||||
|
|
||||||
|
|
@ -91,10 +91,10 @@ const createSocialUser = async ({
|
||||||
});
|
});
|
||||||
const { processAvatar } = getStrategyFunctions(fileStrategy);
|
const { processAvatar } = getStrategyFunctions(fileStrategy);
|
||||||
const avatar = await processAvatar({ buffer: resizedBuffer, userId: newUserId });
|
const avatar = await processAvatar({ buffer: resizedBuffer, userId: newUserId });
|
||||||
await User.updateUser(newUserId, { avatar });
|
await updateUser(newUserId, { avatar });
|
||||||
}
|
}
|
||||||
|
|
||||||
return await User.getUserById(newUserId);
|
return await getUserById(newUserId);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
const { findUser, logger } = require('@librechat/data-schemas');
|
||||||
const { createSocialUser, handleExistingUser } = require('./process');
|
const { createSocialUser, handleExistingUser } = require('./process');
|
||||||
const { isEnabled } = require('~/server/utils');
|
const { isEnabled } = require('~/server/utils');
|
||||||
const { logger } = require('~/config');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const socialLogin =
|
const socialLogin =
|
||||||
(provider, getProfileDetails) => async (accessToken, refreshToken, idToken, profile, cb) => {
|
(provider, getProfileDetails) => async (accessToken, refreshToken, idToken, profile, cb) => {
|
||||||
|
|
@ -11,7 +10,7 @@ const socialLogin =
|
||||||
profile,
|
profile,
|
||||||
});
|
});
|
||||||
|
|
||||||
const oldUser = await db.models.User.findUser({ email: email.trim() });
|
const oldUser = await findUser({ email: email.trim() });
|
||||||
const ALLOW_SOCIAL_REGISTRATION = isEnabled(process.env.ALLOW_SOCIAL_REGISTRATION);
|
const ALLOW_SOCIAL_REGISTRATION = isEnabled(process.env.ALLOW_SOCIAL_REGISTRATION);
|
||||||
|
|
||||||
if (oldUser) {
|
if (oldUser) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
const { isEnabled } = require('~/server/utils/handleText');
|
const { isEnabled } = require('~/server/utils/handleText');
|
||||||
const { createTransaction } = require('~/models/Transaction');
|
const { createTransaction } = require('~/models/Transaction');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -65,7 +65,7 @@ const connect = require('./connect');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the user
|
// Validate the user
|
||||||
const user = await db.models.User.findOne({ email }).lean();
|
const user = await User.findOne({ email }).lean();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
console.red('Error: No user with that email was found!');
|
console.red('Error: No user with that email was found!');
|
||||||
silentExit(1);
|
silentExit(1);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
const banViolation = require('~/cache/banViolation');
|
const banViolation = require('~/cache/banViolation');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -44,7 +44,7 @@ const connect = require('./connect');
|
||||||
silentExit(1);
|
silentExit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await db.models.User.findOne({ email }).lean();
|
const user = await User.findOne({ email }).lean();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
console.red('Error: No user with that email was found!');
|
console.red('Error: No user with that email was found!');
|
||||||
silentExit(1);
|
silentExit(1);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { registerUser } = require('~/server/services/AuthService');
|
const { registerUser } = require('~/server/services/AuthService');
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -92,7 +92,7 @@ or the user will need to attempt logging in to have a verification link sent to
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const userExists = await db.models.User.findOne({ $or: [{ email }, { username }] });
|
const userExists = await User.findOne({ $or: [{ email }, { username }] });
|
||||||
if (userExists) {
|
if (userExists) {
|
||||||
console.red('Error: A user with that email or username already exists!');
|
console.red('Error: A user with that email or username already exists!');
|
||||||
silentExit(1);
|
silentExit(1);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -20,10 +20,10 @@ const connect = require('./connect');
|
||||||
} else {
|
} else {
|
||||||
email = await askQuestion('Email:');
|
email = await askQuestion('Email:');
|
||||||
}
|
}
|
||||||
let user = await db.models.User.findOne({ email: email });
|
let user = await User.findOne({ email: email });
|
||||||
if (user !== null) {
|
if (user !== null) {
|
||||||
if ((await askQuestion(`Delete user ${user}?`)) === 'y') {
|
if ((await askQuestion(`Delete user ${user}?`)) === 'y') {
|
||||||
user = await db.models.User.findOneAndDelete({ _id: user._id });
|
user = await User.findOneAndDelete({ _id: user._id });
|
||||||
if (user !== null) {
|
if (user !== null) {
|
||||||
console.yellow(`Deleted user ${user}`);
|
console.yellow(`Deleted user ${user}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { sendEmail, checkEmailConfig } = require('~/server/utils');
|
const { sendEmail, checkEmailConfig } = require('~/server/utils');
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
const { createInvite } = require('~/models/inviteUser');
|
const { createInvite } = require('~/models/inviteUser');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -40,7 +40,7 @@ const connect = require('./connect');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user already exists
|
// Check if the user already exists
|
||||||
const userExists = await db.models.User.findOne({ email });
|
const userExists = await User.findOne({ email });
|
||||||
if (userExists) {
|
if (userExists) {
|
||||||
console.red('Error: A user with that email already exists!');
|
console.red('Error: A user with that email already exists!');
|
||||||
silentExit(1);
|
silentExit(1);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User, Balance } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { silentExit } = require('./helpers');
|
const { silentExit } = require('./helpers');
|
||||||
const Balance = require('~/models/Balance');
|
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -15,7 +14,7 @@ const connect = require('./connect');
|
||||||
console.purple('Show the balance of all users');
|
console.purple('Show the balance of all users');
|
||||||
console.purple('-----------------------------');
|
console.purple('-----------------------------');
|
||||||
|
|
||||||
let users = await db.models.User.find({});
|
let users = await User.find({});
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
let balance = await Balance.findOne({ user: user._id });
|
let balance = await Balance.findOne({ user: user._id });
|
||||||
if (balance !== null) {
|
if (balance !== null) {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
const listUsers = async () => {
|
const listUsers = async () => {
|
||||||
try {
|
try {
|
||||||
await connect();
|
await connect();
|
||||||
const users = await db.models.User.find({}, 'email provider avatar username name createdAt');
|
const users = await User.find({}, 'email provider avatar username name createdAt');
|
||||||
|
|
||||||
console.log('\nUser List:');
|
console.log('\nUser List:');
|
||||||
console.log('----------------------------------------');
|
console.log('----------------------------------------');
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await connect();
|
await connect();
|
||||||
|
|
@ -20,7 +20,7 @@ const { askQuestion, silentExit } = require('./helpers');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await db.models.User.updateMany({}, { $set: { termsAccepted: false } });
|
const result = await User.updateMany({}, { $set: { termsAccepted: false } });
|
||||||
console.green(`Updated ${result.modifiedCount} user(s).`);
|
console.green(`Updated ${result.modifiedCount} user(s).`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.red('Error resetting terms acceptance:', error);
|
console.red('Error resetting terms acceptance:', error);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { User, Balance } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, silentExit } = require('./helpers');
|
const { askQuestion, silentExit } = require('./helpers');
|
||||||
const { isEnabled } = require('~/server/utils/handleText');
|
const { isEnabled } = require('~/server/utils/handleText');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -56,7 +56,7 @@ const connect = require('./connect');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the user
|
// Validate the user
|
||||||
const user = await db.models.User.findOne({ email }).lean();
|
const user = await User.findOne({ email }).lean();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
console.red('Error: No user with that email was found!');
|
console.red('Error: No user with that email was found!');
|
||||||
silentExit(1);
|
silentExit(1);
|
||||||
|
|
@ -64,7 +64,7 @@ const connect = require('./connect');
|
||||||
console.purple(`Found user: ${user.email}`);
|
console.purple(`Found user: ${user.email}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let balance = await db.models.Balance.findOne({ user: user._id }).lean();
|
let balance = await Balance.findOne({ user: user._id }).lean();
|
||||||
if (!balance) {
|
if (!balance) {
|
||||||
console.purple('User has no balance!');
|
console.purple('User has no balance!');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -85,7 +85,7 @@ const connect = require('./connect');
|
||||||
*/
|
*/
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
result = await db.models.Balance.findOneAndUpdate(
|
result = await Balance.findOneAndUpdate(
|
||||||
{ user: user._id },
|
{ user: user._id },
|
||||||
{ tokenCredits: amount },
|
{ tokenCredits: amount },
|
||||||
{ upsert: true, new: true },
|
{ upsert: true, new: true },
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { v5: uuidv5 } = require('uuid');
|
const { v5: uuidv5 } = require('uuid');
|
||||||
|
const { Banner } = require('@librechat/data-schemas');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { askQuestion, askMultiLineQuestion, silentExit } = require('./helpers');
|
const { askQuestion, askMultiLineQuestion, silentExit } = require('./helpers');
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
const db = require('~/lib/db/connectDb');
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await connect();
|
await connect();
|
||||||
|
|
@ -87,7 +87,6 @@ const db = require('~/lib/db/connectDb');
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
const { Banner } = db.models;
|
|
||||||
// There is always only one Banner record in the DB.
|
// There is always only one Banner record in the DB.
|
||||||
// If a Banner exists in the DB, it will be updated.
|
// If a Banner exists in the DB, it will be updated.
|
||||||
// If it doesn't exist, a new one will be added.
|
// If it doesn't exist, a new one will be added.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
|
||||||
const { silentExit } = require('./helpers');
|
const { silentExit } = require('./helpers');
|
||||||
const db = require('~/lib/db/connectDb');
|
const { User, Conversation, Message } = require('@librechat/data-schemas');
|
||||||
const connect = require('./connect');
|
const connect = require('./connect');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
@ -14,7 +14,6 @@ const connect = require('./connect');
|
||||||
console.purple('Show the stats of all users');
|
console.purple('Show the stats of all users');
|
||||||
console.purple('-----------------------------');
|
console.purple('-----------------------------');
|
||||||
|
|
||||||
const { User, Conversation, Message } = db.models;
|
|
||||||
let users = await User.find({});
|
let users = await User.find({});
|
||||||
let userData = [];
|
let userData = [];
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
// Export all types
|
export { default as logger } from './config/winston';
|
||||||
|
export { default as meiliLogger } from './config/meiliLogger';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|
||||||
// Export all models
|
|
||||||
export * from './models';
|
export * from './models';
|
||||||
|
|
||||||
// Export all methods
|
|
||||||
export * from './methods';
|
export * from './methods';
|
||||||
|
|
||||||
// Export schemas (if needed for direct access)
|
// Export schemas (if needed for direct access)
|
||||||
|
|
@ -16,13 +13,10 @@ export { default as tokenSchema } from './schema/token';
|
||||||
export { signPayload, hashToken } from './schema/session';
|
export { signPayload, hashToken } from './schema/session';
|
||||||
|
|
||||||
export { default as actionSchema } from './schema/action';
|
export { default as actionSchema } from './schema/action';
|
||||||
export type { IAction } from './schema/action';
|
|
||||||
|
|
||||||
export { default as agentSchema } from './schema/agent';
|
export { default as agentSchema } from './schema/agent';
|
||||||
export type { IAgent } from './schema/agent';
|
|
||||||
|
|
||||||
export { default as assistantSchema } from './schema/assistant';
|
export { default as assistantSchema } from './schema/assistant';
|
||||||
export type { IAssistant } from './schema/assistant';
|
|
||||||
|
|
||||||
export { default as balanceSchema } from './schema/balance';
|
export { default as balanceSchema } from './schema/balance';
|
||||||
|
|
||||||
|
|
@ -38,10 +32,8 @@ export type { IConversationTag } from './schema/conversationTag';
|
||||||
export { default as convoSchema } from './schema/convo';
|
export { default as convoSchema } from './schema/convo';
|
||||||
|
|
||||||
export { default as fileSchema } from './schema/file';
|
export { default as fileSchema } from './schema/file';
|
||||||
export type { IMongoFile } from './schema/file';
|
|
||||||
|
|
||||||
export { default as keySchema } from './schema/key';
|
export { default as keySchema } from './schema/key';
|
||||||
export type { IKey } from './schema/key';
|
|
||||||
|
|
||||||
export { default as messageSchema } from './schema/message';
|
export { default as messageSchema } from './schema/message';
|
||||||
export type { IMessage } from './schema/message';
|
export type { IMessage } from './schema/message';
|
||||||
|
|
@ -62,7 +54,6 @@ export { default as promptGroupSchema } from './schema/promptGroup';
|
||||||
export type { IPromptGroup, IPromptGroupDocument } from './schema/promptGroup';
|
export type { IPromptGroup, IPromptGroupDocument } from './schema/promptGroup';
|
||||||
|
|
||||||
export { default as roleSchema } from './schema/role';
|
export { default as roleSchema } from './schema/role';
|
||||||
export type { IRole } from './schema/role';
|
|
||||||
|
|
||||||
export { default as shareSchema } from './schema/share';
|
export { default as shareSchema } from './schema/share';
|
||||||
export type { ISharedLink } from './schema/share';
|
export type { ISharedLink } from './schema/share';
|
||||||
|
|
|
||||||
5
packages/data-schemas/src/models/action.ts
Normal file
5
packages/data-schemas/src/models/action.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import actionSchema from '~/schema/action';
|
||||||
|
import type { IAction } from '~/types';
|
||||||
|
|
||||||
|
export const Action = mongoose.models.Action || mongoose.model<IAction>('Action', actionSchema);
|
||||||
5
packages/data-schemas/src/models/agent.ts
Normal file
5
packages/data-schemas/src/models/agent.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import agentSchema from '~/schema/agent';
|
||||||
|
import type { IAgent } from '~/types';
|
||||||
|
|
||||||
|
export const Agent = mongoose.models.Agent || mongoose.model<IAgent>('Agent', agentSchema);
|
||||||
6
packages/data-schemas/src/models/assistant.ts
Normal file
6
packages/data-schemas/src/models/assistant.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import assistantSchema from '~/schema/assistant';
|
||||||
|
import type { IAssistant } from '~/types';
|
||||||
|
|
||||||
|
export const Assistant =
|
||||||
|
mongoose.models.Assistant || mongoose.model<IAssistant>('Assistant', assistantSchema);
|
||||||
5
packages/data-schemas/src/models/banner.ts
Normal file
5
packages/data-schemas/src/models/banner.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import bannerSchema from '~/schema/banner';
|
||||||
|
import type { IBanner } from '~/types';
|
||||||
|
|
||||||
|
export const Banner = mongoose.models.Banner || mongoose.model<IBanner>('Banner', bannerSchema);
|
||||||
5
packages/data-schemas/src/models/file.ts
Normal file
5
packages/data-schemas/src/models/file.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import fileSchema from '~/schema/file';
|
||||||
|
import type { IMongoFile } from '~/types';
|
||||||
|
|
||||||
|
export const File = mongoose.models.File || mongoose.model<IMongoFile>('File', fileSchema);
|
||||||
|
|
@ -5,3 +5,8 @@ export { Session } from './session';
|
||||||
export { Balance } from './balance';
|
export { Balance } from './balance';
|
||||||
export { Conversation } from './convo';
|
export { Conversation } from './convo';
|
||||||
export { Message } from './message';
|
export { Message } from './message';
|
||||||
|
export { Agent } from './agent';
|
||||||
|
export { Role } from './role';
|
||||||
|
export { Action } from './action';
|
||||||
|
export { Assistant } from './assistant';
|
||||||
|
export { File } from './file';
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import mongoose, { Schema, Document, Model, Query } from 'mongoose';
|
|
||||||
import { MeiliSearch, Index } from 'meilisearch';
|
import { MeiliSearch, Index } from 'meilisearch';
|
||||||
|
import mongoose, { Schema, Document, Model, Query } from 'mongoose';
|
||||||
import logger from '~/config/meiliLogger';
|
import logger from '~/config/meiliLogger';
|
||||||
|
|
||||||
interface MongoMeiliOptions {
|
interface MongoMeiliOptions {
|
||||||
|
|
|
||||||
5
packages/data-schemas/src/models/role.ts
Normal file
5
packages/data-schemas/src/models/role.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import roleSchema from '~/schema/role';
|
||||||
|
import type { IRole } from '~/types';
|
||||||
|
|
||||||
|
export const Role = mongoose.models.Role || mongoose.model<IRole>('Role', roleSchema);
|
||||||
|
|
@ -1,31 +1,5 @@
|
||||||
import mongoose, { Schema, Document } from 'mongoose';
|
import mongoose, { Schema } from 'mongoose';
|
||||||
|
import type { IAction } from '~/types';
|
||||||
export interface IAction extends Document {
|
|
||||||
user: mongoose.Types.ObjectId;
|
|
||||||
action_id: string;
|
|
||||||
type: string;
|
|
||||||
settings?: unknown;
|
|
||||||
agent_id?: string;
|
|
||||||
assistant_id?: string;
|
|
||||||
metadata: {
|
|
||||||
api_key?: string;
|
|
||||||
auth: {
|
|
||||||
authorization_type?: string;
|
|
||||||
custom_auth_header?: string;
|
|
||||||
type: 'service_http' | 'oauth' | 'none';
|
|
||||||
authorization_content_type?: string;
|
|
||||||
authorization_url?: string;
|
|
||||||
client_url?: string;
|
|
||||||
scope?: string;
|
|
||||||
token_exchange_method: 'default_post' | 'basic_auth_header' | null;
|
|
||||||
};
|
|
||||||
domain: string;
|
|
||||||
privacy_policy_url?: string;
|
|
||||||
raw_spec?: string;
|
|
||||||
oauth_client_id?: string;
|
|
||||||
oauth_client_secret?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the Auth sub-schema with type-safety.
|
// Define the Auth sub-schema with type-safety.
|
||||||
const AuthSchema = new Schema(
|
const AuthSchema = new Schema(
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,5 @@
|
||||||
import { Schema, Document, Types } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
export interface IAgent extends Omit<Document, 'model'> {
|
import type { IAgent } from '~/types';
|
||||||
id: string;
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
instructions?: string;
|
|
||||||
avatar?: {
|
|
||||||
filepath: string;
|
|
||||||
source: string;
|
|
||||||
};
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
model_parameters?: Record<string, unknown>;
|
|
||||||
artifacts?: string;
|
|
||||||
access_level?: number;
|
|
||||||
recursion_limit?: number;
|
|
||||||
tools?: string[];
|
|
||||||
tool_kwargs?: Array<unknown>;
|
|
||||||
actions?: string[];
|
|
||||||
author: Types.ObjectId;
|
|
||||||
authorName?: string;
|
|
||||||
hide_sequential_outputs?: boolean;
|
|
||||||
end_after_tools?: boolean;
|
|
||||||
agent_ids?: string[];
|
|
||||||
isCollaborative?: boolean;
|
|
||||||
conversation_starters?: string[];
|
|
||||||
tool_resources?: unknown;
|
|
||||||
projectIds?: Types.ObjectId[];
|
|
||||||
versions?: Omit<IAgent, 'versions'>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const agentSchema = new Schema<IAgent>(
|
const agentSchema = new Schema<IAgent>(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,5 @@
|
||||||
import { Schema, Document, Types } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
import type { IAssistant } from '~/types';
|
||||||
export interface IAssistant extends Document {
|
|
||||||
user: Types.ObjectId;
|
|
||||||
assistant_id: string;
|
|
||||||
avatar?: {
|
|
||||||
filepath: string;
|
|
||||||
source: string;
|
|
||||||
};
|
|
||||||
conversation_starters?: string[];
|
|
||||||
access_level?: number;
|
|
||||||
file_ids?: string[];
|
|
||||||
actions?: string[];
|
|
||||||
append_current_datetime?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const assistantSchema = new Schema<IAssistant>(
|
const assistantSchema = new Schema<IAssistant>(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,6 @@
|
||||||
import mongoose, { Schema, Document, Types } from 'mongoose';
|
import mongoose, { Schema } from 'mongoose';
|
||||||
import { FileSources } from 'librechat-data-provider';
|
import { FileSources } from 'librechat-data-provider';
|
||||||
|
import type { IMongoFile } from '~/types';
|
||||||
// @ts-ignore
|
|
||||||
export interface IMongoFile extends Document {
|
|
||||||
user: Types.ObjectId;
|
|
||||||
conversationId?: string;
|
|
||||||
file_id: string;
|
|
||||||
temp_file_id?: string;
|
|
||||||
bytes: number;
|
|
||||||
text?: string;
|
|
||||||
filename: string;
|
|
||||||
filepath: string;
|
|
||||||
object: 'file';
|
|
||||||
embedded?: boolean;
|
|
||||||
type: string;
|
|
||||||
context?: string;
|
|
||||||
usage: number;
|
|
||||||
source: string;
|
|
||||||
model?: string;
|
|
||||||
width?: number;
|
|
||||||
height?: number;
|
|
||||||
metadata?: {
|
|
||||||
fileIdentifier?: string;
|
|
||||||
};
|
|
||||||
expiresAt?: Date;
|
|
||||||
createdAt?: Date;
|
|
||||||
updatedAt?: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
const file: Schema<IMongoFile> = new Schema(
|
const file: Schema<IMongoFile> = new Schema(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,6 @@
|
||||||
import { Schema, Document } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
||||||
|
import type { IRole } from '~/types';
|
||||||
export interface IRole extends Document {
|
|
||||||
name: string;
|
|
||||||
permissions: {
|
|
||||||
[PermissionTypes.BOOKMARKS]?: {
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
};
|
|
||||||
[PermissionTypes.PROMPTS]?: {
|
|
||||||
[Permissions.SHARED_GLOBAL]?: boolean;
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
[Permissions.CREATE]?: boolean;
|
|
||||||
};
|
|
||||||
[PermissionTypes.AGENTS]?: {
|
|
||||||
[Permissions.SHARED_GLOBAL]?: boolean;
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
[Permissions.CREATE]?: boolean;
|
|
||||||
};
|
|
||||||
[PermissionTypes.MULTI_CONVO]?: {
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
};
|
|
||||||
[PermissionTypes.TEMPORARY_CHAT]?: {
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
};
|
|
||||||
[PermissionTypes.RUN_CODE]?: {
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
};
|
|
||||||
[PermissionTypes.WEB_SEARCH]?: {
|
|
||||||
[Permissions.USE]?: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a sub-schema for permissions. Notice we disable _id for this subdocument.
|
// Create a sub-schema for permissions. Notice we disable _id for this subdocument.
|
||||||
const rolePermissionsSchema = new Schema(
|
const rolePermissionsSchema = new Schema(
|
||||||
|
|
|
||||||
28
packages/data-schemas/src/types/action.ts
Normal file
28
packages/data-schemas/src/types/action.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import mongoose, { Document } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IAction extends Document {
|
||||||
|
user: mongoose.Types.ObjectId;
|
||||||
|
action_id: string;
|
||||||
|
type: string;
|
||||||
|
settings?: unknown;
|
||||||
|
agent_id?: string;
|
||||||
|
assistant_id?: string;
|
||||||
|
metadata: {
|
||||||
|
api_key?: string;
|
||||||
|
auth: {
|
||||||
|
authorization_type?: string;
|
||||||
|
custom_auth_header?: string;
|
||||||
|
type: 'service_http' | 'oauth' | 'none';
|
||||||
|
authorization_content_type?: string;
|
||||||
|
authorization_url?: string;
|
||||||
|
client_url?: string;
|
||||||
|
scope?: string;
|
||||||
|
token_exchange_method: 'default_post' | 'basic_auth_header' | null;
|
||||||
|
};
|
||||||
|
domain: string;
|
||||||
|
privacy_policy_url?: string;
|
||||||
|
raw_spec?: string;
|
||||||
|
oauth_client_id?: string;
|
||||||
|
oauth_client_secret?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
31
packages/data-schemas/src/types/agent.ts
Normal file
31
packages/data-schemas/src/types/agent.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Document, Types } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IAgent extends Omit<Document, 'model'> {
|
||||||
|
id: string;
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
instructions?: string;
|
||||||
|
avatar?: {
|
||||||
|
filepath: string;
|
||||||
|
source: string;
|
||||||
|
};
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
model_parameters?: Record<string, unknown>;
|
||||||
|
artifacts?: string;
|
||||||
|
access_level?: number;
|
||||||
|
recursion_limit?: number;
|
||||||
|
tools?: string[];
|
||||||
|
tool_kwargs?: Array<unknown>;
|
||||||
|
actions?: string[];
|
||||||
|
author: Types.ObjectId;
|
||||||
|
authorName?: string;
|
||||||
|
hide_sequential_outputs?: boolean;
|
||||||
|
end_after_tools?: boolean;
|
||||||
|
agent_ids?: string[];
|
||||||
|
isCollaborative?: boolean;
|
||||||
|
conversation_starters?: string[];
|
||||||
|
tool_resources?: unknown;
|
||||||
|
projectIds?: Types.ObjectId[];
|
||||||
|
versions?: Omit<IAgent, 'versions'>[];
|
||||||
|
}
|
||||||
15
packages/data-schemas/src/types/assistant.ts
Normal file
15
packages/data-schemas/src/types/assistant.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Document, Types } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IAssistant extends Document {
|
||||||
|
user: Types.ObjectId;
|
||||||
|
assistant_id: string;
|
||||||
|
avatar?: {
|
||||||
|
filepath: string;
|
||||||
|
source: string;
|
||||||
|
};
|
||||||
|
conversation_starters?: string[];
|
||||||
|
access_level?: number;
|
||||||
|
file_ids?: string[];
|
||||||
|
actions?: string[];
|
||||||
|
append_current_datetime?: boolean;
|
||||||
|
}
|
||||||
10
packages/data-schemas/src/types/banner.ts
Normal file
10
packages/data-schemas/src/types/banner.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { Document } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IBanner extends Document {
|
||||||
|
bannerId: string;
|
||||||
|
message: string;
|
||||||
|
displayFrom: Date;
|
||||||
|
displayTo?: Date;
|
||||||
|
type: 'banner' | 'popup';
|
||||||
|
isPublic: boolean;
|
||||||
|
}
|
||||||
27
packages/data-schemas/src/types/file.ts
Normal file
27
packages/data-schemas/src/types/file.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { Document, Types } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IMongoFile extends Omit<Document, 'model'> {
|
||||||
|
user: Types.ObjectId;
|
||||||
|
conversationId?: string;
|
||||||
|
file_id: string;
|
||||||
|
temp_file_id?: string;
|
||||||
|
bytes: number;
|
||||||
|
text?: string;
|
||||||
|
filename: string;
|
||||||
|
filepath: string;
|
||||||
|
object: 'file';
|
||||||
|
embedded?: boolean;
|
||||||
|
type: string;
|
||||||
|
context?: string;
|
||||||
|
usage: number;
|
||||||
|
source: string;
|
||||||
|
model?: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
metadata?: {
|
||||||
|
fileIdentifier?: string;
|
||||||
|
};
|
||||||
|
expiresAt?: Date;
|
||||||
|
createdAt?: Date;
|
||||||
|
updatedAt?: Date;
|
||||||
|
}
|
||||||
|
|
@ -3,4 +3,10 @@ export * from './token';
|
||||||
export * from './convo';
|
export * from './convo';
|
||||||
export * from './session';
|
export * from './session';
|
||||||
export * from './balance';
|
export * from './balance';
|
||||||
|
export * from './banner';
|
||||||
export * from './message';
|
export * from './message';
|
||||||
|
export * from './agent';
|
||||||
|
export * from './role';
|
||||||
|
export * from './action';
|
||||||
|
export * from './assistant';
|
||||||
|
export * from './file';
|
||||||
|
|
|
||||||
33
packages/data-schemas/src/types/role.ts
Normal file
33
packages/data-schemas/src/types/role.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { Document } from 'mongoose';
|
||||||
|
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
||||||
|
|
||||||
|
export interface IRole extends Document {
|
||||||
|
name: string;
|
||||||
|
permissions: {
|
||||||
|
[PermissionTypes.BOOKMARKS]?: {
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
};
|
||||||
|
[PermissionTypes.PROMPTS]?: {
|
||||||
|
[Permissions.SHARED_GLOBAL]?: boolean;
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
[Permissions.CREATE]?: boolean;
|
||||||
|
};
|
||||||
|
[PermissionTypes.AGENTS]?: {
|
||||||
|
[Permissions.SHARED_GLOBAL]?: boolean;
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
[Permissions.CREATE]?: boolean;
|
||||||
|
};
|
||||||
|
[PermissionTypes.MULTI_CONVO]?: {
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
};
|
||||||
|
[PermissionTypes.TEMPORARY_CHAT]?: {
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
};
|
||||||
|
[PermissionTypes.RUN_CODE]?: {
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
};
|
||||||
|
[PermissionTypes.WEB_SEARCH]?: {
|
||||||
|
[Permissions.USE]?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue