PATCH /api/user/password — verifies the current password, enforces 8-char minimum on the new one, and rehashes via the configured password hasher. Returns 204 on success, 422 with an `error` body on every validation failure (wrong current, too-short new, missing fields). Settings adds a "Change password" link under the Account section that opens a modal with current/new/confirm fields and posts to the new endpoint. Confirm-mismatch and submit-disabled wiring is client-side; backend errors surface inline. Tests: 4 new controller tests cover success, wrong-current, short-new, and missing-fields; success path also re-fetches the user and checks the hash actually changed.
This commit is contained in:
@@ -115,4 +115,66 @@ class UserApiControllerTest extends AppWebTestCase
|
||||
|
||||
$this->assertResponseRedirects('/login');
|
||||
}
|
||||
|
||||
// US-09: updatePassword valid → 204 and the new password works for re-login
|
||||
public function test_update_password_valid_returns_204_and_rehashes(): void
|
||||
{
|
||||
$user = $this->createUser('us09@example.com', 'currentPass1');
|
||||
$client = $this->loginAs($user);
|
||||
|
||||
$client->request('PATCH', '/api/user/password', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode(['currentPassword' => 'currentPass1', 'newPassword' => 'brandNew2025']));
|
||||
|
||||
$this->assertResponseStatusCodeSame(204);
|
||||
|
||||
// Re-fetch the user; the stored hash must accept the new password and
|
||||
// reject the old one.
|
||||
$hasher = static::getContainer()->get('security.user_password_hasher');
|
||||
$em = static::getContainer()->get('doctrine.orm.entity_manager');
|
||||
$em->clear();
|
||||
$reloaded = $em->getRepository(\App\Entity\User::class)->findOneBy(['email' => 'us09@example.com']);
|
||||
$this->assertNotNull($reloaded);
|
||||
$this->assertTrue($hasher->isPasswordValid($reloaded, 'brandNew2025'));
|
||||
$this->assertFalse($hasher->isPasswordValid($reloaded, 'currentPass1'));
|
||||
}
|
||||
|
||||
// US-10: updatePassword wrong current → 422
|
||||
public function test_update_password_wrong_current_returns_422(): void
|
||||
{
|
||||
$user = $this->createUser('us10@example.com', 'rightPass1');
|
||||
$client = $this->loginAs($user);
|
||||
|
||||
$client->request('PATCH', '/api/user/password', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode(['currentPassword' => 'wrongPass1', 'newPassword' => 'brandNew2025']));
|
||||
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
}
|
||||
|
||||
// US-11: updatePassword too-short new → 422
|
||||
public function test_update_password_short_new_returns_422(): void
|
||||
{
|
||||
$user = $this->createUser('us11@example.com', 'currentPass1');
|
||||
$client = $this->loginAs($user);
|
||||
|
||||
$client->request('PATCH', '/api/user/password', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode(['currentPassword' => 'currentPass1', 'newPassword' => 'short']));
|
||||
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
}
|
||||
|
||||
// US-12: updatePassword missing fields → 422
|
||||
public function test_update_password_missing_fields_returns_422(): void
|
||||
{
|
||||
$user = $this->createUser('us12@example.com', 'currentPass1');
|
||||
$client = $this->loginAs($user);
|
||||
|
||||
$client->request('PATCH', '/api/user/password', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode(['newPassword' => 'brandNew2025']));
|
||||
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user