diff --git a/app/forms/reset_password_form.rb b/app/forms/reset_password_form.rb index 14feb592407..aa9b4237c3d 100644 --- a/app/forms/reset_password_form.rb +++ b/app/forms/reset_password_form.rb @@ -69,9 +69,7 @@ def mark_profile_as_password_reset end def password_reset_profile - FeatureManagement.pending_in_person_password_reset_enabled? ? - find_in_progress_in_person_or_active_profile : - active_profile + find_in_progress_in_person_or_active_profile end def find_in_progress_in_person_or_active_profile @@ -103,12 +101,8 @@ def extra_analytics_attributes end def pending_profile_invalidated? - if FeatureManagement.pending_in_person_password_reset_enabled? - pending_profile.present? && - !pending_profile.in_person_verification_pending? && - !pending_profile.fraud_deactivation_reason? - else - pending_profile.present? - end + pending_profile.present? && + !pending_profile.in_person_verification_pending? && + !pending_profile.fraud_deactivation_reason? end end diff --git a/app/models/user.rb b/app/models/user.rb index 98289aa8931..2feb5f46ec6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -546,19 +546,17 @@ def current_in_progress_in_person_enrollment_profile private def find_password_reset_profile - FeatureManagement.pending_in_person_password_reset_enabled? ? - find_in_person_in_progress_or_active_profile : - find_active_profile - end - - def find_active_profile - profiles.where.not(activated_at: nil).order(activated_at: :desc).first + find_in_person_in_progress_or_active_profile end def find_in_person_in_progress_or_active_profile current_in_progress_in_person_enrollment_profile || find_active_profile end + def find_active_profile + profiles.where.not(activated_at: nil).order(activated_at: :desc).first + end + def lockout_period IdentityConfig.store.lockout_period_in_minutes.minutes end diff --git a/app/views/user_mailer/reset_password_instructions.html.erb b/app/views/user_mailer/reset_password_instructions.html.erb index d87995ed1a4..65052270b69 100644 --- a/app/views/user_mailer/reset_password_instructions.html.erb +++ b/app/views/user_mailer/reset_password_instructions.html.erb @@ -17,13 +17,6 @@ <% end %> -<% if @in_person_verification_pending_profile && !IdentityConfig.store.feature_pending_in_person_password_reset_enabled %> - <%= render 'user_mailer/shared/in_person_warning_banner' %> -

- <%= @header || message.subject %> -

-<% end %> -

<%= t( 'user_mailer.reset_password_instructions.header', diff --git a/app/views/user_mailer/shared/_in_person_warning_banner.html.erb b/app/views/user_mailer/shared/_in_person_warning_banner.html.erb deleted file mode 100644 index 10fe28efa28..00000000000 --- a/app/views/user_mailer/shared/_in_person_warning_banner.html.erb +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -
- <%= image_tag('email/warning.png', width: 16, height: 14, alt: 'warning icon', style: 'margin-top: 5px;') %> - -

<%= t('user_mailer.reset_password_instructions.in_person_warning_description_html') %>

-
diff --git a/config/application.yml.default b/config/application.yml.default index 23e66c2e61f..c8064ece1ff 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -144,7 +144,6 @@ event_disavowal_expiration_hours: 240 facial_match_general_availability_enabled: true feature_idv_force_gpo_verification_enabled: false feature_idv_hybrid_flow_enabled: true -feature_pending_in_person_password_reset_enabled: true feature_select_email_to_share_enabled: true geo_data_file_path: 'geo_data/GeoLite2-City.mmdb' get_usps_proofing_results_job_cron: '0/30 * * * *' @@ -535,7 +534,6 @@ production: enable_usps_verification: false encrypted_document_storage_s3_bucket: '' facial_match_general_availability_enabled: false - feature_pending_in_person_password_reset_enabled: false feature_select_email_to_share_enabled: false idv_sp_required: true invalid_gpo_confirmation_zipcode: '' diff --git a/config/locales/en.yml b/config/locales/en.yml index 368ee45fbad..c4bdc8a36b7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1975,7 +1975,6 @@ user_mailer.reset_password_instructions.footer: This link expires in %{expires} user_mailer.reset_password_instructions.gpo_letter_description: If you reset your password, the verification code in your letter will no longer work and you’ll have to verify your identity again. user_mailer.reset_password_instructions.gpo_letter_header: Your letter is on the way user_mailer.reset_password_instructions.header: To finish resetting your password, please click the link below or copy and paste the entire link into your browser. -user_mailer.reset_password_instructions.in_person_warning_description_html: If you reset your password now, your barcode will not work at the Post Office. You’ll have to restart the identity verification process from the beginning. user_mailer.reset_password_instructions.link_text: Reset your password user_mailer.reset_password_instructions.subject: Reset your password user_mailer.signup_with_your_email.help_html: If you did not request a new account or suspect an error, please visit the %{app_name_html} %{help_link_html} or %{contact_link_html}. diff --git a/config/locales/es.yml b/config/locales/es.yml index e972c781917..27d85b42b68 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1987,7 +1987,6 @@ user_mailer.reset_password_instructions.footer: Este vínculo vence en %{expires user_mailer.reset_password_instructions.gpo_letter_description: Si restablece su contraseña, el código de verificación que recibió en su carta ya no funcionará y tendrá que volver a verificar su identidad. user_mailer.reset_password_instructions.gpo_letter_header: Su carta está en camino user_mailer.reset_password_instructions.header: Para terminar de restablecer su contraseña, haga clic en el enlace de abajo o copie y pegue el enlace completo en su navegador. -user_mailer.reset_password_instructions.in_person_warning_description_html: Si restablece su contraseña ahora, su código de barras no funcionará en la oficina de correos. Tendrá que volver a iniciar el proceso de verificación de identidad desde el principio. user_mailer.reset_password_instructions.link_text: Restablezca su contraseña user_mailer.reset_password_instructions.subject: Restablezca su contraseña user_mailer.signup_with_your_email.help_html: Si usted no solicitó una cuenta nueva o sospecha que hubo un error, visite la %{help_link_html} de %{app_name_html} o %{contact_link_html}. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 3860ec9dcea..f2d8de121fb 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1975,7 +1975,6 @@ user_mailer.reset_password_instructions.footer: Ce lien expire dans %{expires} h user_mailer.reset_password_instructions.gpo_letter_description: Si vous réinitialisez votre mot de passe, le code de vérification contenu dans votre lettre ne fonctionnera plus et vous devrez reconfirmer votre identité. user_mailer.reset_password_instructions.gpo_letter_header: Votre lettre est en route user_mailer.reset_password_instructions.header: Pour terminer la réinitialisation de votre mot de passe, veuillez cliquer sur le lien ci-dessous ou copier et coller le lien complet dans votre navigateur. -user_mailer.reset_password_instructions.in_person_warning_description_html: Si vous réinitialisez maintenant votre mot de passe, votre code-barres ne fonctionnera pas au bureau de poste. Vous devrez recommencer la procédure de vérification d’identité depuis le début. user_mailer.reset_password_instructions.link_text: Réinitialiser votre mot de passe user_mailer.reset_password_instructions.subject: Réinitialiser votre mot de passe user_mailer.signup_with_your_email.help_html: Si vous n’avez pas demandé un nouveau compte ou soupçonnez qu’une erreur s’est produite, veuillez visiter le %{help_link_html} de %{app_name_html} ou %{contact_link_html}. diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 30bbff2d6f1..22ef4e7f01e 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -1988,7 +1988,6 @@ user_mailer.reset_password_instructions.footer: 这一链接 %{expires} 小时 user_mailer.reset_password_instructions.gpo_letter_description: 如果你重设密码,信件中的一次性代码就会失效,你需要再次验证身份。 user_mailer.reset_password_instructions.gpo_letter_header: 你的信件已寄出。 user_mailer.reset_password_instructions.header: 要完成重设密码,请点击下面的链接或把整个链接复制并黏贴进浏览器。 -user_mailer.reset_password_instructions.in_person_warning_description_html: 如果你现在重设密码,你的条形码在邮局将无法使用。你会不得不从头开始身份验证流程。 user_mailer.reset_password_instructions.link_text: 重设你的密码 user_mailer.reset_password_instructions.subject: 重设你的密码 user_mailer.signup_with_your_email.help_html: 如果你没有要求一封新电邮或怀疑有错, 请访问 %{app_name_html}的 %{help_link_html} 或者 %{contact_link_html}。 diff --git a/lib/feature_management.rb b/lib/feature_management.rb index 0c4a35fd9f7..a34a2ec6ef7 100644 --- a/lib/feature_management.rb +++ b/lib/feature_management.rb @@ -174,9 +174,4 @@ def self.idv_by_mail_only? outage_status.any_phone_vendor_outage? || outage_status.phone_finder_outage? end - - # Whether pending in person password reset is enabled. - def self.pending_in_person_password_reset_enabled? - IdentityConfig.store.feature_pending_in_person_password_reset_enabled - end end diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 81a2a028c04..c9c84e97177 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -162,7 +162,6 @@ def self.store config.add(:facial_match_general_availability_enabled, type: :boolean) config.add(:feature_idv_force_gpo_verification_enabled, type: :boolean) config.add(:feature_idv_hybrid_flow_enabled, type: :boolean) - config.add(:feature_pending_in_person_password_reset_enabled, type: :boolean) config.add(:feature_select_email_to_share_enabled, type: :boolean) config.add(:geo_data_file_path, type: :string) config.add(:get_usps_proofing_results_job_cron, type: :string) diff --git a/spec/forms/reset_password_form_spec.rb b/spec/forms/reset_password_form_spec.rb index 58ee0f47c8b..ccdc717f058 100644 --- a/spec/forms/reset_password_form_spec.rb +++ b/spec/forms/reset_password_form_spec.rb @@ -14,493 +14,259 @@ end it_behaves_like 'password validation' + it_behaves_like 'strong password', 'ResetPasswordForm' describe '#submit' do subject(:result) { form.submit(params) } - context 'when pending in person password reset enabled' do + context 'when the password is valid but the token has expired' do before do - allow(FeatureManagement).to receive( - :pending_in_person_password_reset_enabled?, - ).and_return(true) + allow(user).to receive(:reset_password_period_valid?).and_return(false) end - context 'when the password is valid but the token has expired' do - before do - allow(user).to receive(:reset_password_period_valid?).and_return(false) - end - - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { reset_password_token: { token_expired: true } }, - user_id: '123', - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) - end + it 'returns a hash with errors' do + expect(result.to_h).to eq( + success: false, + error_details: { reset_password_token: { token_expired: true } }, + user_id: '123', + profile_deactivated: false, + pending_profile_invalidated: false, + pending_profile_pending_reasons: '', + ) end + end - context 'when the password is invalid and token is valid' do - let(:password) { 'invalid' } - - before do - allow(user).to receive(:reset_password_period_valid?).and_return(true) - end + context 'when the password is invalid and token is valid' do + let(:password) { 'invalid' } - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { - password: { too_short: true }, - password_confirmation: { too_short: true }, - }, - user_id: '123', - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) - end + before do + allow(user).to receive(:reset_password_period_valid?).and_return(true) end - context 'when both the password and token are valid' do - before do - allow(user).to receive(:reset_password_period_valid?).and_return(true) - end - - it 'sets the user password to the submitted password' do - expect { result }.to change { user.reload.encrypted_password_digest } - - expect(result.to_h).to eq( - success: true, - user_id: '123', - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) - end + it 'returns a hash with errors' do + expect(result.to_h).to eq( + success: false, + error_details: { + password: { too_short: true }, + password_confirmation: { too_short: true }, + }, + user_id: '123', + profile_deactivated: false, + pending_profile_invalidated: false, + pending_profile_pending_reasons: '', + ) end + end - context 'when both the password and token are invalid' do - let(:password) { 'short' } + context 'when both the password and token are valid' do + before do + allow(user).to receive(:reset_password_period_valid?).and_return(true) + end - before do - allow(user).to receive(:reset_password_period_valid?).and_return(false) - end + it 'sets the user password to the submitted password' do + expect { result }.to change { user.reload.encrypted_password_digest } - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { - password: { too_short: true }, - password_confirmation: { too_short: true }, - reset_password_token: { token_expired: true }, - }, - user_id: '123', - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) - end + expect(result.to_h).to eq( + success: true, + user_id: '123', + profile_deactivated: false, + pending_profile_invalidated: false, + pending_profile_pending_reasons: '', + ) end + end - context 'when the user does not exist in the db' do - let(:user) { User.new } + context 'when both the password and token are invalid' do + let(:password) { 'short' } - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { reset_password_token: { invalid_token: true } }, - user_id: nil, - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) - end + before do + allow(user).to receive(:reset_password_period_valid?).and_return(false) end - context 'when the user has an active profile' do - let(:user) { create(:user, :proofed, reset_password_sent_at: Time.zone.now) } + it 'returns a hash with errors' do + expect(result.to_h).to eq( + success: false, + error_details: { + password: { too_short: true }, + password_confirmation: { too_short: true }, + reset_password_token: { token_expired: true }, + }, + user_id: '123', + profile_deactivated: false, + pending_profile_invalidated: false, + pending_profile_pending_reasons: '', + ) + end + end - it 'deactivates the profile' do - expect(result.success?).to eq(true) - expect(result.extra[:profile_deactivated]).to eq(true) - expect(user.profiles.any?(&:active?)).to eq(false) - end + context 'when the user does not exist in the db' do + let(:user) { User.new } + + it 'returns a hash with errors' do + expect(result.to_h).to eq( + success: false, + error_details: { reset_password_token: { invalid_token: true } }, + user_id: nil, + profile_deactivated: false, + pending_profile_invalidated: false, + pending_profile_pending_reasons: '', + ) end + end - context 'when the user does not have an active profile' do - let(:user) { create(:user, reset_password_sent_at: Time.zone.now) } + context 'when the user has an active profile' do + let(:user) { create(:user, :proofed, reset_password_sent_at: Time.zone.now) } - it 'includes that the profile was not deactivated in the form response' do - expect(result.success?).to eq(true) - expect(result.extra[:profile_deactivated]).to eq(false) - end + it 'deactivates the profile' do + expect(result.success?).to eq(true) + expect(result.extra[:profile_deactivated]).to eq(true) + expect(user.profiles.any?(&:active?)).to eq(false) end + end - context 'when the user has a pending profile' do - context 'when the profile is pending gpo verification' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:profile) do - create(:profile, :verify_by_mail_pending, user: user) - end - - before do - @result = form.submit(params) - profile.reload - end - - it 'includes that the profile was not deactivated in the form response' do - expect(result.success?).to eq(true) - expect(result.extra[:pending_profile_invalidated]).to eq(true) - expect(result.extra[:pending_profile_pending_reasons]).to eq( - 'gpo_verification_pending', - ) - end - end + context 'when the user does not have an active profile' do + let(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - context 'when the profile is pending in person verification' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:profile) { create(:profile, :in_person_verification_pending, user: user) } - - before do - @result = form.submit(params) - profile.reload - end - - it 'returns a successful response' do - expect(@result.success?).to eq(true) - end - - it 'includes that the profile was not deactivated in the form response' do - expect(@result.extra).to include( - user_id: user.uuid, - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: 'in_person_verification_pending', - ) - end - - it 'updates the profile to have a "password reset" deactivation reason' do - expect(profile.deactivation_reason).to eq('password_reset') - end - end + it 'includes that the profile was not deactivated in the form response' do + expect(result.success?).to eq(true) + expect(result.extra[:profile_deactivated]).to eq(false) + end + end - context 'when the profile is in fraud review for in person verification' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:enrollment) { create(:in_person_enrollment, :in_fraud_review, user: user) } - let(:profile) { enrollment.profile } - - before do - @result = form.submit(params) - profile.reload - end - - it 'returns a successful response' do - expect(@result.success?).to eq(true) - end - - it 'includes that the profile was not deactivated in the form response' do - expect(@result.extra).to include( - user_id: user.uuid, - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: 'fraud_check_pending', - ) - end - - it 'updates the profile to have a "password reset" deactivation reason' do - expect(profile.deactivation_reason).to eq('password_reset') - end + context 'when the user has a pending profile' do + context 'when the profile is pending gpo verification' do + let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } + let!(:profile) do + create(:profile, :verify_by_mail_pending, user: user) end - context 'when the user has an active and a pending in-person verification profile' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:pending_profile) { create(:profile, :in_person_verification_pending, user: user) } - let!(:active_profile) { create(:profile, :active, user: user) } - - before do - @result = form.submit(params) - pending_profile.reload - active_profile.reload - end - - it 'returns a successful response' do - expect(@result.success?).to eq(true) - end - - it 'includes that the profile was not deactivated in the form response' do - expect(@result.extra).to include( - user_id: user.uuid, - profile_deactivated: true, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) - end - - it 'updates the pending profile to have a "password reset" deactivation reason' do - expect(pending_profile.deactivation_reason).to eq('password_reset') - end - - it 'does not update the active profile to have a "password reset" deactivation reason' do - expect(active_profile.deactivation_reason).to be_nil - end + before do + @result = form.submit(params) + profile.reload end - end - - context 'when the user does not have a pending profile' do - let(:user) { create(:user, reset_password_sent_at: Time.zone.now) } it 'includes that the profile was not deactivated in the form response' do expect(result.success?).to eq(true) - expect(result.extra[:pending_profile_invalidated]).to eq(false) - expect(result.extra[:pending_profile_pending_reasons]).to eq('') + expect(result.extra[:pending_profile_invalidated]).to eq(true) + expect(result.extra[:pending_profile_pending_reasons]).to eq( + 'gpo_verification_pending', + ) end end - context 'when the unconfirmed email address has been confirmed by another account' do - let(:user) { create(:user, :unconfirmed, reset_password_sent_at: Time.zone.now) } + context 'when the profile is pending in person verification' do + let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } + let!(:profile) { create(:profile, :in_person_verification_pending, user: user) } before do - create( - :user, - email_addresses: [create(:email_address, email: user.email_addresses.first.email)], - ) + @result = form.submit(params) + profile.reload end - it 'does not raise an error and is not successful' do - expect(result.success?).to eq(false) - expect(result.errors).to eq({ reset_password_token: ['token_expired'] }) + it 'returns a successful response' do + expect(@result.success?).to eq(true) end - end - - it_behaves_like 'strong password', 'ResetPasswordForm' - end - - context 'when pending in person password reset disabled' do - before do - allow(FeatureManagement).to receive( - :pending_in_person_password_reset_enabled?, - ).and_return(false) - end - context 'when the password is valid but the token has expired' do - before do - allow(user).to receive(:reset_password_period_valid?).and_return(false) - end - - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { reset_password_token: { token_expired: true } }, - user_id: '123', + it 'includes that the profile was not deactivated in the form response' do + expect(@result.extra).to include( + user_id: user.uuid, profile_deactivated: false, pending_profile_invalidated: false, - pending_profile_pending_reasons: '', + pending_profile_pending_reasons: 'in_person_verification_pending', ) end - end - - context 'when the password is invalid and token is valid' do - let(:password) { 'invalid' } - - before do - allow(user).to receive(:reset_password_period_valid?).and_return(true) - end - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { - password: { too_short: true }, - password_confirmation: { too_short: true }, - }, - user_id: '123', - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) + it 'updates the profile to have a "password reset" deactivation reason' do + expect(profile.deactivation_reason).to eq('password_reset') end end - context 'when both the password and token are valid' do + context 'when the profile is in fraud review for in person verification' do + let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } + let!(:enrollment) { create(:in_person_enrollment, :in_fraud_review, user: user) } + let(:profile) { enrollment.profile } + before do - allow(user).to receive(:reset_password_period_valid?).and_return(true) + @result = form.submit(params) + profile.reload end - it 'sets the user password to the submitted password' do - expect { result }.to change { user.reload.encrypted_password_digest } + it 'returns a successful response' do + expect(@result.success?).to eq(true) + end - expect(result.to_h).to eq( - success: true, - user_id: '123', + it 'includes that the profile was not deactivated in the form response' do + expect(@result.extra).to include( + user_id: user.uuid, profile_deactivated: false, pending_profile_invalidated: false, - pending_profile_pending_reasons: '', + pending_profile_pending_reasons: 'fraud_check_pending', ) end + + it 'updates the profile to have a "password reset" deactivation reason' do + expect(profile.deactivation_reason).to eq('password_reset') + end end - context 'when both the password and token are invalid' do - let(:password) { 'short' } + context 'when the user has an active and a pending in-person verification profile' do + let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } + let!(:pending_profile) { create(:profile, :in_person_verification_pending, user: user) } + let!(:active_profile) { create(:profile, :active, user: user) } before do - allow(user).to receive(:reset_password_period_valid?).and_return(false) + @result = form.submit(params) + pending_profile.reload + active_profile.reload end - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { - password: { too_short: true }, - password_confirmation: { too_short: true }, - reset_password_token: { token_expired: true }, - }, - user_id: '123', - profile_deactivated: false, - pending_profile_invalidated: false, - pending_profile_pending_reasons: '', - ) + it 'returns a successful response' do + expect(@result.success?).to eq(true) end - end - - context 'when the user does not exist in the db' do - let(:user) { User.new } - it 'returns a hash with errors' do - expect(result.to_h).to eq( - success: false, - error_details: { reset_password_token: { invalid_token: true } }, - user_id: nil, - profile_deactivated: false, + it 'includes that the profile was not deactivated in the form response' do + expect(@result.extra).to include( + user_id: user.uuid, + profile_deactivated: true, pending_profile_invalidated: false, pending_profile_pending_reasons: '', ) end - end - - context 'when the user has an active profile' do - let(:user) { create(:user, :proofed, reset_password_sent_at: Time.zone.now) } - it 'deactivates the profile' do - expect(result.success?).to eq(true) - expect(result.extra[:profile_deactivated]).to eq(true) - expect(user.profiles.any?(&:active?)).to eq(false) + it 'updates the pending profile to have a "password reset" deactivation reason' do + expect(pending_profile.deactivation_reason).to eq('password_reset') end - end - context 'when the user does not have an active profile' do - let(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - - it 'includes that the profile was not deactivated in the form response' do - expect(result.success?).to eq(true) - expect(result.extra[:profile_deactivated]).to eq(false) + it 'does not update the active profile to have a "password reset" deactivation reason' do + expect(active_profile.deactivation_reason).to be_nil end end + end - context 'when the user has a pending profile' do - context 'when the profile is pending gpo verification' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:profile) do - create(:profile, :verify_by_mail_pending, :in_person_verification_pending, user: user) - end - - before do - @result = form.submit(params) - profile.reload - end - - it 'includes that the profile was not deactivated in the form response' do - expect(result.success?).to eq(true) - expect(result.extra[:pending_profile_invalidated]).to eq(true) - expect(result.extra[:pending_profile_pending_reasons]).to eq( - 'gpo_verification_pending,in_person_verification_pending', - ) - end - end - - context 'when the profile is pending in person verification' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:profile) { create(:profile, :in_person_verification_pending, user: user) } - - before do - @result = form.submit(params) - profile.reload - end - - it 'returns a successful response' do - expect(@result.success?).to eq(true) - end - - it 'includes that the profile was not deactivated in the form response' do - expect(@result.extra).to include( - pending_profile_invalidated: true, - pending_profile_pending_reasons: 'in_person_verification_pending', - ) - end - - it 'does not update the profile to have a "password reset" deactivation reason' do - expect(profile.deactivation_reason).to be_nil - end - end + context 'when the user does not have a pending profile' do + let(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - context 'when the profile is in fraud review for in person verification' do - let!(:user) { create(:user, reset_password_sent_at: Time.zone.now) } - let!(:enrollment) { create(:in_person_enrollment, :in_fraud_review, user: user) } - let(:profile) { enrollment.profile } - - before do - @result = form.submit(params) - profile.reload - end - - it 'returns a successful response' do - expect(@result.success?).to eq(true) - end - - it 'includes that the profile was not deactivated in the form response' do - expect(@result.extra).to include( - user_id: user.uuid, - profile_deactivated: false, - pending_profile_invalidated: true, - pending_profile_pending_reasons: 'fraud_check_pending', - ) - end - - it 'does not update the profile to have a "password reset" deactivation reason' do - expect(profile.deactivation_reason).to be_nil - end - end + it 'includes that the profile was not deactivated in the form response' do + expect(result.success?).to eq(true) + expect(result.extra[:pending_profile_invalidated]).to eq(false) + expect(result.extra[:pending_profile_pending_reasons]).to eq('') end + end - context 'when the user does not have a pending profile' do - let(:user) { create(:user, reset_password_sent_at: Time.zone.now) } + context 'when the unconfirmed email address has been confirmed by another account' do + let(:user) { create(:user, :unconfirmed, reset_password_sent_at: Time.zone.now) } - it 'includes that the profile was not deactivated in the form response' do - expect(result.success?).to eq(true) - expect(result.extra[:pending_profile_invalidated]).to eq(false) - expect(result.extra[:pending_profile_pending_reasons]).to eq('') - end + before do + create( + :user, + email_addresses: [create(:email_address, email: user.email_addresses.first.email)], + ) end - context 'when the unconfirmed email address has been confirmed by another account' do - let(:user) { create(:user, :unconfirmed, reset_password_sent_at: Time.zone.now) } - - before do - create( - :user, - email_addresses: [create(:email_address, email: user.email_addresses.first.email)], - ) - end - - it 'does not raise an error and is not successful' do - expect(result.success?).to eq(false) - expect(result.errors).to eq({ reset_password_token: ['token_expired'] }) - end + it 'does not raise an error and is not successful' do + expect(result.success?).to eq(false) + expect(result.errors).to eq({ reset_password_token: ['token_expired'] }) end - - it_behaves_like 'strong password', 'ResetPasswordForm' end end end diff --git a/spec/lib/feature_management_spec.rb b/spec/lib/feature_management_spec.rb index f6d8e62149e..f5c88b2fe6c 100644 --- a/spec/lib/feature_management_spec.rb +++ b/spec/lib/feature_management_spec.rb @@ -537,30 +537,4 @@ end end end - - describe '#pending_in_person_password_reset_enabled?' do - context 'when feature_pending_in_person_password_enabled is true' do - before do - allow(IdentityConfig.store).to receive( - :feature_pending_in_person_password_reset_enabled, - ).and_return(true) - end - - it 'returns true' do - expect(FeatureManagement.pending_in_person_password_reset_enabled?).to be(true) - end - end - - context 'when feature_pending_in_person_password_enabled is false' do - before do - allow(IdentityConfig.store).to receive( - :feature_pending_in_person_password_reset_enabled, - ).and_return(false) - end - - it 'returns false' do - expect(FeatureManagement.pending_in_person_password_reset_enabled?).to be(false) - end - end - end end diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index f4ab34cf2af..7842c6c04f4 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -26,14 +26,6 @@ def reset_password_instructions_with_pending_gpo_letter ) end - def reset_password_instructions_with_pending_in_person_warning - UserMailer.with( - user: user_with_pending_in_person_profile, email_address: email_address_record, - ).reset_password_instructions( - token: SecureRandom.hex, request_id: SecureRandom.hex, - ) - end - def password_changed UserMailer.with(user: user, email_address: email_address_record) .password_changed(disavowal_token: SecureRandom.hex) @@ -318,19 +310,6 @@ def user_with_pending_gpo_letter raw_user end - def user_with_pending_in_person_profile - raw_user = user - in_person_pending_profile = unsaveable( - Profile.new( - user: raw_user, - active: false, - in_person_verification_pending_at: Time.zone.now, - ), - ) - raw_user.send(:instance_variable_set, :@pending_profile, in_person_pending_profile) - raw_user - end - def email_address 'email@example.com' end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 23f604d8b72..5bcaffbe3ba 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -148,14 +148,6 @@ ) end - it 'does not render the in person warning banner' do - expect(mail.html_part.body).not_to have_content( - strip_tags( - t('user_mailer.reset_password_instructions.in_person_warning_description_html'), - ), - ) - end - it 'renders the reset password instructions' do expect(mail.html_part.body).to have_content( t('user_mailer.reset_password_instructions.header'), @@ -185,36 +177,6 @@ expect(mail.subject).to eq t('user_mailer.reset_password_instructions.subject') end - context 'when feature_pending_in_person_password_reset_enabled flag is true' do - before do - allow(IdentityConfig.store).to receive(:feature_pending_in_person_password_reset_enabled) - .and_return(true) - end - - it 'does not render the in person warning banner' do - expect(mail.html_part.body).not_to have_content( - strip_tags( - t('user_mailer.reset_password_instructions.in_person_warning_description_html'), - ), - ) - end - end - - context 'when feature_pending_in_person_password_reset_enabled flag is false' do - before do - allow(IdentityConfig.store).to receive(:feature_pending_in_person_password_reset_enabled) - .and_return(false) - end - - it 'renders the in person warning banner' do - expect(mail.html_part.body).to have_content( - strip_tags( - t('user_mailer.reset_password_instructions.in_person_warning_description_html'), - ), - ) - end - end - it 'does not render the gpo warning alert' do expect(mail.html_part.body).not_to have_content( t('user_mailer.reset_password_instructions.gpo_letter_description'), @@ -254,14 +216,6 @@ ) end - it 'does not render the in person warning banner' do - expect(mail.html_part.body).not_to have_content( - strip_tags( - t('user_mailer.reset_password_instructions.in_person_warning_description_html'), - ), - ) - end - it 'renders the reset password instructions' do expect(mail.html_part.body).to have_content( t('user_mailer.reset_password_instructions.header'), diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7417fb9627e..5e5442d51cb 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1640,171 +1640,101 @@ def it_should_not_send_survey describe '#password_reset_profile' do let(:user) { create(:user) } - context 'when pending in-person password reset is enabled' do - before do - allow(FeatureManagement).to receive( - :pending_in_person_password_reset_enabled?, - ).and_return(true) - end + context 'with no profiles' do + it { expect(user.password_reset_profile).to be_nil } + end - context 'with no profiles' do - it { expect(user.password_reset_profile).to be_nil } + context 'with an active profile' do + let(:active_profile) do + build(:profile, :active, :verified, activated_at: 1.day.ago, pii: { first_name: 'Jane' }) end - context 'with an active profile' do - let(:active_profile) do - build(:profile, :active, :verified, activated_at: 1.day.ago, pii: { first_name: 'Jane' }) - end - - before do - user.profiles << [ - active_profile, - build(:profile, :verified, activated_at: 5.days.ago, pii: { first_name: 'Susan' }), - ] - end - - it { expect(user.password_reset_profile).to be_nil } - - context 'when the active profile is deactivated due to password reset' do - before { active_profile.deactivate(:password_reset) } - - it { expect(user.password_reset_profile).to eq(active_profile) } + before do + user.profiles << [ + active_profile, + build(:profile, :verified, activated_at: 5.days.ago, pii: { first_name: 'Susan' }), + ] + end - context 'with a previously-cancelled pending profile' do - before do - user.profiles << build(:profile, :verification_cancelled) - end + it { expect(user.password_reset_profile).to be_nil } - it { expect(user.password_reset_profile).to eq(active_profile) } - end - end - end + context 'when the active profile is deactivated due to password reset' do + before { active_profile.deactivate(:password_reset) } - context 'with a pending in person profile' do - let(:pending_in_person_enrollment) { create(:in_person_enrollment, :pending, user: user) } - let(:pending_profile) { pending_in_person_enrollment.profile } + it { expect(user.password_reset_profile).to eq(active_profile) } - context 'when the pending in person profile has a "password_reset deactivation reason"' do + context 'with a previously-cancelled pending profile' do before do - pending_profile.update!(deactivation_reason: 'password_reset') + user.profiles << build(:profile, :verification_cancelled) end - it 'returns the pending profile' do - expect(user.password_reset_profile).to eq(pending_profile) - end - end - - context 'when the pending in person profile does not have a deactivation reason' do - it 'returns nil' do - expect(user.password_reset_profile).to be_nil - end + it { expect(user.password_reset_profile).to eq(active_profile) } end end + end - context 'with a fraud review in person profile' do - let(:enrollment) { create(:in_person_enrollment, :in_fraud_review, user: user) } - let(:profile) { enrollment.profile } + context 'with a pending in person profile' do + let(:pending_in_person_enrollment) { create(:in_person_enrollment, :pending, user: user) } + let(:pending_profile) { pending_in_person_enrollment.profile } - context 'when the profile has a "password_reset deactivation reason"' do - before do - profile.update!(deactivation_reason: 'password_reset') - end - - it 'returns the profile' do - expect(user.password_reset_profile).to eq(profile) - end + context 'when the pending in person profile has a "password_reset deactivation reason"' do + before do + pending_profile.update!(deactivation_reason: 'password_reset') end - context 'when the profile does not have a deactivation reason' do - it 'returns nil' do - expect(user.password_reset_profile).to be_nil - end + it 'returns the pending profile' do + expect(user.password_reset_profile).to eq(pending_profile) end end - context 'with a pending in person and an active profile' do - let(:pending_in_person_enrollment) { create(:in_person_enrollment, :pending, user: user) } - let(:pending_profile) { pending_in_person_enrollment.profile } - let(:active_profile) do - create(:profile, :active, :verified, activated_at: 1.day.ago, pii: { first_name: 'Jane' }) + context 'when the pending in person profile does not have a deactivation reason' do + it 'returns nil' do + expect(user.password_reset_profile).to be_nil end + end + end - context 'when the pending in person profile has a "password_reset deactivation reason"' do - before do - pending_profile.update!(deactivation_reason: 'password_reset') - end + context 'with a fraud review in person profile' do + let(:enrollment) { create(:in_person_enrollment, :in_fraud_review, user: user) } + let(:profile) { enrollment.profile } - it 'returns the pending profile' do - expect(user.password_reset_profile).to eq(pending_profile) - end + context 'when the profile has a "password_reset deactivation reason"' do + before do + profile.update!(deactivation_reason: 'password_reset') end - context 'when the pending in person profile does not have a deactivation reason' do - it 'returns nil' do - expect(user.password_reset_profile).to be_nil - end + it 'returns the profile' do + expect(user.password_reset_profile).to eq(profile) end end - end - context 'when pending in-person password reset is disabled' do - before do - allow(FeatureManagement).to receive( - :pending_in_person_password_reset_enabled?, - ).and_return(false) + context 'when the profile does not have a deactivation reason' do + it 'returns nil' do + expect(user.password_reset_profile).to be_nil + end end + end - context 'with no profiles' do - it { expect(user.password_reset_profile).to be_nil } + context 'with a pending in person and an active profile' do + let(:pending_in_person_enrollment) { create(:in_person_enrollment, :pending, user: user) } + let(:pending_profile) { pending_in_person_enrollment.profile } + let(:active_profile) do + create(:profile, :active, :verified, activated_at: 1.day.ago, pii: { first_name: 'Jane' }) end - context 'with an active profile' do - let(:active_profile) do - build(:profile, :active, :verified, activated_at: 1.day.ago, pii: { first_name: 'Jane' }) - end - + context 'when the pending in person profile has a "password_reset deactivation reason"' do before do - user.profiles << [ - active_profile, - build(:profile, :verified, activated_at: 5.days.ago, pii: { first_name: 'Susan' }), - ] + pending_profile.update!(deactivation_reason: 'password_reset') end - it { expect(user.password_reset_profile).to be_nil } - - context 'when the active profile is deactivated due to password reset' do - before { active_profile.deactivate(:password_reset) } - - it { expect(user.password_reset_profile).to eq(active_profile) } - - context 'with a previously-cancelled pending profile' do - before do - user.profiles << build(:profile, :verification_cancelled) - end - - it { expect(user.password_reset_profile).to eq(active_profile) } - end + it 'returns the pending profile' do + expect(user.password_reset_profile).to eq(pending_profile) end end - context 'with a pending in person profile' do - let(:pending_in_person_enrollment) { create(:in_person_enrollment, :pending, user: user) } - let(:pending_profile) { pending_in_person_enrollment.profile } - - context 'when the pending in person profile has a "password_reset deactivation reason"' do - before do - pending_profile.update!(deactivation_reason: 'password_reset') - end - - it 'returns nil' do - expect(user.password_reset_profile).to be_nil - end - end - - context 'when the pending in person profile does not have a deactivation reason' do - it 'returns nil' do - expect(user.password_reset_profile).to be_nil - end + context 'when the pending in person profile does not have a deactivation reason' do + it 'returns nil' do + expect(user.password_reset_profile).to be_nil end end end