From ec0edf89b92d7abcdea1adcc354f143e97569035 Mon Sep 17 00:00:00 2001 From: Hyko Date: Fri, 24 Apr 2026 15:52:34 -0400 Subject: [PATCH] fix(admin): require current password for self password change and fix field ordering - initialize `newPassword` in form state on load - add `needsCurrentPassword` flag triggered by email or password change when editing self - route self password change to profile endpoint with current password verification - move role tag input above password section and update current password field visibility logic --- .../admin/components/UserEditModal.client.js | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/features/admin/components/UserEditModal.client.js b/src/features/admin/components/UserEditModal.client.js index b8bc001..1acfe4f 100644 --- a/src/features/admin/components/UserEditModal.client.js +++ b/src/features/admin/components/UserEditModal.client.js @@ -46,6 +46,7 @@ const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => { name: userJson.user.name || '', email: userJson.user.email || '', currentPassword: '', + newPassword: '', }); } else { toast.error(userJson.message || 'Utilisateur introuvable'); @@ -90,10 +91,12 @@ const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => { const emailChanged = userData && formData.email !== userData.email; + const needsCurrentPassword = isSelf && (emailChanged || !!formData.newPassword); + const validate = () => { const newErrors = {}; if (!formData.name?.trim()) newErrors.name = 'Le nom est requis'; - if (emailChanged && isSelf && !formData.currentPassword) newErrors.currentPassword = 'Le mot de passe est requis pour changer le courriel'; + if (needsCurrentPassword && !formData.currentPassword) newErrors.currentPassword = 'Le mot de passe actuel est requis'; setErrors(newErrors); return Object.keys(newErrors).length === 0; }; @@ -175,11 +178,16 @@ const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => { } if (formData.newPassword) { - const pwdRes = await fetch(`/zen/api/users/${userId}/password`, { - method: 'PUT', + const pwdUrl = isSelf ? '/zen/api/users/profile/password' : `/zen/api/users/${userId}/password`; + const pwdMethod = isSelf ? 'POST' : 'PUT'; + const pwdBody = isSelf + ? { currentPassword: formData.currentPassword, newPassword: formData.newPassword } + : { newPassword: formData.newPassword }; + const pwdRes = await fetch(pwdUrl, { + method: pwdMethod, headers: { 'Content-Type': 'application/json' }, credentials: 'include', - body: JSON.stringify({ newPassword: formData.newPassword }), + body: JSON.stringify(pwdBody), }); const pwdData = await pwdRes.json(); if (!pwdRes.ok) { @@ -242,17 +250,17 @@ const UserEditModal = ({ userId, currentUserId, isOpen, onClose, onSaved }) => { placeholder="courriel@exemple.com" /> - {isSelf && emailChanged && ( - handleInputChange('currentPassword', value)} - placeholder="Votre mot de passe" - error={errors.currentPassword} - description="Requis pour confirmer le changement de courriel" - /> - )} + + ( + + )} + />
{
- ( - - )} - /> + {needsCurrentPassword && ( + handleInputChange('currentPassword', value)} + placeholder="Votre mot de passe" + error={errors.currentPassword} + description={emailChanged && formData.newPassword ? 'Requis pour confirmer le changement de courriel et de mot de passe' : emailChanged ? 'Requis pour confirmer le changement de courriel' : 'Requis pour confirmer le changement de mot de passe'} + /> + )} )}