diff --git a/app/controllers/account_reset/request_controller.rb b/app/controllers/account_reset/request_controller.rb index 0eb7e428faa..3b16b6d6f7f 100644 --- a/app/controllers/account_reset/request_controller.rb +++ b/app/controllers/account_reset/request_controller.rb @@ -4,6 +4,7 @@ class RequestController < ApplicationController before_action :check_account_reset_enabled before_action :confirm_two_factor_enabled + before_action :confirm_user_not_verified def show; end @@ -21,6 +22,11 @@ def check_account_reset_enabled redirect_to root_url unless FeatureManagement.account_reset_enabled? end + def confirm_user_not_verified + # IAL2 users should not be able to reset account to comply with AAL2 reqs + redirect_to account_url if decorated_user.identity_verified? + end + def reset_session_with_email email = current_user.email sign_out diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index ae06a833f18..5e2cb40dd78 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -45,6 +45,11 @@ def options end end + def should_display_account_reset_or_cancel_link? + # IAL2 users should not be able to reset account to comply with AAL2 reqs + !current_user.decorate.identity_verified? + end + def account_reset_or_cancel_link account_reset_token_valid? ? account_reset_cancel_link : account_reset_link end diff --git a/app/services/account_reset_service.rb b/app/services/account_reset_service.rb index 43bc7d4f638..43e5fad94cb 100644 --- a/app/services/account_reset_service.rb +++ b/app/services/account_reset_service.rb @@ -58,7 +58,7 @@ def self.send_notifications_with_sql(users_sql) def self.reset_and_notify(arr) user = arr.user return false unless AccountResetService.new(user).grant_request - UserMailer.account_reset_granted(user, arr).deliver_later + UserMailer.account_reset_granted(user, arr.reload).deliver_later true end private_class_method :reset_and_notify diff --git a/app/views/two_factor_authentication/options/index.html.slim b/app/views/two_factor_authentication/options/index.html.slim index 75c6c1f3ed5..a035884faae 100644 --- a/app/views/two_factor_authentication/options/index.html.slim +++ b/app/views/two_factor_authentication/options/index.html.slim @@ -23,5 +23,6 @@ p.mt-tiny.mb3 = @presenter.info = f.button :submit, t('forms.buttons.continue') br -p = @presenter.account_reset_or_cancel_link +- if @presenter.should_display_account_reset_or_cancel_link? + p = @presenter.account_reset_or_cancel_link = render 'shared/cancel', link: destroy_user_session_path diff --git a/spec/features/account_reset/delete_account_spec.rb b/spec/features/account_reset/delete_account_spec.rb new file mode 100644 index 00000000000..e9635fdf13c --- /dev/null +++ b/spec/features/account_reset/delete_account_spec.rb @@ -0,0 +1,66 @@ +require 'rails_helper' + +describe 'Account Reset Request: Delete Account', email: true do + let(:user) { create(:user, :signed_up) } + + before do + TwilioService::Utils.telephony_service = FakeSms + end + + context 'as an LOA1 user' do + it 'allows the user to delete their account after 24 hours' do + signin(user.email, user.password) + click_link t('two_factor_authentication.login_options_link_text') + click_link t('devise.two_factor_authentication.account_reset.link') + click_button t('account_reset.request.yes_continue') + reset_email + + Timecop.travel(Time.zone.now + 2.days) do + AccountResetService.grant_tokens_and_send_notifications + open_last_email + click_email_link_matching(/delete_account\?token/) + + expect(page).to have_content(t('account_reset.delete_account.title')) + expect(page).to have_current_path(account_reset_delete_account_path) + + click_on t('account_reset.delete_account.delete_button') + + expect(page).to have_content( + strip_tags( + t( + 'account_reset.confirm_delete_account.info', + email: user.email, + link: t('account_reset.confirm_delete_account.link_text') + ) + ) + ) + expect(page).to have_current_path(account_reset_confirm_delete_account_path) + expect(User.where(id: user.id)).to be_empty + end + end + end + + context 'as an LOA3 user' do + let(:user) do + create( + :profile, + :active, + :verified, + pii: { first_name: 'John', ssn: '111223333' } + ).user + end + + it 'does not allow the user to delete their account from 2FA screen' do + signin(user.email, user.password) + click_link t('two_factor_authentication.login_options_link_text') + + # Account reset link should not be present + expect(page).to_not have_content(t('devise.two_factor_authentication.account_reset.link')) + + # Visiting account reset directly should redirect to 2FA + visit account_reset_request_path + + expect(page.current_path).to eq(login_two_factor_path(otp_delivery_preference: :sms)) + end + end +end