From b497bb2908b1726a484e071e0ff6a8360dd0824f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 18 Mar 2026 05:33:00 -0400 Subject: [PATCH] Normalize `current_username` on account redirect form (#38262) --- app/models/form/redirect.rb | 15 ++++++++------- spec/models/form/redirect_spec.rb | 7 +++++++ spec/system/settings/migration/redirects_spec.rb | 13 +++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/models/form/redirect.rb b/app/models/form/redirect.rb index 6ab95f21f1..5721674ef9 100644 --- a/app/models/form/redirect.rb +++ b/app/models/form/redirect.rb @@ -2,15 +2,20 @@ class Form::Redirect include ActiveModel::Model + include ActiveModel::Attributes + include ActiveModel::Attributes::Normalization - attr_accessor :account, :target_account, :current_password, - :current_username + attr_accessor :account, :target_account, :current_password - attr_reader :acct + attribute :acct, :string + attribute :current_username, :string validates :acct, presence: true, domain: { acct: true } validate :validate_target_account + normalizes :acct, with: ->(value) { value.to_s.strip.gsub(/\A@/, '') }, apply_to_nil: true + normalizes :current_username, with: ->(value) { value.strip.delete_prefix('@') } + def valid_with_challenge?(current_user) if current_user.encrypted_password.present? errors.add(:current_password, :invalid) unless current_user.valid_password?(current_password) @@ -24,10 +29,6 @@ class Form::Redirect valid? end - def acct=(val) - @acct = val.to_s.strip.gsub(/\A@/, '') - end - private def set_target_account diff --git a/spec/models/form/redirect_spec.rb b/spec/models/form/redirect_spec.rb index 4427a0bb86..afd10c3ccb 100644 --- a/spec/models/form/redirect_spec.rb +++ b/spec/models/form/redirect_spec.rb @@ -29,4 +29,11 @@ RSpec.describe Form::Redirect do end end end + + describe 'Normalizations' do + it { is_expected.to normalize(:acct).from(nil).to('') } + it { is_expected.to normalize(:acct).from(' @username ').to('username') } + + it { is_expected.to normalize(:current_username).from(' @username ').to('username') } + end end diff --git a/spec/system/settings/migration/redirects_spec.rb b/spec/system/settings/migration/redirects_spec.rb index b59be5ac1f..11882c571d 100644 --- a/spec/system/settings/migration/redirects_spec.rb +++ b/spec/system/settings/migration/redirects_spec.rb @@ -32,6 +32,19 @@ RSpec.describe 'Settings Migration Redirects' do .to have_content(I18n.t('migrations.cancelled_msg')) end + context 'when user has blank encrypted password' do + before { user.update! encrypted_password: '' } + + it 'saves a redirect via username confirmation' do + visit new_settings_migration_redirect_path + + fill_in 'form_redirect_acct', with: 'new@example.host' + fill_in 'form_redirect_current_username', with: " @#{user.account.username} " + expect { click_on I18n.t('migrations.set_redirect') } + .to(change { user.reload.account.moved_to_account_id }.from(nil)) + end + end + private def stub_resolver