🏗️ refactor: Extract DB layers to data-schemas for shared use (#7650)

* refactor: move model definitions and database-related methods to packages/data-schemas

* ci: update tests due to new DB structure

fix: disable mocking `librechat-data-provider`

feat: Add schema exports to data-schemas package

- Introduced a new schema module that exports various schemas including action, agent, and user schemas.
- Updated index.ts to include the new schema exports for better modularity and organization.

ci: fix appleStrategy tests

fix: Agent.spec.js

ci: refactor handleTools tests to use MongoMemoryServer for in-memory database

fix: getLogStores imports

ci: update banViolation tests to use MongoMemoryServer and improve session mocking

test: refactor samlStrategy tests to improve mock configurations and user handling

ci: fix crypto mock in handleText tests for improved accuracy

ci: refactor spendTokens tests to improve model imports and setup

ci: refactor Message model tests to use MongoMemoryServer and improve database interactions

* refactor: streamline IMessage interface and move feedback properties to types/message.ts

* refactor: use exported initializeRoles from `data-schemas`, remove api workspace version (this serves as an example of future migrations that still need to happen)

* refactor: update model imports to use destructuring from `~/db/models` for consistency and clarity

* refactor: remove unused mongoose imports from model files for cleaner code

* refactor: remove unused mongoose imports from Share, Prompt, and Transaction model files for cleaner code

* refactor: remove unused import in Transaction model for cleaner code

* ci: update deploy workflow to reference new Docker Dev Branch Images Build and add new workflow for building Docker images on dev branch

* chore: cleanup imports
This commit is contained in:
Danny Avila 2025-05-30 22:18:13 -04:00 committed by GitHub
parent 4cbab86b45
commit a2fc7d312a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
161 changed files with 2998 additions and 2088 deletions

View file

@ -17,9 +17,9 @@ const { logger, getFlowStateManager, sendEvent } = require('~/config');
const { encryptV2, decryptV2 } = require('~/server/utils/crypto');
const { getActions, deleteActions } = require('~/models/Action');
const { deleteAssistant } = require('~/models/Assistant');
const { findToken } = require('~/models/Token');
const { logAxiosError } = require('~/utils');
const { getLogStores } = require('~/cache');
const { findToken } = require('~/models');
const JWT_SECRET = process.env.JWT_SECRET;
const toolNameRegex = /^[a-zA-Z0-9_-]+$/;

View file

@ -1,5 +1,7 @@
jest.mock('~/models/Role', () => ({
jest.mock('~/models', () => ({
initializeRoles: jest.fn(),
}));
jest.mock('~/models/Role', () => ({
updateAccessPermissions: jest.fn(),
getRoleByName: jest.fn(),
updateRoleByName: jest.fn(),

View file

@ -25,8 +25,8 @@ const { processModelSpecs } = require('./start/modelSpecs');
const { initializeS3 } = require('./Files/S3/initialize');
const { loadAndFormatTools } = require('./ToolService');
const { agentsConfigSetup } = require('./start/agents');
const { initializeRoles } = require('~/models/Role');
const { isEnabled } = require('~/server/utils');
const { initializeRoles } = require('~/models');
const { getMCPManager } = require('~/config');
const paths = require('~/config/paths');

View file

@ -24,8 +24,10 @@ jest.mock('./Config/loadCustomConfig', () => {
jest.mock('./Files/Firebase/initialize', () => ({
initializeFirebase: jest.fn(),
}));
jest.mock('~/models/Role', () => ({
jest.mock('~/models', () => ({
initializeRoles: jest.fn(),
}));
jest.mock('~/models/Role', () => ({
updateAccessPermissions: jest.fn(),
}));
jest.mock('./ToolService', () => ({

View file

@ -3,24 +3,23 @@ const { webcrypto } = require('node:crypto');
const { SystemRoles, errorsToString } = require('librechat-data-provider');
const {
findUser,
countUsers,
createUser,
updateUser,
getUserById,
generateToken,
deleteUserById,
} = require('~/models/userMethods');
const {
createToken,
findToken,
deleteTokens,
countUsers,
getUserById,
findSession,
createToken,
deleteTokens,
deleteSession,
createSession,
generateToken,
deleteUserById,
generateRefreshToken,
} = require('~/models');
const { isEnabled, checkEmailConfig, sendEmail } = require('~/server/utils');
const { isEmailDomainAllowed } = require('~/server/services/domains');
const { getBalanceConfig } = require('~/server/services/Config');
const { registerSchema } = require('~/strategies/validators');
const { logger } = require('~/config');
@ -146,6 +145,7 @@ const verifyEmail = async (req) => {
}
const updatedUser = await updateUser(emailVerificationData.userId, { emailVerified: true });
if (!updatedUser) {
logger.warn(`[verifyEmail] [User update failed] [Email: ${decodedEmail}]`);
return new Error('Failed to update user verification status');
@ -155,6 +155,7 @@ const verifyEmail = async (req) => {
logger.info(`[verifyEmail] Email verification successful [Email: ${decodedEmail}]`);
return { message: 'Email verification was successful', status: 'success' };
};
/**
* Register a new user.
* @param {MongoUser} user <email, password, name, username>
@ -216,7 +217,9 @@ const registerUser = async (user, additionalData = {}) => {
const emailEnabled = checkEmailConfig();
const disableTTL = isEnabled(process.env.ALLOW_UNVERIFIED_EMAIL_LOGIN);
const newUser = await createUser(newUserData, disableTTL, true);
const balanceConfig = await getBalanceConfig();
const newUser = await createUser(newUserData, balanceConfig, disableTTL, true);
newUserId = newUser._id;
if (emailEnabled && !newUser.emailVerified) {
await sendVerificationEmail({
@ -389,6 +392,7 @@ const setAuthTokens = async (userId, res, sessionId = null) => {
throw error;
}
};
/**
* @function setOpenIDAuthTokens
* Set OpenID Authentication Tokens

View file

@ -1,10 +1,9 @@
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { logger } = require('@librechat/data-schemas');
const { resizeImageBuffer } = require('../images/resize');
const { updateUser } = require('~/models/userMethods');
const { updateFile } = require('~/models/File');
const { logger } = require('~/config');
const { updateUser, updateFile } = require('~/models');
const { saveBufferToAzure } = require('./crud');
/**

View file

@ -1,11 +1,10 @@
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { logger } = require('@librechat/data-schemas');
const { resizeImageBuffer } = require('../images/resize');
const { updateUser } = require('~/models/userMethods');
const { updateUser, updateFile } = require('~/models');
const { saveBufferToFirebase } = require('./crud');
const { updateFile } = require('~/models/File');
const { logger } = require('~/config');
/**
* Converts an image file to the target format. The function first resizes the image based on the specified

View file

@ -2,8 +2,7 @@ const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { resizeImageBuffer } = require('../images/resize');
const { updateUser } = require('~/models/userMethods');
const { updateFile } = require('~/models/File');
const { updateUser, updateFile } = require('~/models');
/**
* Converts an image file to the target format. The function first resizes the image based on the specified

View file

@ -1,11 +1,10 @@
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { logger } = require('@librechat/data-schemas');
const { resizeImageBuffer } = require('../images/resize');
const { updateUser } = require('~/models/userMethods');
const { updateUser, updateFile } = require('~/models');
const { saveBufferToS3 } = require('./crud');
const { updateFile } = require('~/models/File');
const { logger } = require('~/config');
const defaultBasePath = 'images';

View file

@ -1,5 +1,5 @@
const PluginAuth = require('~/models/schema/pluginAuthSchema');
const { encrypt, decrypt } = require('~/server/utils/');
const { encrypt, decrypt } = require('~/server/utils/crypto');
const { PluginAuth } = require('~/db/models');
const { logger } = require('~/config');
/**

View file

@ -1,7 +1,8 @@
const { logger } = require('@librechat/data-schemas');
const { ErrorTypes } = require('librechat-data-provider');
const { encrypt, decrypt } = require('~/server/utils');
const { updateUser, Key } = require('~/models');
const { logger } = require('~/config');
const { encrypt, decrypt } = require('~/server/utils/crypto');
const { updateUser } = require('~/models');
const { Key } = require('~/db/models');
/**
* Updates the plugins for a user based on the action specified (install/uninstall).

View file

@ -1,26 +0,0 @@
const jwt = require('jsonwebtoken');
/**
* Signs a given payload using either the `jose` library (for Bun runtime) or `jsonwebtoken`.
*
* @async
* @function
* @param {Object} options - The options for signing the payload.
* @param {Object} options.payload - The payload to be signed.
* @param {string} options.secret - The secret key used for signing.
* @param {number} options.expirationTime - The expiration time in seconds.
* @returns {Promise<string>} Returns a promise that resolves to the signed JWT.
* @throws {Error} Throws an error if there's an issue during signing.
*
* @example
* const signedPayload = await signPayload({
* payload: { userId: 123 },
* secret: 'my-secret-key',
* expirationTime: 3600
* });
*/
async function signPayload({ payload, secret, expirationTime }) {
return jwt.sign(payload, secret, { expiresIn: expirationTime });
}
module.exports = signPayload;

View file

@ -1,6 +1,6 @@
const { webcrypto } = require('node:crypto');
const { decryptV3, decryptV2 } = require('../utils/crypto');
const { hashBackupCode } = require('~/server/utils/crypto');
const { hashBackupCode, decryptV3, decryptV2 } = require('~/server/utils/crypto');
const { updateUser } = require('~/models');
// Base32 alphabet for TOTP secret encoding.
const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
@ -172,7 +172,6 @@ const verifyBackupCode = async ({ user, backupCode }) => {
: codeObj,
);
// Update the user record with the marked backup code.
const { updateUser } = require('~/models');
await updateUser(user._id, { backupCodes: updatedBackupCodes });
return true;
}