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)