diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php deleted file mode 100644 index dd3ff35b6f..0000000000 --- a/app/Actions/Fortify/UpdateUserProfileInformation.php +++ /dev/null @@ -1,73 +0,0 @@ - $input - */ - public function update(User $user, array $input): void - { - $changedFields = collect(['name', 'email']) - ->filter(fn (string $field): bool => $user->{$field} !== $input[$field]) - ->values() - ->all(); - Validator::make($input, [ - 'name' => ['required', 'string', 'max:255'], - - 'email' => [ - 'required', - 'string', - 'email', - 'max:255', - Rule::unique('users')->ignore($user->id), - ], - ])->validateWithBag('updateProfileInformation'); - - if ( - $input['email'] !== $user->email && - $user instanceof MustVerifyEmail - ) { - $this->updateVerifiedUser($user, $input); - } else { - $user->fill([ - 'name' => $input['name'], - 'email' => $input['email'], - ])->save(); - } - - if ($changedFields !== []) { - auditLog('ui.user.profile_updated', [ - 'team_id' => $user->currentTeam()?->id, - 'resource' => 'user', - 'user_name' => $user->name, - 'changed_fields' => $changedFields, - ]); - } - } - - /** - * Update the given verified user's profile information. - * - * @param array $input - */ - protected function updateVerifiedUser(User $user, array $input): void - { - $user->fill([ - 'name' => $input['name'], - 'email' => $input['email'], - 'email_verified_at' => null, - ])->save(); - - $user->sendEmailVerificationNotification(); - } -} diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 50df845f7b..a340c2033b 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -5,7 +5,6 @@ namespace App\Providers; use App\Actions\Fortify\CreateNewUser; use App\Actions\Fortify\ResetUserPassword; use App\Actions\Fortify\UpdateUserPassword; -use App\Actions\Fortify\UpdateUserProfileInformation; use App\Models\OauthSetting; use App\Models\TeamInvitation; use App\Models\User; @@ -115,7 +114,6 @@ class FortifyServiceProvider extends ServiceProvider }); Fortify::resetUserPasswordsUsing(ResetUserPassword::class); - Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class); Fortify::updateUserPasswordsUsing(UpdateUserPassword::class); Fortify::confirmPasswordView(function () { diff --git a/config/fortify.php b/config/fortify.php index 6b78c1c65f..5b7864af01 100644 --- a/config/fortify.php +++ b/config/fortify.php @@ -136,7 +136,6 @@ return [ Features::registration(), Features::resetPasswords(), // Features::emailVerification(), - Features::updateProfileInformation(), Features::updatePasswords(), Features::twoFactorAuthentication([ 'confirm' => true, diff --git a/tests/Feature/FortifyProfileInformationRouteTest.php b/tests/Feature/FortifyProfileInformationRouteTest.php new file mode 100644 index 0000000000..340505232b --- /dev/null +++ b/tests/Feature/FortifyProfileInformationRouteTest.php @@ -0,0 +1,38 @@ + 0]); +}); + +it('does not let a user change the email through the Fortify profile route', function (bool $hasSsoIdentity) { + $user = User::factory()->create(['email' => 'owner@example.com']); + if ($hasSsoIdentity) { + OauthIdentity::create([ + 'user_id' => $user->id, + 'provider' => 'github', + 'issuer' => 'github', + 'provider_user_id' => '123', + 'email' => 'owner@example.com', + ]); + } + + $this->actingAs($user) + ->withoutMiddleware(VerifyCsrfToken::class) + ->put('/user/profile-information', ['name' => 'Changed', 'email' => 'attacker@example.com']); + + expect(Route::has('user-profile-information.update'))->toBeFalse() + ->and($user->fresh()->email)->toBe('owner@example.com') + ->and($user->fresh()->name)->not->toBe('Changed'); +})->with([ + 'SSO user' => [true], + 'password user' => [false], +]);