mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
🚫👤feat: delete user from UI (#1526)
* initial commit * fix: UserController bugs; fix: lint errors * fix: delete files * language support * style(DeleteAccount): update to the latest style * style: fix after merge main * chore: Add canDeleteAccount middleware for user deletion endpoint * chore: renamed to ALLOW_ACCOUNT_DELETION * fix(canDeleteAccount): use uppercase admin role * chore: imports order * chore: Enable account deletion by default if omitted/commented out * chore: Add logging for user account deletion * chore: Bump data-provider package version to 0.6.6 * chore: Import Transaction model in UserController * chore: Update CONFIG_VERSION to 1.1.4 * chore: Update user account deletion logging * chore: Refactor user account deletion logic --------- Co-authored-by: Berry-13 <root@Berry> Co-authored-by: Danny Avila <messagedaniel@protonmail.com> Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
f69b317171
commit
a7f5b57272
19 changed files with 348 additions and 17 deletions
|
|
@ -1,5 +1,15 @@
|
|||
const { updateUserPluginsService } = require('~/server/services/UserService');
|
||||
const {
|
||||
User,
|
||||
Session,
|
||||
Balance,
|
||||
deleteFiles,
|
||||
deleteConvos,
|
||||
deletePresets,
|
||||
deleteMessages,
|
||||
} = require('~/models');
|
||||
const { updateUserPluginAuth, deleteUserPluginAuth } = require('~/server/services/PluginService');
|
||||
const { updateUserPluginsService, deleteUserKey } = require('~/server/services/UserService');
|
||||
const { Transaction } = require('~/models/Transaction');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
const getUserController = async (req, res) => {
|
||||
|
|
@ -53,7 +63,30 @@ const updateUserPluginsController = async (req, res) => {
|
|||
}
|
||||
};
|
||||
|
||||
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
|
||||
await deleteConvos(user.id); // delete user convos
|
||||
await deleteUserPluginAuth(user.id, null, true); // delete user plugin auth
|
||||
await User.deleteOne({ _id: user.id }); // delete user
|
||||
await deleteFiles(null, user.id); // delete user files
|
||||
logger.info(`User deleted account. Email: ${user.email} ID: ${user.id}`);
|
||||
res.status(200).send({ message: 'User deleted' });
|
||||
} catch (err) {
|
||||
logger.error('[deleteUserController]', err);
|
||||
res.status(500).send({ message: err.message });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getUserController,
|
||||
updateUserPluginsController,
|
||||
deleteUserController,
|
||||
};
|
||||
|
|
|
|||
27
api/server/middleware/canDeleteAccount.js
Normal file
27
api/server/middleware/canDeleteAccount.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
const { isEnabled } = require('~/server/utils');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
/**
|
||||
* Checks if the user can delete their account
|
||||
*
|
||||
* @async
|
||||
* @function
|
||||
* @param {Object} req - Express request object
|
||||
* @param {Object} res - Express response object
|
||||
* @param {Function} next - Next middleware function
|
||||
*
|
||||
* @returns {Promise<function|Object>} - Returns a Promise which when resolved calls next middleware if the user can delete their account
|
||||
*/
|
||||
|
||||
const canDeleteAccount = async (req, res, next = () => {}) => {
|
||||
const { user } = req;
|
||||
const { ALLOW_ACCOUNT_DELETION = true } = process.env;
|
||||
if (user?.role === 'ADMIN' || isEnabled(ALLOW_ACCOUNT_DELETION)) {
|
||||
return next();
|
||||
} else {
|
||||
logger.error(`[User] [Delete Account] [User cannot delete account] [User: ${user?.id}]`);
|
||||
return res.status(403).send({ message: 'You do not have permission to delete this account' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = canDeleteAccount;
|
||||
|
|
@ -20,6 +20,7 @@ const validateImageRequest = require('./validateImageRequest');
|
|||
const moderateText = require('./moderateText');
|
||||
const noIndex = require('./noIndex');
|
||||
const importLimiters = require('./importLimiters');
|
||||
const canDeleteAccount = require('./canDeleteAccount');
|
||||
|
||||
module.exports = {
|
||||
...uploadLimiters,
|
||||
|
|
@ -44,4 +45,5 @@ module.exports = {
|
|||
noIndex,
|
||||
...importLimiters,
|
||||
checkDomainAllowed,
|
||||
canDeleteAccount,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
const express = require('express');
|
||||
const requireJwtAuth = require('../middleware/requireJwtAuth');
|
||||
const { getUserController, updateUserPluginsController } = require('../controllers/UserController');
|
||||
const canDeleteAccount = require('../middleware/canDeleteAccount');
|
||||
const {
|
||||
getUserController,
|
||||
updateUserPluginsController,
|
||||
deleteUserController,
|
||||
} = require('../controllers/UserController');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', requireJwtAuth, getUserController);
|
||||
router.post('/plugins', requireJwtAuth, updateUserPluginsController);
|
||||
router.delete('/delete', requireJwtAuth, canDeleteAccount, deleteUserController);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
|||
|
|
@ -88,7 +88,17 @@ const updateUserPluginAuth = async (userId, authField, pluginKey, value) => {
|
|||
}
|
||||
};
|
||||
|
||||
const deleteUserPluginAuth = async (userId, authField) => {
|
||||
const deleteUserPluginAuth = async (userId, authField, all = false) => {
|
||||
if (all) {
|
||||
try {
|
||||
const response = await PluginAuth.deleteMany({ userId });
|
||||
return response;
|
||||
} catch (err) {
|
||||
logger.error('[deleteUserPluginAuth]', err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return await PluginAuth.deleteOne({ userId, authField });
|
||||
} catch (err) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue