diff --git a/app/Http/Controllers/Settings/HomeSettings.php b/app/Http/Controllers/Settings/HomeSettings.php index 9211a5f9e..487fcd6c0 100644 --- a/app/Http/Controllers/Settings/HomeSettings.php +++ b/app/Http/Controllers/Settings/HomeSettings.php @@ -172,7 +172,9 @@ trait HomeSettings public function emailUpdate(Request $request) { $this->validate($request, [ - 'email' => 'required|email|unique:users,email', + // Ignore the user's own row so an unchanged (pre-filled) submission + // is a no-op; collisions with other accounts still fail. + 'email' => 'required|email|unique:users,email,'.$request->user()->id, ]); $changes = false; $email = $request->input('email'); diff --git a/tests/Feature/Settings/EmailUpdateTest.php b/tests/Feature/Settings/EmailUpdateTest.php new file mode 100644 index 000000000..ac9e924f1 --- /dev/null +++ b/tests/Feature/Settings/EmailUpdateTest.php @@ -0,0 +1,56 @@ +create(); + $user->refresh(); + + $this->actingAs($user) + ->withSession(['auth.password_confirmed_at' => time()]) + ->post('/settings/email', ['email' => $user->email]) + ->assertRedirect('/settings/email') + ->assertSessionHasNoErrors(); +}); + +it('persists a genuinely new email', function () { + $user = User::factory()->create(); + $user->refresh(); + + $newEmail = 'brand.new.'.uniqid().'@example.com'; + + $this->actingAs($user) + ->withSession(['auth.password_confirmed_at' => time()]) + ->post('/settings/email', ['email' => $newEmail]) + ->assertSessionHasNoErrors(); + + expect($user->fresh()->email)->toBe($newEmail); +}); + +it('rejects an email already used by another account', function () { + $other = User::factory()->create(['email' => 'taken@example.com']); + $user = User::factory()->create(); + $user->refresh(); + + $this->actingAs($user) + ->withSession(['auth.password_confirmed_at' => time()]) + ->post('/settings/email', ['email' => 'taken@example.com']) + ->assertSessionHasErrors('email'); + + expect($user->fresh()->email)->not->toBe('taken@example.com'); +});