Compare commits

...

8 Commits

Author SHA1 Message Date
Ruben Talstra
13d3257801 🔧 fix: Add support for configurable MongoDB database name in connection logic 2025-06-15 12:50:08 +02:00
Ruben Talstra
cde930e0d6 🔧 fix: Make MongoDB database name configurable via environment variable 2025-06-15 12:07:02 +02:00
Ruben Talstra
c94d4d9ae1 Merge branch 'dev' into explicit-mongo-dbname 2025-06-15 12:05:18 +02:00
Ruben Talstra
6a811c708b 🔧 refactor: Move MongoDB connection logic to a separate module and make database name optional 2025-06-15 12:04:55 +02:00
Ruben Talstra
cffd66054e 🔧 refactor: Make MongoDB name optional in connection options 2025-05-29 16:21:52 +02:00
Jason Koh
d7f4f8ef4a update env vars for testing 2025-05-27 16:25:57 -07:00
Jason Koh
50e36e67f0 clean up 2025-05-27 14:51:31 -07:00
Jason Koh
12ac302a68 define mongodb name 2025-05-27 14:32:41 -07:00
5 changed files with 111 additions and 3 deletions

View File

@@ -15,6 +15,7 @@ HOST=localhost
PORT=3080
MONGO_URI=mongodb://127.0.0.1:27017/LibreChat
# MONGO_DB_NAME=LibreChat
DOMAIN_CLIENT=http://localhost:3080
DOMAIN_SERVER=http://localhost:3080

View File

@@ -1,6 +1,7 @@
require('dotenv').config();
const mongoose = require('mongoose');
const MONGO_URI = process.env.MONGO_URI;
const MONGO_DB_NAME = process.env.MONGO_DB_NAME;
if (!MONGO_URI) {
throw new Error('Please define the MONGO_URI environment variable');
@@ -33,6 +34,10 @@ async function connectDb() {
// useCreateIndex: true
};
if (MONGO_DB_NAME) {
opts.dbName = MONGO_DB_NAME;
}
mongoose.set('strictQuery', true);
cached.promise = mongoose.connect(MONGO_URI, opts).then((mongoose) => {
return mongoose;
@@ -43,6 +48,4 @@ async function connectDb() {
return cached.conn;
}
module.exports = {
connectDb,
};
module.exports = { connectDb };

102
api/db/connect.spec.js Normal file
View File

@@ -0,0 +1,102 @@
jest.mock('dotenv');
require('dotenv').config();
const mongoose = require('mongoose');
const { MongoMemoryServer } = require('mongodb-memory-server');
// Helper to clear the connect module from require cache
function clearConnectModule() {
delete require.cache[require.resolve('./connect')];
}
beforeEach(() => {
// Reset environment and global state
clearConnectModule();
delete process.env.MONGO_URI;
delete process.env.MONGO_DB_NAME;
global.mongoose = undefined;
});
describe('connectDb Module', () => {
it('throws if MONGO_URI is not defined', () => {
expect(() => require('./connect')).toThrow('Please define the MONGO_URI environment variable');
});
describe('with in-memory MongoDB', () => {
let mongoServer;
let uri;
beforeAll(async () => {
mongoServer = await MongoMemoryServer.create();
uri = mongoServer.getUri();
});
afterAll(async () => {
// Ensure real mongoose connection is torn down
await mongoose.disconnect();
await mongoServer.stop();
});
it('connects using only MONGO_URI (no dbName override)', async () => {
process.env.MONGO_URI = uri;
clearConnectModule();
const { connectDb } = require('./connect');
const mongooseInstance = await connectDb();
expect(mongooseInstance).toBe(mongoose);
// The default DB is whatever follows the last slash in the URI
const defaultDbNameMatch = uri.match(/\/([\w-]+)(\?.*)?$/);
const defaultDbName = defaultDbNameMatch ? defaultDbNameMatch[1] : mongoose.connection.name;
expect(mongooseInstance.connection.name).toBe(defaultDbName);
});
it('strips any DB name in URI when MONGO_DB_NAME is set', async () => {
process.env.MONGO_URI = uri;
process.env.MONGO_DB_NAME = 'ignoredDbName';
clearConnectModule();
const connectSpy = jest.spyOn(mongoose, 'connect');
const { connectDb } = require('./connect');
await connectDb();
const [calledUri, calledOpts] = connectSpy.mock.calls[0];
// Should have removed the trailing "/<dbname>"
expect(calledUri).not.toMatch(/\/[\w-]+$/);
// And since we strip it rather than passing dbName, opts.dbName remains unset
expect(calledOpts).not.toHaveProperty('dbName');
connectSpy.mockRestore();
});
it('caches the connection between calls', async () => {
process.env.MONGO_URI = uri;
clearConnectModule();
const { connectDb } = require('./connect');
const first = await connectDb();
// simulate still-connected
mongoose.connection.readyState = 1;
const second = await connectDb();
expect(second).toBe(first);
});
it('reconnects if cached conn is disconnected', async () => {
process.env.MONGO_URI = uri;
clearConnectModule();
const { connectDb } = require('./connect');
// First, establish a connection
await connectDb();
expect(mongoose.connection.readyState).toBe(1);
// Now actually tear it down
await mongoose.disconnect();
expect(mongoose.connection.readyState).toBe(0);
// Calling again should reconnect
await connectDb();
expect(mongoose.connection.readyState).toBe(1);
});
});
});

View File

@@ -1,5 +1,6 @@
# Test DB URI. You can use your actual MONGO_URI if you don't mind it potentially including test data.
MONGO_URI=mongodb://127.0.0.1:27017/chatgpt-jest
MONGO_DB_NAME=librechat-test
# Credential encryption/decryption for testing
CREDS_KEY=c3301ad2f69681295e022fb135e92787afb6ecfeaa012a10f8bb4ddf6b669e6d

View File

@@ -2,6 +2,7 @@
require('dotenv').config({ path: './test/.env.test' });
process.env.MONGO_URI = 'mongodb://127.0.0.1:27017/dummy-uri';
process.env.MONGO_DB_NAME = 'librechat-test';
process.env.BAN_VIOLATIONS = 'true';
process.env.BAN_DURATION = '7200000';
process.env.BAN_INTERVAL = '20';