+ Are you sure you want to delete {deletingUser.username}?
+ This action cannot be undone and will permanently remove the user and all associated data.
+
+
+
+
+
+
+
+
+
+ )}
);
@@ -1369,6 +1426,25 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => {
toast.error('Failed to update user status');
}
};
+
+ const handleDeleteUser = (user) => {
+ setDeletingUser(user);
+ setShowDeleteConfirm(true);
+ };
+
+ const confirmDeleteUser = async () => {
+ if (!deletingUser) return;
+
+ try {
+ await api.delete(`/tenant/users/${deletingUser.id}`);
+ toast.success('User deleted successfully');
+ fetchUsers();
+ setShowDeleteConfirm(false);
+ setDeletingUser(null);
+ } catch (error) {
+ toast.error('Failed to delete user');
+ }
+ };
};
// Create User Modal Component (for local auth only)
diff --git a/server/routes/tenant.js b/server/routes/tenant.js
index eeac267..ee75327 100644
--- a/server/routes/tenant.js
+++ b/server/routes/tenant.js
@@ -673,6 +673,84 @@ router.put('/users/:userId', authenticateToken, requirePermissions(['users.edit'
}
});
+/**
+ * DELETE /tenant/users/:userId
+ * Delete user permanently (user admin or higher, local auth only)
+ */
+router.delete('/users/:userId', authenticateToken, requirePermissions(['users.delete']), async (req, res) => {
+ try {
+ // Determine tenant from request
+ const tenantId = await multiAuth.determineTenant(req);
+ if (!tenantId) {
+ return res.status(400).json({
+ success: false,
+ message: 'Unable to determine tenant'
+ });
+ }
+
+ const tenant = await Tenant.findOne({ where: { slug: tenantId } });
+ if (!tenant) {
+ return res.status(404).json({
+ success: false,
+ message: 'Tenant not found'
+ });
+ }
+
+ // Check if tenant uses local authentication
+ if (tenant.auth_provider !== 'local') {
+ return res.status(400).json({
+ success: false,
+ message: `User management is only available for local authentication. This tenant uses ${tenant.auth_provider}.`
+ });
+ }
+
+ const { userId } = req.params;
+
+ // Find user in this tenant
+ const user = await User.findOne({
+ where: {
+ id: userId,
+ tenant_id: tenant.id
+ }
+ });
+
+ if (!user) {
+ return res.status(404).json({
+ success: false,
+ message: 'User not found in this tenant'
+ });
+ }
+
+ // Prevent self-deletion
+ if (user.id === req.user.id) {
+ return res.status(400).json({
+ success: false,
+ message: 'Cannot delete your own user account'
+ });
+ }
+
+ // Store username for logging before deletion
+ const deletedUsername = user.username;
+
+ // Delete the user permanently
+ await user.destroy();
+
+ console.log(`⚠️ User "${deletedUsername}" permanently deleted from tenant "${tenantId}" by admin "${req.user.username}"`);
+
+ res.json({
+ success: true,
+ message: 'User deleted successfully'
+ });
+
+ } catch (error) {
+ console.error('Error deleting user:', error);
+ res.status(500).json({
+ success: false,
+ message: 'Failed to delete user'
+ });
+ }
+});
+
/**
* GET /tenant/auth
* Get authentication configuration (auth admins or higher)