From 149d0df5577908cc58a8648d0619aa6b28bc6e2b Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Thu, 5 Nov 2026 17:08:50 +0100 Subject: [PATCH 1/3] fix(manager): land on the dashboard after changing a password (#2553) The save redirected to the user list, which needs edit_user, so a role without it saw "You don't have enough privileges" and lost the tab even though the password had changed. Co-Authored-By: Claude Opus 5.5 --- core/src/Controllers/Users/ChangePassword.php | 3 ++- .../ChangePasswordRedirectTest.php | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 core/tests/Unit/Controllers/ChangePasswordRedirectTest.php diff --git a/core/src/Controllers/Users/ChangePassword.php b/core/src/Controllers/Users/ChangePassword.php index eebc1d6803..ee6355f190 100644 --- a/core/src/Controllers/Users/ChangePassword.php +++ b/core/src/Controllers/Users/ChangePassword.php @@ -42,7 +42,8 @@ public function process() : bool } } - header("Location: index.php?a=99"); + // not the user list (a=99): it needs edit_user, which this action does not require + header("Location: index.php?a=2"); exit(); } diff --git a/core/tests/Unit/Controllers/ChangePasswordRedirectTest.php b/core/tests/Unit/Controllers/ChangePasswordRedirectTest.php new file mode 100644 index 0000000000..e3558f7cb2 --- /dev/null +++ b/core/tests/Unit/Controllers/ChangePasswordRedirectTest.php @@ -0,0 +1,21 @@ +toContain('header("Location: index.php?a=2");') + ->not->toContain('Location: index.php?a=99') + ->and($theme)->toMatch('/^\s*2 => null,/m') + ->and($dashboard)->not->toContain('error_no_privileges'); +}); + +test('the user list stays closed to roles without edit_user', function () { + $list = (string) file_get_contents(dirname(__DIR__, 4) . '/manager/actions/web_user_management.static.php'); + + expect($list)->toContain("hasPermission('edit_user')"); +}); From b49eb722705d49a59053bbef749981b9ea5a02a6 Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Thu, 5 Nov 2026 17:08:51 +0100 Subject: [PATCH 2/3] fix(manager): stop locking the change password page The form changes the viewer's own password only, yet a second manager opening it while another had it open was refused with the privilege error. Co-Authored-By: Claude Opus 5.5 --- core/src/Controllers/Password.php | 9 +-------- core/tests/Unit/Controllers/PasswordPageLockTest.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 core/tests/Unit/Controllers/PasswordPageLockTest.php diff --git a/core/src/Controllers/Password.php b/core/src/Controllers/Password.php index d363a35e92..8c48929294 100644 --- a/core/src/Controllers/Password.php +++ b/core/src/Controllers/Password.php @@ -1,6 +1,5 @@ first(); - if ($out !== null) { - return sprintf($this->managerTheme->getLexicon('error_no_privileges'), $out->username); - } - - return $out; + return null; } /** diff --git a/core/tests/Unit/Controllers/PasswordPageLockTest.php b/core/tests/Unit/Controllers/PasswordPageLockTest.php new file mode 100644 index 0000000000..f0282f11a0 --- /dev/null +++ b/core/tests/Unit/Controllers/PasswordPageLockTest.php @@ -0,0 +1,10 @@ +newInstanceWithoutConstructor(); + + expect($controller->checkLocked())->toBeNull(); +}); From 4d236ed8c6273f89d2ae0f5b19d17db1208efbe3 Mon Sep 17 00:00:00 2001 From: Artur Kyryliuk Date: Thu, 5 Nov 2026 17:08:51 +0100 Subject: [PATCH 3/3] fix(manager): open the user list after a delete only with edit_user A role with delete_user but not edit_user deleted the user and then got the privilege error from the list. It now lands on the dashboard. Co-Authored-By: Claude Opus 5.5 --- core/src/Controllers/Users/DeleteUser.php | 4 +++- .../tests/Unit/Controllers/DeleteUserRedirectTest.php | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 core/tests/Unit/Controllers/DeleteUserRedirectTest.php diff --git a/core/src/Controllers/Users/DeleteUser.php b/core/src/Controllers/Users/DeleteUser.php index ef24601f3a..5a3d0ec557 100644 --- a/core/src/Controllers/Users/DeleteUser.php +++ b/core/src/Controllers/Users/DeleteUser.php @@ -53,7 +53,9 @@ public function process() : bool } } } - header("Location: index.php?a=99"); + // the user list needs edit_user, which this action does not require + $landing = $this->managerTheme->getCore()->hasPermission('edit_user') ? 99 : 2; + header("Location: index.php?a={$landing}"); exit(); } diff --git a/core/tests/Unit/Controllers/DeleteUserRedirectTest.php b/core/tests/Unit/Controllers/DeleteUserRedirectTest.php new file mode 100644 index 0000000000..9629acf56b --- /dev/null +++ b/core/tests/Unit/Controllers/DeleteUserRedirectTest.php @@ -0,0 +1,11 @@ +toContain("\$landing = \$this->managerTheme->getCore()->hasPermission('edit_user') ? 99 : 2;") + ->toContain('header("Location: index.php?a={$landing}");') + ->not->toContain('header("Location: index.php?a=99");'); +});