diff --git a/client/src/pages/Settings.jsx b/client/src/pages/Settings.jsx index a74cbb7..0b3854b 100644 --- a/client/src/pages/Settings.jsx +++ b/client/src/pages/Settings.jsx @@ -1130,6 +1130,43 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => { } }; + // Helper functions for local user management + const handleEditUser = (user) => { + setEditingUser(user); + setShowEditUser(true); + }; + + const handleToggleUserStatus = async (user) => { + try { + await api.put(`/tenant/users/${user.id}/status`, { + is_active: !user.is_active + }); + toast.success(`User ${user.is_active ? 'deactivated' : 'activated'} successfully`); + fetchUsers(); + } catch (error) { + 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'); + } + }; + if (loading) { return (
@@ -1408,43 +1445,6 @@ const UsersSettings = ({ tenantConfig, onRefresh }) => { )}
); - - // Helper functions for local user management - const handleEditUser = (user) => { - setEditingUser(user); - setShowEditUser(true); - }; - - const handleToggleUserStatus = async (user) => { - try { - await api.put(`/tenant/users/${user.id}/status`, { - is_active: !user.is_active - }); - toast.success(`User ${user.is_active ? 'deactivated' : 'activated'} successfully`); - fetchUsers(); - } catch (error) { - 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 ee75327..5e8f26b 100644 --- a/server/routes/tenant.js +++ b/server/routes/tenant.js @@ -673,6 +673,88 @@ router.put('/users/:userId', authenticateToken, requirePermissions(['users.edit' } }); +/** + * DELETE /tenant/users/:userId + * Delete a 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 deletion 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 account' + }); + } + + // Store user info for logging before deletion + const userInfo = { + id: user.id, + username: user.username, + email: user.email + }; + + // Delete the user + await user.destroy(); + + console.log(`🗑️ User "${userInfo.username}" (${userInfo.email}) 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' + }); + } +}); + /** * DELETE /tenant/users/:userId * Delete user permanently (user admin or higher, local auth only)