mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
* refactor: Agent CodeFiles, abortUpload WIP * feat: code environment file upload * refactor: useLazyEffect * refactor: - Add `watch` from `useFormContext` to check if code execution is enabled - Disable file upload button if `agent_id` is not selected or code execution is disabled * WIP: primeCodeFiles; refactor: rename sessionId to session_id for uniformity * Refactor: Rename session_id to sessionId for uniformity in AuthService.js * chore: bump @librechat/agents to version 1.7.1 * WIP: prime code files * refactor: Update code env file upload method to use read stream * feat: reupload code env file if no longer active * refactor: isAssistantTool -> isEntityTool + address type issues * feat: execute code tool hook * refactor: Rename isPluginAuthenticated to checkPluginAuth in PluginController.js * refactor: Update PluginController.js to use AuthType constant for comparison * feat: verify tool authentication (execute_code) * feat: enter librechat_code_api_key * refactor: Remove unused imports in BookmarkForm.tsx * feat: authenticate code tool * refactor: Update Action.tsx to conditionally render the key and revoke key buttons * refactor(Code/Action): prevent uncheck-able 'Run Code' capability when key is revoked * refactor(Code/Action): Update Action.tsx to conditionally render the key and revoke key buttons * fix: agent file upload edge cases * chore: bump @librechat/agents * fix: custom endpoint providerValue icon * feat: ollama meta modal token values + context * feat: ollama agents * refactor: Update token models for Ollama models * chore: Comment out CodeForm * refactor: Update token models for Ollama and Meta models
171 lines
5.8 KiB
JavaScript
171 lines
5.8 KiB
JavaScript
const {
|
|
Session,
|
|
Balance,
|
|
getFiles,
|
|
deleteFiles,
|
|
deleteConvos,
|
|
deletePresets,
|
|
deleteMessages,
|
|
deleteUserById,
|
|
} = require('~/models');
|
|
const User = require('~/models/User');
|
|
const { updateUserPluginAuth, deleteUserPluginAuth } = require('~/server/services/PluginService');
|
|
const { updateUserPluginsService, deleteUserKey } = require('~/server/services/UserService');
|
|
const { verifyEmail, resendVerificationEmail } = require('~/server/services/AuthService');
|
|
const { processDeleteRequest } = require('~/server/services/Files/process');
|
|
const { deleteAllSharedLinks } = require('~/models/Share');
|
|
const { Transaction } = require('~/models/Transaction');
|
|
const { logger } = require('~/config');
|
|
|
|
const getUserController = async (req, res) => {
|
|
res.status(200).send(req.user);
|
|
};
|
|
|
|
const getTermsStatusController = async (req, res) => {
|
|
try {
|
|
const user = await User.findById(req.user.id);
|
|
if (!user) {
|
|
return res.status(404).json({ message: 'User not found' });
|
|
}
|
|
res.status(200).json({ termsAccepted: !!user.termsAccepted });
|
|
} catch (error) {
|
|
logger.error('Error fetching terms acceptance status:', error);
|
|
res.status(500).json({ message: 'Error fetching terms acceptance status' });
|
|
}
|
|
};
|
|
|
|
const acceptTermsController = async (req, res) => {
|
|
try {
|
|
const user = await User.findByIdAndUpdate(req.user.id, { termsAccepted: true }, { new: true });
|
|
if (!user) {
|
|
return res.status(404).json({ message: 'User not found' });
|
|
}
|
|
res.status(200).json({ message: 'Terms accepted successfully' });
|
|
} catch (error) {
|
|
logger.error('Error accepting terms:', error);
|
|
res.status(500).json({ message: 'Error accepting terms' });
|
|
}
|
|
};
|
|
|
|
const deleteUserFiles = async (req) => {
|
|
try {
|
|
const userFiles = await getFiles({ user: req.user.id });
|
|
await processDeleteRequest({
|
|
req,
|
|
files: userFiles,
|
|
});
|
|
} catch (error) {
|
|
logger.error('[deleteUserFiles]', error);
|
|
}
|
|
};
|
|
|
|
const updateUserPluginsController = async (req, res) => {
|
|
const { user } = req;
|
|
const { pluginKey, action, auth, isEntityTool } = req.body;
|
|
let authService;
|
|
try {
|
|
if (!isEntityTool) {
|
|
const userPluginsService = await updateUserPluginsService(user, pluginKey, action);
|
|
|
|
if (userPluginsService instanceof Error) {
|
|
logger.error('[userPluginsService]', userPluginsService);
|
|
const { status, message } = userPluginsService;
|
|
res.status(status).send({ message });
|
|
}
|
|
}
|
|
|
|
if (auth) {
|
|
const keys = Object.keys(auth);
|
|
const values = Object.values(auth);
|
|
if (action === 'install' && keys.length > 0) {
|
|
for (let i = 0; i < keys.length; i++) {
|
|
authService = await updateUserPluginAuth(user.id, keys[i], pluginKey, values[i]);
|
|
if (authService instanceof Error) {
|
|
logger.error('[authService]', authService);
|
|
const { status, message } = authService;
|
|
res.status(status).send({ message });
|
|
}
|
|
}
|
|
}
|
|
if (action === 'uninstall' && keys.length > 0) {
|
|
for (let i = 0; i < keys.length; i++) {
|
|
authService = await deleteUserPluginAuth(user.id, keys[i]);
|
|
if (authService instanceof Error) {
|
|
logger.error('[authService]', authService);
|
|
const { status, message } = authService;
|
|
res.status(status).send({ message });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
res.status(200).send();
|
|
} catch (err) {
|
|
logger.error('[updateUserPluginsController]', err);
|
|
return res.status(500).json({ message: 'Something went wrong.' });
|
|
}
|
|
};
|
|
|
|
const deleteUserController = async (req, res) => {
|
|
const { user } = req;
|
|
|
|
try {
|
|
await deleteMessages({ user: user.id }); // delete user messages
|
|
await Session.deleteMany({ user: user.id }); // delete user sessions
|
|
await Transaction.deleteMany({ user: user.id }); // delete user transactions
|
|
await deleteUserKey({ userId: user.id, all: true }); // delete user keys
|
|
await Balance.deleteMany({ user: user._id }); // delete user balances
|
|
await deletePresets(user.id); // delete user presets
|
|
/* TODO: Delete Assistant Threads */
|
|
await deleteConvos(user.id); // delete user convos
|
|
await deleteUserPluginAuth(user.id, null, true); // delete user plugin auth
|
|
await deleteUserById(user.id); // delete user
|
|
await deleteAllSharedLinks(user.id); // delete user shared links
|
|
await deleteUserFiles(req); // delete user files
|
|
await deleteFiles(null, user.id); // delete database files in case of orphaned files from previous steps
|
|
/* TODO: queue job for cleaning actions and assistants of non-existant users */
|
|
logger.info(`User deleted account. Email: ${user.email} ID: ${user.id}`);
|
|
res.status(200).send({ message: 'User deleted' });
|
|
} catch (err) {
|
|
logger.error('[deleteUserController]', err);
|
|
return res.status(500).json({ message: 'Something went wrong.' });
|
|
}
|
|
};
|
|
|
|
const verifyEmailController = async (req, res) => {
|
|
try {
|
|
const verifyEmailService = await verifyEmail(req);
|
|
if (verifyEmailService instanceof Error) {
|
|
return res.status(400).json(verifyEmailService);
|
|
} else {
|
|
return res.status(200).json(verifyEmailService);
|
|
}
|
|
} catch (e) {
|
|
logger.error('[verifyEmailController]', e);
|
|
return res.status(500).json({ message: 'Something went wrong.' });
|
|
}
|
|
};
|
|
|
|
const resendVerificationController = async (req, res) => {
|
|
try {
|
|
const result = await resendVerificationEmail(req);
|
|
if (result instanceof Error) {
|
|
return res.status(400).json(result);
|
|
} else {
|
|
return res.status(200).json(result);
|
|
}
|
|
} catch (e) {
|
|
logger.error('[verifyEmailController]', e);
|
|
return res.status(500).json({ message: 'Something went wrong.' });
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getUserController,
|
|
getTermsStatusController,
|
|
acceptTermsController,
|
|
deleteUserController,
|
|
verifyEmailController,
|
|
updateUserPluginsController,
|
|
resendVerificationController,
|
|
};
|