fix(auth): prevent admin from revoking their last users.manage role
- add self-lockout guard in handleRevokeUserRole api handler - sequence role additions before removals and handle delete errors in UserEditModal - document the security rule in core/users README
This commit is contained in:
@@ -123,22 +123,33 @@ const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => {
|
||||
const toAdd = selectedRoleIds.filter(id => !initialRoleIds.includes(id));
|
||||
const toRemove = initialRoleIds.filter(id => !selectedRoleIds.includes(id));
|
||||
|
||||
await Promise.all([
|
||||
...toAdd.map(roleId =>
|
||||
await Promise.all(
|
||||
toAdd.map(roleId =>
|
||||
fetch(`/zen/api/users/${userId}/roles`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ roleId }),
|
||||
})
|
||||
),
|
||||
...toRemove.map(roleId =>
|
||||
)
|
||||
);
|
||||
|
||||
const removeResults = await Promise.all(
|
||||
toRemove.map(roleId =>
|
||||
fetch(`/zen/api/users/${userId}/roles/${roleId}`, {
|
||||
method: 'DELETE',
|
||||
credentials: 'include',
|
||||
})
|
||||
),
|
||||
]);
|
||||
}).then(async res => ({ res, data: await res.json() }))
|
||||
)
|
||||
);
|
||||
|
||||
const failedRemove = removeResults.find(({ res }) => !res.ok);
|
||||
if (failedRemove) {
|
||||
toast.error(failedRemove.data?.message || failedRemove.data?.error || 'Impossible de retirer ce rôle');
|
||||
onSaved?.();
|
||||
onClose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (emailChanged) {
|
||||
if (isSelf) {
|
||||
|
||||
Reference in New Issue
Block a user