From fdb4d4049147644956432ee1c86fa2b9be5e11ad Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 27 Feb 2024 15:17:22 -0500 Subject: [PATCH 01/33] changelog: Upcoming Features, Account reset, Dont let account reset fraud users --- .../account_reset/pending_controller.rb | 12 +- .../account_reset/request_controller.rb | 12 +- .../concerns/account_reset_concern.rb | 27 +++ app/mailers/user_mailer.rb | 18 +- .../two_factor_login_options_presenter.rb | 16 +- .../grant_requests_and_send_emails.rb | 13 ++ config/application.yml.default | 1 + lib/identity_config.rb | 1 + .../grant_requests_and_send_emails_spec.rb | 158 ++++++++++++++---- 9 files changed, 199 insertions(+), 59 deletions(-) create mode 100644 app/controllers/concerns/account_reset_concern.rb diff --git a/app/controllers/account_reset/pending_controller.rb b/app/controllers/account_reset/pending_controller.rb index 855a6e12452..a906f704aba 100644 --- a/app/controllers/account_reset/pending_controller.rb +++ b/app/controllers/account_reset/pending_controller.rb @@ -1,6 +1,7 @@ module AccountReset class PendingController < ApplicationController include UserAuthenticator + include AccountResetConcern include ActionView::Helpers::DateHelper before_action :authenticate_user @@ -32,16 +33,5 @@ def pending_account_reset_request current_user, ).call end - - def account_reset_deletion_period_interval - current_time = Time.zone.now - - distance_of_time_in_words( - current_time, - current_time + IdentityConfig.store.account_reset_wait_period_days.days, - true, - accumulate_on: :hours, - ) - end end end diff --git a/app/controllers/account_reset/request_controller.rb b/app/controllers/account_reset/request_controller.rb index afc55e4df98..72073562c27 100644 --- a/app/controllers/account_reset/request_controller.rb +++ b/app/controllers/account_reset/request_controller.rb @@ -1,6 +1,7 @@ module AccountReset class RequestController < ApplicationController include TwoFactorAuthenticatable + include AccountResetConcern include ActionView::Helpers::DateHelper before_action :confirm_two_factor_enabled @@ -41,16 +42,5 @@ def analytics_attributes email_addresses: current_user.email_addresses.count, } end - - def account_reset_deletion_period_interval - current_time = Time.zone.now - - distance_of_time_in_words( - current_time, - current_time + IdentityConfig.store.account_reset_wait_period_days.days, - true, - accumulate_on: :hours, - ) - end end end diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb new file mode 100644 index 00000000000..6f87647a89a --- /dev/null +++ b/app/controllers/concerns/account_reset_concern.rb @@ -0,0 +1,27 @@ +module AccountResetConcern + def account_reset_deletion_period_interval + current_time = Time.zone.now + + distance_of_time_in_words( + current_time, + current_time + account_reset_wait_period_days, + true, + accumulate_on: :hours, + ) + end + + def account_reset_wait_period_days + if supports_fraud_account_reset? + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + else + IdentityConfig.store.account_reset_wait_period_days.days + end + end + + def supports_fraud_account_reset? + (current_user.fraud_review_pending? || + current_user.fraud_rejection?) && + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + end +end + \ No newline at end of file diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index d6be78e7d4d..c9e008f2950 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -461,14 +461,28 @@ def account_reset_deletion_period_interval distance_of_time_in_words( current_time, - current_time + IdentityConfig.store.account_reset_wait_period_days.days, + current_time + account_reset_wait_period_days, true, accumulate_on: :hours, ) end + def account_reset_wait_period_days + if supports_fraud_account_reset? + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + else + IdentityConfig.store.account_reset_wait_period_days.days + end + end + + def supports_fraud_account_reset? + (user.fraud_review_pending? || + user.fraud_rejection?) && + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + end + def account_reset_deletion_period_hours - IdentityConfig.store.account_reset_wait_period_days.days.in_hours.to_i + account_reset_wait_period_days.in_hours.to_i end def account_reset_token_valid_period diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index 0d9556a4168..2bcfea1c362 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -149,9 +149,23 @@ def account_reset_deletion_period_interval view.distance_of_time_in_words( current_time, - current_time + IdentityConfig.store.account_reset_wait_period_days.days, + current_time + account_reset_wait_period_days, true, accumulate_on: :hours, ) end + + def account_reset_wait_period_days + if supports_fraud_account_reset? + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + else + IdentityConfig.store.account_reset_wait_period_days.days + end + end + + def supports_fraud_account_reset? + (current_user.fraud_review_pending? || + current_user.fraud_rejection?) && + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + end end diff --git a/app/services/account_reset/grant_requests_and_send_emails.rb b/app/services/account_reset/grant_requests_and_send_emails.rb index 8e4f1fa1696..2ecd202146d 100644 --- a/app/services/account_reset/grant_requests_and_send_emails.rb +++ b/app/services/account_reset/grant_requests_and_send_emails.rb @@ -8,6 +8,7 @@ def perform(now) sql_query_for_users_eligible_to_delete_their_accounts, tvalue: now - IdentityConfig.store.account_reset_wait_period_days.days, ).order('requested_at ASC').each do |arr| + next if fraud_wait_period_not_met?(arr, now) notifications_sent += 1 if grant_request_and_send_email(arr) end @@ -48,5 +49,17 @@ def grant_request_and_send_email(arr) end true end + + def fraud_wait_period_not_met?(arr, now) + if (arr.user.fraud_review_pending? || + arr.user.fraud_rejection?) && + (fraud_wait_period_days > 0) + return arr.requested_at > (now - fraud_wait_period_days) + end + end + + def fraud_wait_period_days + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + end end end diff --git a/config/application.yml.default b/config/application.yml.default index 9b82d3281e7..0abf37f7ec9 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -24,6 +24,7 @@ all_redirect_uris_cache_duration_minutes: 2 allowed_ialmax_providers: '[]' allowed_verified_within_providers: '[]' account_reset_token_valid_for_days: 1 +account_reset_fraud_user_wait_period_days: 0 account_reset_wait_period_days: 1 account_suspended_support_code: EFGHI acuant_assure_id_password: '' diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 66cbe876517..be8dc16524e 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -108,6 +108,7 @@ def self.build_store(config_map) config.add(:aamva_verification_url) config.add(:account_reset_token_valid_for_days, type: :integer) config.add(:account_reset_wait_period_days, type: :integer) + config.add(:account_reset_fraud_user_wait_period_days, type: :integer) config.add(:account_suspended_support_code, type: :string) config.add(:acuant_assure_id_password) config.add(:acuant_assure_id_subscription_id) diff --git a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb index 54a8aab1093..e8c4f1c5eb0 100644 --- a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb +++ b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb @@ -10,62 +10,145 @@ let(:now) { Time.zone.now } context 'after waiting the full wait period' do - it 'does not send notifications when the notifications were already sent' do - before_waiting_the_full_wait_period(now) do - create_account_reset_request_for(user) + context 'standard user' do + it 'does not send notifications when the notifications were already sent' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + end + + AccountReset::GrantRequestsAndSendEmails.new.perform(now) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) end - AccountReset::GrantRequestsAndSendEmails.new.perform(now) - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(0) - end + it 'does not send notifications when the request was cancelled' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + cancel_request_for(user) + end - it 'does not send notifications when the request was cancelled' do - before_waiting_the_full_wait_period(now) do - create_account_reset_request_for(user) - cancel_request_for(user) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) end - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(0) - end + it 'sends notifications after a request is granted' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + end - it 'sends notifications after a request is granted' do - before_waiting_the_full_wait_period(now) do - create_account_reset_request_for(user) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + + expect(notifications_sent).to eq(1) end - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + it 'sends 2 notifications after 2 requests are granted' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(1) + expect(notifications_sent).to eq(2) + end end - it 'sends 2 notifications after 2 requests are granted' do - before_waiting_the_full_wait_period(now) do - create_account_reset_request_for(user) - create_account_reset_request_for(user2) + context 'possible fraud user' do + let(:user) { create(:user, :gpo_pending_with_fraud_review) } + let(:user2) { create(:user, :gpo_pending_with_fraud_rejection) } + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(10) + end + it 'does not send notifications when the notifications were already sent' do + before_waiting_the_full_fraud_wait_period(now) do + create_account_reset_request_for(user) + end + + AccountReset::GrantRequestsAndSendEmails.new.perform(now) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) end - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + it 'does not send notifications when the request was cancelled' do + before_waiting_the_full_fraud_wait_period(now) do + create_account_reset_request_for(user) + cancel_request_for(user) + end - expect(notifications_sent).to eq(2) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'sends notifications after a request is granted' do + before_waiting_the_full_fraud_wait_period(now) do + create_account_reset_request_for(user) + end + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + + expect(notifications_sent).to eq(1) + end + + it 'sends 2 notifications after 2 requests are granted' do + before_waiting_the_full_fraud_wait_period(now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + + expect(notifications_sent).to eq(2) + end end end context 'after not waiting the full wait period' do - it 'does not send notifications after a request' do - create_account_reset_request_for(user) + context 'standard user' do + it 'does not send notifications before a request wait period is done' do + create_account_reset_request_for(user) - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(0) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'does not send notifications when the request was cancelled' do + create_account_reset_request_for(user) + cancel_request_for(user) + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end end - it 'does not send notifications when the request was cancelled' do - create_account_reset_request_for(user) - cancel_request_for(user) + context 'possible fraud user' do + let(:user) { create(:user, :fraud_review_pending) } + let(:user2) { create(:user, :fraud_rejection) } + it 'does not send notifications before a request wait period is done' do + create_account_reset_request_for(user) + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'does not send notifications when the request was cancelled' do + create_account_reset_request_for(user) + cancel_request_for(user) - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(0) + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'should not send if its in between regular wait period and fraud wait period' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + + expect(notifications_sent).to eq(0) + end end end end @@ -76,4 +159,11 @@ def before_waiting_the_full_wait_period(now) yield end end + + def before_waiting_the_full_fraud_wait_period(now) + days = IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + travel_to(now - 1 - days) do + yield + end + end end From ae6f163ac3846fbd8e11068f649b551f5cc81f9f Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 27 Feb 2024 15:18:59 -0500 Subject: [PATCH 02/33] rubocop --- app/controllers/concerns/account_reset_concern.rb | 5 ++--- app/mailers/user_mailer.rb | 4 ++-- app/presenters/two_factor_login_options_presenter.rb | 4 ++-- .../account_reset/grant_requests_and_send_emails.rb | 8 ++++---- .../account_reset/grant_requests_and_send_emails_spec.rb | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index 6f87647a89a..0da10e996f1 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -19,9 +19,8 @@ def account_reset_wait_period_days end def supports_fraud_account_reset? - (current_user.fraud_review_pending? || - current_user.fraud_rejection?) && + (current_user.fraud_review_pending? || + current_user.fraud_rejection?) && (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) end end - \ No newline at end of file diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index c9e008f2950..0a9d0e2f74b 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -476,8 +476,8 @@ def account_reset_wait_period_days end def supports_fraud_account_reset? - (user.fraud_review_pending? || - user.fraud_rejection?) && + (user.fraud_review_pending? || + user.fraud_rejection?) && (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) end diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index 2bcfea1c362..b033972c63e 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -164,8 +164,8 @@ def account_reset_wait_period_days end def supports_fraud_account_reset? - (current_user.fraud_review_pending? || - current_user.fraud_rejection?) && + (current_user.fraud_review_pending? || + current_user.fraud_rejection?) && (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) end end diff --git a/app/services/account_reset/grant_requests_and_send_emails.rb b/app/services/account_reset/grant_requests_and_send_emails.rb index 2ecd202146d..a1a0ca86f26 100644 --- a/app/services/account_reset/grant_requests_and_send_emails.rb +++ b/app/services/account_reset/grant_requests_and_send_emails.rb @@ -51,15 +51,15 @@ def grant_request_and_send_email(arr) end def fraud_wait_period_not_met?(arr, now) - if (arr.user.fraud_review_pending? || - arr.user.fraud_rejection?) && - (fraud_wait_period_days > 0) + if (arr.user.fraud_review_pending? || + arr.user.fraud_rejection?) && + (fraud_wait_period_days > 0) return arr.requested_at > (now - fraud_wait_period_days) end end def fraud_wait_period_days - IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days end end end diff --git a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb index e8c4f1c5eb0..ab665d1ced0 100644 --- a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb +++ b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb @@ -104,7 +104,7 @@ end context 'after not waiting the full wait period' do - context 'standard user' do + context 'standard user' do it 'does not send notifications before a request wait period is done' do create_account_reset_request_for(user) @@ -121,7 +121,7 @@ end end - context 'possible fraud user' do + context 'possible fraud user' do let(:user) { create(:user, :fraud_review_pending) } let(:user2) { create(:user, :fraud_rejection) } it 'does not send notifications before a request wait period is done' do From f5b0910faf8cb9be1b17b9bbcc1bf4781518c5d1 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 28 Feb 2024 10:37:32 -0500 Subject: [PATCH 03/33] login options presenter --- app/presenters/two_factor_login_options_presenter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index b033972c63e..48a94f1e7cd 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -164,8 +164,8 @@ def account_reset_wait_period_days end def supports_fraud_account_reset? - (current_user.fraud_review_pending? || - current_user.fraud_rejection?) && + (user.fraud_review_pending? || + user.fraud_rejection?) && (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) end end From c495263ca5e7275897c52cb1ef0d6a8bed408927 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Thu, 29 Feb 2024 12:11:10 -0500 Subject: [PATCH 04/33] pending controller specs --- config/application.yml.default | 1 + .../account_reset/pending_controller_spec.rb | 41 +++++++++++++++++++ .../account_reset/request_controller_spec.rb | 36 ++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/config/application.yml.default b/config/application.yml.default index 857e6cf0747..44cbd680bc9 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -511,6 +511,7 @@ production: test: aamva_private_key: 123abc aamva_public_key: 123abc + account_reset_fraud_user_wait_period_days: 30 acuant_assure_id_url: https://example.com acuant_facial_match_url: https://facial_match.example.com acuant_passlive_url: https://liveness.example.com diff --git a/spec/controllers/account_reset/pending_controller_spec.rb b/spec/controllers/account_reset/pending_controller_spec.rb index 3348bb4cf70..5b5cfd03e97 100644 --- a/spec/controllers/account_reset/pending_controller_spec.rb +++ b/spec/controllers/account_reset/pending_controller_spec.rb @@ -1,6 +1,8 @@ require 'rails_helper' RSpec.describe AccountReset::PendingController do + include ActionView::Helpers::DateHelper + include AccountResetHelper let(:user) { create(:user) } before do @@ -17,6 +19,45 @@ end end + describe '#confirm' do + before do + end + context 'non-fraud user' do + it 'should have @account_reset_deletion_period_interval to match regular wait period' do + create_account_reset_request_for(user) + + get :confirm + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(controller.view_assigns['account_reset_deletion_period_interval']). + to eq(time_in_hours) + end + end + + context 'fraud user' do + let(:user) { create(:user, :fraud_review_pending) } + it 'should have @account_reset_deletion_period_interval to match fraud wait period' do + create_account_reset_request_for(user) + + get :confirm + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(controller.view_assigns['account_reset_deletion_period_interval']). + to eq(time_in_hours) + end + end + end + describe '#cancel' do it 'cancels the account reset request and logs the cancellation event' do stub_attempts_tracker diff --git a/spec/controllers/account_reset/request_controller_spec.rb b/spec/controllers/account_reset/request_controller_spec.rb index 09c7484d905..13486a38b09 100644 --- a/spec/controllers/account_reset/request_controller_spec.rb +++ b/spec/controllers/account_reset/request_controller_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' RSpec.describe AccountReset::RequestController, allowed_extra_analytics: [:*] do + include ActionView::Helpers::DateHelper let(:user) { create(:user, :with_authentication_app) } describe '#show' do it 'renders the page' do @@ -32,6 +33,41 @@ get :show end + + context 'non-fraud user' do + it 'should have @account_reset_deletion_period_interval to match regular wait period' do + stub_sign_in_before_2fa(user) + + get :show + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(controller.view_assigns['account_reset_deletion_period_interval']). + to eq(time_in_hours) + end + end + + context 'fraud user' do + let(:user) { create(:user, :fraud_review_pending) } + it 'should have @account_reset_deletion_period_interval to match fraud wait period' do + stub_sign_in_before_2fa(user) + + get :show + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(controller.view_assigns['account_reset_deletion_period_interval']). + to eq(time_in_hours) + end + end end describe '#create' do From b5765c5e6cc73cf281c0f6673664ee27445c1bff Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Thu, 29 Feb 2024 15:37:40 -0500 Subject: [PATCH 05/33] Account Reset spec --- .../account_reset/pending_controller.rb | 1 - .../account_reset/request_controller.rb | 1 - .../concerns/account_reset_concern.rb | 1 + .../concerns/account_reset_concern_spec.rb | 49 +++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 spec/controllers/concerns/account_reset_concern_spec.rb diff --git a/app/controllers/account_reset/pending_controller.rb b/app/controllers/account_reset/pending_controller.rb index a906f704aba..88ea7b50f30 100644 --- a/app/controllers/account_reset/pending_controller.rb +++ b/app/controllers/account_reset/pending_controller.rb @@ -2,7 +2,6 @@ module AccountReset class PendingController < ApplicationController include UserAuthenticator include AccountResetConcern - include ActionView::Helpers::DateHelper before_action :authenticate_user before_action :confirm_account_reset_request_exists diff --git a/app/controllers/account_reset/request_controller.rb b/app/controllers/account_reset/request_controller.rb index 72073562c27..48ba34427f5 100644 --- a/app/controllers/account_reset/request_controller.rb +++ b/app/controllers/account_reset/request_controller.rb @@ -2,7 +2,6 @@ module AccountReset class RequestController < ApplicationController include TwoFactorAuthenticatable include AccountResetConcern - include ActionView::Helpers::DateHelper before_action :confirm_two_factor_enabled diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index 0da10e996f1..22d3d8df66b 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -1,4 +1,5 @@ module AccountResetConcern + include ActionView::Helpers::DateHelper def account_reset_deletion_period_interval current_time = Time.zone.now diff --git a/spec/controllers/concerns/account_reset_concern_spec.rb b/spec/controllers/concerns/account_reset_concern_spec.rb new file mode 100644 index 00000000000..d01d497e140 --- /dev/null +++ b/spec/controllers/concerns/account_reset_concern_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +RSpec.describe AccountResetConcern do + include ActionView::Helpers::DateHelper + let(:test_class) do + Class.new do + include AccountResetConcern + + attr_reader :current_user + + def initialize(current_user:) + @current_user = current_user + end + end + end + let(:user) { build(:user) } + let(:instance) { test_class.new(current_user: user) } + + describe '#account_reset_deletion_period_interval' do + context 'non fraud user' do + it 'should return regular wait time' do + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(instance.account_reset_deletion_period_interval). + to eq(time_in_hours) + end + end + + context 'fraud user' do + let(:user) { create(:user, :fraud_review_pending) } + it 'should return regular wait time' do + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(instance.account_reset_deletion_period_interval). + to eq(time_in_hours) + end + end + end +end From d30a086713106074ca657a9a91a0827e5558337d Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Thu, 29 Feb 2024 15:58:55 -0500 Subject: [PATCH 06/33] update pending specs --- app/controllers/concerns/account_reset_concern.rb | 10 +++++++++- .../account_reset/pending_controller_spec.rb | 2 +- .../account_reset/request_controller_spec.rb | 2 +- .../controllers/concerns/account_reset_concern_spec.rb | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index 22d3d8df66b..a9555b67915 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -7,7 +7,7 @@ def account_reset_deletion_period_interval current_time, current_time + account_reset_wait_period_days, true, - accumulate_on: :hours, + accumulate_on: reset_accumulation_type, ) end @@ -24,4 +24,12 @@ def supports_fraud_account_reset? current_user.fraud_rejection?) && (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) end + + def reset_accumulation_type + if supports_fraud_account_reset? + :days + else + :hours + end + end end diff --git a/spec/controllers/account_reset/pending_controller_spec.rb b/spec/controllers/account_reset/pending_controller_spec.rb index 5b5cfd03e97..b143043ab9a 100644 --- a/spec/controllers/account_reset/pending_controller_spec.rb +++ b/spec/controllers/account_reset/pending_controller_spec.rb @@ -50,7 +50,7 @@ current_time, current_time + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days, true, - accumulate_on: :hours, + accumulate_on: :days, ) expect(controller.view_assigns['account_reset_deletion_period_interval']). to eq(time_in_hours) diff --git a/spec/controllers/account_reset/request_controller_spec.rb b/spec/controllers/account_reset/request_controller_spec.rb index 13486a38b09..71f9e03ba5f 100644 --- a/spec/controllers/account_reset/request_controller_spec.rb +++ b/spec/controllers/account_reset/request_controller_spec.rb @@ -62,7 +62,7 @@ current_time, current_time + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days, true, - accumulate_on: :hours, + accumulate_on: :days, ) expect(controller.view_assigns['account_reset_deletion_period_interval']). to eq(time_in_hours) diff --git a/spec/controllers/concerns/account_reset_concern_spec.rb b/spec/controllers/concerns/account_reset_concern_spec.rb index d01d497e140..959d85eb6e5 100644 --- a/spec/controllers/concerns/account_reset_concern_spec.rb +++ b/spec/controllers/concerns/account_reset_concern_spec.rb @@ -39,7 +39,7 @@ def initialize(current_user:) current_time, current_time + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days, true, - accumulate_on: :hours, + accumulate_on: :days, ) expect(instance.account_reset_deletion_period_interval). to eq(time_in_hours) From 8e709a458c7f46499dbb0c323e521629d5532037 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 4 Mar 2024 12:45:46 -0500 Subject: [PATCH 07/33] LG-11784: users will see over again --- app/mailers/user_mailer.rb | 18 +++++---- .../account_reset/pending_presenter.rb | 39 +++++++++++++++++-- app/views/account_reset/pending/show.html.erb | 2 +- .../account_reset_granted.html.erb | 2 +- .../account_reset_request.html.erb | 2 +- config/locales/account_reset/en.yml | 2 +- config/locales/account_reset/es.yml | 2 +- config/locales/account_reset/fr.yml | 2 +- config/locales/user_mailer/en.yml | 6 +-- config/locales/user_mailer/es.yml | 6 +-- config/locales/user_mailer/fr.yml | 6 +-- spec/mailers/user_mailer_spec.rb | 4 +- 12 files changed, 64 insertions(+), 27 deletions(-) diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 3c7c6162cad..59af4252211 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -144,7 +144,7 @@ def personal_key_regenerated def account_reset_request(account_reset) with_user_locale(user) do @token = account_reset&.request_token - @account_reset_deletion_period_hours = account_reset_deletion_period_hours + @account_reset_deletion_period_interval = account_reset_deletion_period_interval @header = t( 'user_mailer.account_reset_request.header', interval: account_reset_deletion_period_interval, @@ -160,7 +160,7 @@ def account_reset_granted(account_reset) with_user_locale(user) do @token = account_reset&.request_token @granted_token = account_reset&.granted_token - @account_reset_deletion_period_hours = account_reset_deletion_period_hours + @account_reset_deletion_period_interval = account_reset_deletion_period_interval @account_reset_token_valid_period = account_reset_token_valid_period mail( to: email_address.email, @@ -438,7 +438,7 @@ def account_reset_deletion_period_interval current_time, current_time + account_reset_wait_period_days, true, - accumulate_on: :hours, + accumulate_on: reset_accumulation_type, ) end @@ -456,10 +456,6 @@ def supports_fraud_account_reset? (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) end - def account_reset_deletion_period_hours - account_reset_wait_period_days.in_hours.to_i - end - def account_reset_token_valid_period current_time = Time.zone.now @@ -470,4 +466,12 @@ def account_reset_token_valid_period accumulate_on: :hours, ) end + + def reset_accumulation_type + if supports_fraud_account_reset? + :days + else + :hours + end + end end diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index 636b7bcd081..ca781f24ee3 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -9,7 +9,7 @@ def initialize(account_reset_request) end def time_remaining_until_granted(now: Time.zone.now) - wait_time = IdentityConfig.store.account_reset_wait_period_days.days + wait_time = account_reset_wait_period_days distance_of_time_in_words( now, @@ -19,8 +19,41 @@ def time_remaining_until_granted(now: Time.zone.now) ) end - def account_reset_deletion_period_hours - IdentityConfig.store.account_reset_wait_period_days.days.in_hours.to_i + def account_reset_deletion_period + current_time = Time.zone.now + + distance_of_time_in_words( + current_time, + current_time + account_reset_wait_period_days, + true, + accumulate_on: reset_accumulation_type, + ) + end + + def account_reset_wait_period_days + if supports_fraud_account_reset? + IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + else + IdentityConfig.store.account_reset_wait_period_days.days + end + end + + def supports_fraud_account_reset? + (account_reset_request_user.fraud_review_pending? || + account_reset_request_user.fraud_rejection?) && + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + end + + def account_reset_request_user + account_reset_request.user + end + + def reset_accumulation_type + if supports_fraud_account_reset? + :days + else + :hours + end end end end diff --git a/app/views/account_reset/pending/show.html.erb b/app/views/account_reset/pending/show.html.erb index ceb730fe1fc..970283d4574 100644 --- a/app/views/account_reset/pending/show.html.erb +++ b/app/views/account_reset/pending/show.html.erb @@ -5,7 +5,7 @@

<%= t( 'account_reset.pending.wait_html', - hours: @pending_presenter.account_reset_deletion_period_hours, + waiting_period: @pending_presenter.account_reset_deletion_period, interval: @pending_presenter.time_remaining_until_granted, ) %>

diff --git a/app/views/user_mailer/account_reset_granted.html.erb b/app/views/user_mailer/account_reset_granted.html.erb index 70d608be1d9..4da0fcc5ec8 100644 --- a/app/views/user_mailer/account_reset_granted.html.erb +++ b/app/views/user_mailer/account_reset_granted.html.erb @@ -1,5 +1,5 @@

- <%= t('user_mailer.account_reset_granted.intro_html', hours: @account_reset_deletion_period_hours, app_name: link_to(APP_NAME, IdentityConfig.store.mailer_domain_name, class: 'gray')) %> + <%= t('user_mailer.account_reset_granted.intro_html', waiting_period: @account_reset_deletion_period_interval, app_name: link_to(APP_NAME, IdentityConfig.store.mailer_domain_name, class: 'gray')) %>

diff --git a/app/views/user_mailer/account_reset_request.html.erb b/app/views/user_mailer/account_reset_request.html.erb index d486d654efc..932fcfad3a5 100644 --- a/app/views/user_mailer/account_reset_request.html.erb +++ b/app/views/user_mailer/account_reset_request.html.erb @@ -1,5 +1,5 @@

- <%= t('user_mailer.account_reset_request.intro_html', app_name: link_to(APP_NAME, IdentityConfig.store.mailer_domain_name, class: 'gray'), hours: @account_reset_deletion_period_hours) %> + <%= t('user_mailer.account_reset_request.intro_html', app_name: link_to(APP_NAME, IdentityConfig.store.mailer_domain_name, class: 'gray'), waiting_period: @account_reset_deletion_period_interval) %>

diff --git a/config/locales/account_reset/en.yml b/config/locales/account_reset/en.yml index f3fe9cf0d60..9457421914c 100644 --- a/config/locales/account_reset/en.yml +++ b/config/locales/account_reset/en.yml @@ -33,7 +33,7 @@ en: confirm: If you cancel now, you must create a new request and wait another %{interval} to delete your account. header: You requested to delete your account - wait_html: There is a %{hours}-hour waiting period to delete your account. In + wait_html: There is a %{waiting_period} waiting period to delete your account. In %{interval}, you will receive an email with instructions to complete the deletion. recovery_options: diff --git a/config/locales/account_reset/es.yml b/config/locales/account_reset/es.yml index 9f8f1dc4317..8a626b531e3 100644 --- a/config/locales/account_reset/es.yml +++ b/config/locales/account_reset/es.yml @@ -34,7 +34,7 @@ es: confirm: Si cancela ahora, debe crear una nueva solicitud y esperar otras %{interval} para eliminar su cuenta. header: Solicitaste eliminar tu cuenta - wait_html: Hay un período de espera de %{hours} horas para eliminar su cuenta. + wait_html: Hay un período de espera de %{hours} para eliminar su cuenta. En %{interval}, recibirá un correo electrónico con instrucciones para completar la eliminación. recovery_options: diff --git a/config/locales/account_reset/fr.yml b/config/locales/account_reset/fr.yml index cd52a50fa08..d26da9260c3 100644 --- a/config/locales/account_reset/fr.yml +++ b/config/locales/account_reset/fr.yml @@ -34,7 +34,7 @@ fr: confirm: Si vous annulez maintenant, vous devez créer une nouvelle demande et attendre encore %{interval} pour supprimer votre compte. header: Vous avez demandé de supprimer votre compte - wait_html: Il y a un délai d’attente de %{hours} heures pour supprimer votre + wait_html: Il y a un délai d’attente de %{hours} pour supprimer votre compte. Dans %{interval}, vous recevrez un e-mail avec des instructions pour terminer la suppression. recovery_options: diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index 430d6552c71..eb396e37b34 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -20,7 +20,7 @@ en: button: Yes, continue deleting cancel_link_text: please cancel help_html: If you don’t want to delete your account, %{cancel_account_reset_html}. - intro_html: Your %{hours} hour waiting period has ended. Please complete step 2 + intro_html: Your %{waiting_period} waiting period has ended. Please complete step 2 of the process.

If you’ve been unable to locate your authentication methods, select “confirm deletion” to delete your %{app_name} account.

In the future, if you need to access @@ -33,11 +33,11 @@ en: to cancel. header: Your account will be deleted in %{interval} intro_html: 'As a security measure, %{app_name} requires a two-step process to - delete your account:

Step One: There is a %{hours} hour waiting + delete your account:

Step One: There is a %{waiting_period} waiting period if you have lost access to your authentication methods and need to delete your account. If you locate your authentication methods, you can sign in to your %{app_name} account to cancel this request.

- Step Two: After your %{hours} hour waiting period, you will receive an + Step Two: After your %{waiting_period} waiting period, you will receive an email that will ask you to confirm the deletion of your %{app_name} account. Your account will not be deleted until you confirm.' subject: How to delete your %{app_name} account diff --git a/config/locales/user_mailer/es.yml b/config/locales/user_mailer/es.yml index e71f33c9287..da81bad3c9f 100644 --- a/config/locales/user_mailer/es.yml +++ b/config/locales/user_mailer/es.yml @@ -22,7 +22,7 @@ es: button: Sí, continúa eliminando cancel_link_text: por favor cancele help_html: Si no desea eliminar su cuenta, %{cancel_account_reset_html}. - intro_html: Su período de espera de %{hours} horas ha finalizado. Complete el + intro_html: Su período de espera de %{waiting_period} ha finalizado. Complete el paso 2 del proceso.

Si no ha podido localizar sus métodos de autenticación, seleccione “confirmar eliminación” para eliminar su cuenta de %{app_name}.

En el futuro, si necesita acceder a los @@ -36,11 +36,11 @@ es: header: Su cuenta será eliminada en %{interval} intro_html: 'Como medida de seguridad, %{app_name} requiere un proceso de dos pasos para eliminar su cuenta:

Paso uno: hay un período de - espera de %{hours} horas si ha perdido el acceso a sus métodos de + espera de %{waiting_period} si ha perdido el acceso a sus métodos de autenticación y necesita eliminar su cuenta. Si encuentra sus métodos de autenticación, puede iniciar sesión en su cuenta %{app_name} para cancelar esta solicitud.

Paso dos: Después de su período de - espera de %{hours} horas, recibirá un correo electrónico que le pedirá + espera de %{waiting_period}, recibirá un correo electrónico que le pedirá que confirme la eliminación de su cuenta %{app_name}. Su cuenta no se eliminará hasta que confirme.' subject: Cómo eliminar su cuenta de %{app_name} diff --git a/config/locales/user_mailer/fr.yml b/config/locales/user_mailer/fr.yml index cf220fa3213..0c8efc64195 100644 --- a/config/locales/user_mailer/fr.yml +++ b/config/locales/user_mailer/fr.yml @@ -22,7 +22,7 @@ fr: cancel_link_text: veuillez annuler help_html: Si vous ne souhaitez pas supprimer votre compte, %{cancel_account_reset_html}. - intro_html: Votre période d’attente de %{hours} heures est terminée. Veuillez + intro_html: Votre période d’attente de %{waiting_period} est terminée. Veuillez terminer l’étape 2 du processus.

Si vous ne parvenez pas à localiser vos méthodes d’authentification, sélectionnez “confirmer la suppression” pour supprimer votre compte %{app_name}.

À @@ -37,11 +37,11 @@ fr: header: Votre compte sera supprimé dans %{interval} intro_html: 'Par mesure de sécurité, %{app_name} nécessite un processus en deux étapes pour supprimer votre compte:

Étape 1: Il y a une - période d’attente de %{hours} heures si vous avez perdu l’accès à vos + période d’attente de %{waiting_period} si vous avez perdu l’accès à vos méthodes d’authentification et devez supprimer votre compte. Si vous trouvez vos méthodes d’authentification, vous pouvez vous connecter à votre compte %{app_name} pour annuler cette demande.

Deuxième - étape: après votre période d’attente de %{hours} heures, vous recevrez + étape: après votre période d’attente de %{waiting_period}, vous recevrez un e-mail qui vous demandera de confirmer la suppression de votre compte %{app_name}. Votre compte ne sera pas supprimé tant que vous ne l’aurez pas confirmé.' diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 20d86af472f..4d28e11ce50 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -323,7 +323,7 @@ def expect_email_body_to_have_help_and_contact_links t( 'user_mailer.account_reset_request.intro_html', app_name: APP_NAME, interval: interval, - hours: + waiting_period: account_reset_deletion_period_hours ), ), @@ -377,7 +377,7 @@ def expect_email_body_to_have_help_and_contact_links strip_tags( t( 'user_mailer.account_reset_granted.intro_html', app_name: APP_NAME, - hours: + waiting_period: account_reset_deletion_period_hours ), ), From 5450aa3c03ca3f41401bef291441cbbefa9cacae Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 4 Mar 2024 15:03:22 -0500 Subject: [PATCH 08/33] fix spec --- config/locales/account_reset/en.yml | 4 ++-- config/locales/account_reset/es.yml | 4 ++-- config/locales/account_reset/fr.yml | 6 +++--- config/locales/user_mailer/en.yml | 19 ++++++++++--------- config/locales/user_mailer/es.yml | 6 +++--- spec/mailers/user_mailer_spec.rb | 4 ++-- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/config/locales/account_reset/en.yml b/config/locales/account_reset/en.yml index 9457421914c..0dfd2c8f76b 100644 --- a/config/locales/account_reset/en.yml +++ b/config/locales/account_reset/en.yml @@ -33,8 +33,8 @@ en: confirm: If you cancel now, you must create a new request and wait another %{interval} to delete your account. header: You requested to delete your account - wait_html: There is a %{waiting_period} waiting period to delete your account. In - %{interval}, you will receive an email with + wait_html: There is a %{waiting_period} waiting period to delete your account. + In %{interval}, you will receive an email with instructions to complete the deletion. recovery_options: check_saved_credential: See if you have a saved credential diff --git a/config/locales/account_reset/es.yml b/config/locales/account_reset/es.yml index 8a626b531e3..15fe280bd82 100644 --- a/config/locales/account_reset/es.yml +++ b/config/locales/account_reset/es.yml @@ -34,8 +34,8 @@ es: confirm: Si cancela ahora, debe crear una nueva solicitud y esperar otras %{interval} para eliminar su cuenta. header: Solicitaste eliminar tu cuenta - wait_html: Hay un período de espera de %{hours} para eliminar su cuenta. - En %{interval}, recibirá un correo electrónico con + wait_html: Hay un período de espera de %{hours} para eliminar su cuenta. En + %{interval}, recibirá un correo electrónico con instrucciones para completar la eliminación. recovery_options: check_saved_credential: Verifica si tienes una credencial almacenada diff --git a/config/locales/account_reset/fr.yml b/config/locales/account_reset/fr.yml index d26da9260c3..bd81d5a4a25 100644 --- a/config/locales/account_reset/fr.yml +++ b/config/locales/account_reset/fr.yml @@ -34,9 +34,9 @@ fr: confirm: Si vous annulez maintenant, vous devez créer une nouvelle demande et attendre encore %{interval} pour supprimer votre compte. header: Vous avez demandé de supprimer votre compte - wait_html: Il y a un délai d’attente de %{hours} pour supprimer votre - compte. Dans %{interval}, vous recevrez un e-mail avec - des instructions pour terminer la suppression. + wait_html: Il y a un délai d’attente de %{hours} pour supprimer votre compte. + Dans %{interval}, vous recevrez un e-mail avec des + instructions pour terminer la suppression. recovery_options: check_saved_credential: Vérifiez si vous avez des informations d’identification sauvegardées check_webauthn_platform_info: Si vous avez configuré le déverrouillage facial ou diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index eb396e37b34..91df158260b 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -20,8 +20,8 @@ en: button: Yes, continue deleting cancel_link_text: please cancel help_html: If you don’t want to delete your account, %{cancel_account_reset_html}. - intro_html: Your %{waiting_period} waiting period has ended. Please complete step 2 - of the process.

If you’ve been unable to locate your + intro_html: Your %{waiting_period} waiting period has ended. Please complete + step 2 of the process.

If you’ve been unable to locate your authentication methods, select “confirm deletion” to delete your %{app_name} account.

In the future, if you need to access participating government websites who use %{app_name}, you can create a @@ -33,13 +33,14 @@ en: to cancel. header: Your account will be deleted in %{interval} intro_html: 'As a security measure, %{app_name} requires a two-step process to - delete your account:

Step One: There is a %{waiting_period} waiting - period if you have lost access to your authentication methods and need - to delete your account. If you locate your authentication methods, you - can sign in to your %{app_name} account to cancel this request.

- Step Two: After your %{waiting_period} waiting period, you will receive an - email that will ask you to confirm the deletion of your %{app_name} - account. Your account will not be deleted until you confirm.' + delete your account:

Step One: There is a %{waiting_period} + waiting period if you have lost access to your authentication methods + and need to delete your account. If you locate your authentication + methods, you can sign in to your %{app_name} account to cancel this + request.

Step Two: After your %{waiting_period} waiting period, + you will receive an email that will ask you to confirm the deletion of + your %{app_name} account. Your account will not be deleted until you + confirm.' subject: How to delete your %{app_name} account account_verified: change_password_link: change your password diff --git a/config/locales/user_mailer/es.yml b/config/locales/user_mailer/es.yml index da81bad3c9f..e817c6363d9 100644 --- a/config/locales/user_mailer/es.yml +++ b/config/locales/user_mailer/es.yml @@ -40,9 +40,9 @@ es: autenticación y necesita eliminar su cuenta. Si encuentra sus métodos de autenticación, puede iniciar sesión en su cuenta %{app_name} para cancelar esta solicitud.

Paso dos: Después de su período de - espera de %{waiting_period}, recibirá un correo electrónico que le pedirá - que confirme la eliminación de su cuenta %{app_name}. Su cuenta no se - eliminará hasta que confirme.' + espera de %{waiting_period}, recibirá un correo electrónico que le + pedirá que confirme la eliminación de su cuenta %{app_name}. Su cuenta + no se eliminará hasta que confirme.' subject: Cómo eliminar su cuenta de %{app_name} account_verified: change_password_link: cambiar tu contraseña diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 4d28e11ce50..aaac96febaf 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -304,7 +304,7 @@ def expect_email_body_to_have_help_and_contact_links let(:account_reset) { user.account_reset_request } let(:interval) { '24 hours' } - let(:account_reset_deletion_period_hours) { 24 } + let(:account_reset_deletion_period_hours) { '24 hours' } it_behaves_like 'a system email' it_behaves_like 'an email that respects user email locale preference' @@ -355,7 +355,7 @@ def expect_email_body_to_have_help_and_contact_links UserMailer.with(user: user, email_address: email_address). account_reset_granted(user.account_reset_request) end - let(:account_reset_deletion_period_hours) { 24 } + let(:account_reset_deletion_period_hours) { '24 hours' } let(:token_expiration_interval) { '24 hours' } it_behaves_like 'a system email' From 7c9cf4e3af3e8502acaa2e192ef4fa26ac07e0c4 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 4 Mar 2024 15:24:58 -0500 Subject: [PATCH 09/33] spanish and french --- config/locales/account_reset/es.yml | 2 +- config/locales/account_reset/fr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/account_reset/es.yml b/config/locales/account_reset/es.yml index 15fe280bd82..a16e75c9ce5 100644 --- a/config/locales/account_reset/es.yml +++ b/config/locales/account_reset/es.yml @@ -34,7 +34,7 @@ es: confirm: Si cancela ahora, debe crear una nueva solicitud y esperar otras %{interval} para eliminar su cuenta. header: Solicitaste eliminar tu cuenta - wait_html: Hay un período de espera de %{hours} para eliminar su cuenta. En + wait_html: Hay un período de espera de %{waiting_period} para eliminar su cuenta. En %{interval}, recibirá un correo electrónico con instrucciones para completar la eliminación. recovery_options: diff --git a/config/locales/account_reset/fr.yml b/config/locales/account_reset/fr.yml index bd81d5a4a25..9506cab659a 100644 --- a/config/locales/account_reset/fr.yml +++ b/config/locales/account_reset/fr.yml @@ -34,7 +34,7 @@ fr: confirm: Si vous annulez maintenant, vous devez créer une nouvelle demande et attendre encore %{interval} pour supprimer votre compte. header: Vous avez demandé de supprimer votre compte - wait_html: Il y a un délai d’attente de %{hours} pour supprimer votre compte. + wait_html: Il y a un délai d’attente de %{waiting_period} pour supprimer votre compte. Dans %{interval}, vous recevrez un e-mail avec des instructions pour terminer la suppression. recovery_options: From b94920f495cf594a91b97b6cfee2c366da06d341 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 08:45:53 -0500 Subject: [PATCH 10/33] normalize_yaml --- config/locales/account_reset/es.yml | 6 +++--- config/locales/account_reset/fr.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/account_reset/es.yml b/config/locales/account_reset/es.yml index a16e75c9ce5..3cd6eb93a1d 100644 --- a/config/locales/account_reset/es.yml +++ b/config/locales/account_reset/es.yml @@ -34,9 +34,9 @@ es: confirm: Si cancela ahora, debe crear una nueva solicitud y esperar otras %{interval} para eliminar su cuenta. header: Solicitaste eliminar tu cuenta - wait_html: Hay un período de espera de %{waiting_period} para eliminar su cuenta. En - %{interval}, recibirá un correo electrónico con - instrucciones para completar la eliminación. + wait_html: Hay un período de espera de %{waiting_period} para eliminar su + cuenta. En %{interval}, recibirá un correo electrónico + con instrucciones para completar la eliminación. recovery_options: check_saved_credential: Verifica si tienes una credencial almacenada check_webauthn_platform_info: Si has habilitado el desbloqueo facial o táctil, diff --git a/config/locales/account_reset/fr.yml b/config/locales/account_reset/fr.yml index 9506cab659a..f26afe7d5e0 100644 --- a/config/locales/account_reset/fr.yml +++ b/config/locales/account_reset/fr.yml @@ -34,9 +34,9 @@ fr: confirm: Si vous annulez maintenant, vous devez créer une nouvelle demande et attendre encore %{interval} pour supprimer votre compte. header: Vous avez demandé de supprimer votre compte - wait_html: Il y a un délai d’attente de %{waiting_period} pour supprimer votre compte. - Dans %{interval}, vous recevrez un e-mail avec des - instructions pour terminer la suppression. + wait_html: Il y a un délai d’attente de %{waiting_period} pour supprimer votre + compte. Dans %{interval}, vous recevrez un e-mail avec + des instructions pour terminer la suppression. recovery_options: check_saved_credential: Vérifiez si vous avez des informations d’identification sauvegardées check_webauthn_platform_info: Si vous avez configuré le déverrouillage facial ou From 879c1f0b2bf1907bbc9d011211d4803be644c0a6 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 08:50:57 -0500 Subject: [PATCH 11/33] use nil instead of 0 for check --- app/controllers/concerns/account_reset_concern.rb | 2 +- app/mailers/user_mailer.rb | 2 +- app/presenters/account_reset/pending_presenter.rb | 2 +- app/presenters/two_factor_login_options_presenter.rb | 2 +- config/application.yml.default | 2 +- lib/identity_config.rb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index a9555b67915..3a667e962a7 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -22,7 +22,7 @@ def account_reset_wait_period_days def supports_fraud_account_reset? (current_user.fraud_review_pending? || current_user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present? ) end def reset_accumulation_type diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 59af4252211..bac7e4a2b0a 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -453,7 +453,7 @@ def account_reset_wait_period_days def supports_fraud_account_reset? (user.fraud_review_pending? || user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present?) end def account_reset_token_valid_period diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index ca781f24ee3..f5a9c97a7a6 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -41,7 +41,7 @@ def account_reset_wait_period_days def supports_fraud_account_reset? (account_reset_request_user.fraud_review_pending? || account_reset_request_user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present?) end def account_reset_request_user diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index 48a94f1e7cd..87fb8258ea6 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -166,6 +166,6 @@ def account_reset_wait_period_days def supports_fraud_account_reset? (user.fraud_review_pending? || user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.days > 0) + (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present?) end end diff --git a/config/application.yml.default b/config/application.yml.default index 195f595bc68..0f8f78284e5 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -24,7 +24,7 @@ all_redirect_uris_cache_duration_minutes: 2 allowed_ialmax_providers: '[]' allowed_verified_within_providers: '[]' account_reset_token_valid_for_days: 1 -account_reset_fraud_user_wait_period_days: 0 +account_reset_fraud_user_wait_period_days: account_reset_wait_period_days: 1 account_suspended_support_code: EFGHI acuant_assure_id_password: '' diff --git a/lib/identity_config.rb b/lib/identity_config.rb index c6f45cad426..ae3934078d5 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -108,7 +108,7 @@ def self.build_store(config_map) config.add(:aamva_verification_url) config.add(:account_reset_token_valid_for_days, type: :integer) config.add(:account_reset_wait_period_days, type: :integer) - config.add(:account_reset_fraud_user_wait_period_days, type: :integer) + config.add(:account_reset_fraud_user_wait_period_days, type: :integer, allow_nil: true) config.add(:account_suspended_support_code, type: :string) config.add(:acuant_assure_id_password) config.add(:acuant_assure_id_subscription_id) From 9e080d102f25ca98a4e30c30df5abd5cf6b9a2d1 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 08:52:54 -0500 Subject: [PATCH 12/33] change to use specific hours rather than whether featuere is on --- app/controllers/concerns/account_reset_concern.rb | 2 +- app/mailers/user_mailer.rb | 2 +- app/presenters/account_reset/pending_presenter.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index 3a667e962a7..cb831132d71 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -26,7 +26,7 @@ def supports_fraud_account_reset? end def reset_accumulation_type - if supports_fraud_account_reset? + if account_reset_wait_period_days > 3 :days else :hours diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index bac7e4a2b0a..fe78d91c2dc 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -468,7 +468,7 @@ def account_reset_token_valid_period end def reset_accumulation_type - if supports_fraud_account_reset? + if account_reset_wait_period_days > 3 :days else :hours diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index f5a9c97a7a6..cc91d138f81 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -49,7 +49,7 @@ def account_reset_request_user end def reset_accumulation_type - if supports_fraud_account_reset? + if account_reset_wait_period_days > 3 :days else :hours From 735dea47b1e76250979fa7bbdec8986d33988b26 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 10:17:18 -0500 Subject: [PATCH 13/33] refactor account reset concern --- .../account_reset/pending_controller.rb | 2 +- .../account_reset/request_controller.rb | 2 +- .../concerns/account_reset_concern.rb | 23 ++++++----- app/mailers/user_mailer.rb | 38 ++----------------- .../account_reset/pending_presenter.rb | 2 +- .../two_factor_login_options_presenter.rb | 28 +------------- 6 files changed, 21 insertions(+), 74 deletions(-) diff --git a/app/controllers/account_reset/pending_controller.rb b/app/controllers/account_reset/pending_controller.rb index 88ea7b50f30..d1a713ea934 100644 --- a/app/controllers/account_reset/pending_controller.rb +++ b/app/controllers/account_reset/pending_controller.rb @@ -12,7 +12,7 @@ def show end def confirm - @account_reset_deletion_period_interval = account_reset_deletion_period_interval + @account_reset_deletion_period_interval = account_reset_deletion_period_interval(current_user) end def cancel diff --git a/app/controllers/account_reset/request_controller.rb b/app/controllers/account_reset/request_controller.rb index 48ba34427f5..7f51aea7740 100644 --- a/app/controllers/account_reset/request_controller.rb +++ b/app/controllers/account_reset/request_controller.rb @@ -7,7 +7,7 @@ class RequestController < ApplicationController def show analytics.account_reset_visit - @account_reset_deletion_period_interval = account_reset_deletion_period_interval + @account_reset_deletion_period_interval = account_reset_deletion_period_interval(current_user) end def create diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index cb831132d71..7df32a1eb41 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -1,31 +1,34 @@ module AccountResetConcern include ActionView::Helpers::DateHelper - def account_reset_deletion_period_interval + def account_reset_deletion_period_interval(user) current_time = Time.zone.now distance_of_time_in_words( current_time, - current_time + account_reset_wait_period_days, + current_time + account_reset_wait_period_days(user), true, - accumulate_on: reset_accumulation_type, + accumulate_on: account_reset_time_accumulation, ) end - def account_reset_wait_period_days - if supports_fraud_account_reset? + def account_reset_wait_period_days(user) + if supports_fraud_account_reset?(user) IdentityConfig.store.account_reset_fraud_user_wait_period_days.days else IdentityConfig.store.account_reset_wait_period_days.days end end - def supports_fraud_account_reset? - (current_user.fraud_review_pending? || - current_user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present? ) + def supports_fraud_account_reset?(user) + IdentityConfig.store.account_reset_fraud_user_wait_period_days.present? && + fraud_state?(user) end - def reset_accumulation_type + def fraud_state?(user) + user.fraud_review_pending? || user.fraud_rejection? + end + + def account_reset_time_accumulation if account_reset_wait_period_days > 3 :days else diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index fe78d91c2dc..86d3a4136ee 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -15,6 +15,7 @@ class UserMailer < ActionMailer::Base include Mailable include LocaleHelper + include AccountResetConcern include ActionView::Helpers::DateHelper class UserEmailAddressMismatchError < StandardError; end @@ -144,7 +145,7 @@ def personal_key_regenerated def account_reset_request(account_reset) with_user_locale(user) do @token = account_reset&.request_token - @account_reset_deletion_period_interval = account_reset_deletion_period_interval + @account_reset_deletion_period_interval = account_reset_deletion_period_interval(user) @header = t( 'user_mailer.account_reset_request.header', interval: account_reset_deletion_period_interval, @@ -160,7 +161,7 @@ def account_reset_granted(account_reset) with_user_locale(user) do @token = account_reset&.request_token @granted_token = account_reset&.granted_token - @account_reset_deletion_period_interval = account_reset_deletion_period_interval + @account_reset_deletion_period_interval = account_reset_deletion_period_interval(user) @account_reset_token_valid_period = account_reset_token_valid_period mail( to: email_address.email, @@ -431,31 +432,6 @@ def account_reinstated private - def account_reset_deletion_period_interval - current_time = Time.zone.now - - distance_of_time_in_words( - current_time, - current_time + account_reset_wait_period_days, - true, - accumulate_on: reset_accumulation_type, - ) - end - - def account_reset_wait_period_days - if supports_fraud_account_reset? - IdentityConfig.store.account_reset_fraud_user_wait_period_days.days - else - IdentityConfig.store.account_reset_wait_period_days.days - end - end - - def supports_fraud_account_reset? - (user.fraud_review_pending? || - user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present?) - end - def account_reset_token_valid_period current_time = Time.zone.now @@ -466,12 +442,4 @@ def account_reset_token_valid_period accumulate_on: :hours, ) end - - def reset_accumulation_type - if account_reset_wait_period_days > 3 - :days - else - :hours - end - end end diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index cc91d138f81..4c691110296 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -41,7 +41,7 @@ def account_reset_wait_period_days def supports_fraud_account_reset? (account_reset_request_user.fraud_review_pending? || account_reset_request_user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present?) + IdentityConfig.store.account_reset_fraud_user_wait_period_days.present? end def account_reset_request_user diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index 87fb8258ea6..cff2c81bfb0 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -1,4 +1,5 @@ class TwoFactorLoginOptionsPresenter < TwoFactorAuthCode::GenericDeliveryPresenter + include AccountResetConcern include ActionView::Helpers::TranslationHelper attr_reader :user, :reauthentication_context, :phishing_resistant_required, :piv_cac_required @@ -117,7 +118,7 @@ def account_reset_cancel_link [ t( 'two_factor_authentication.account_reset.pending', - interval: account_reset_deletion_period_interval, + interval: account_reset_deletion_period_interval(user), ), @view.link_to( t('two_factor_authentication.account_reset.cancel_link'), @@ -143,29 +144,4 @@ def sp_name APP_NAME end end - - def account_reset_deletion_period_interval - current_time = Time.zone.now - - view.distance_of_time_in_words( - current_time, - current_time + account_reset_wait_period_days, - true, - accumulate_on: :hours, - ) - end - - def account_reset_wait_period_days - if supports_fraud_account_reset? - IdentityConfig.store.account_reset_fraud_user_wait_period_days.days - else - IdentityConfig.store.account_reset_wait_period_days.days - end - end - - def supports_fraud_account_reset? - (user.fraud_review_pending? || - user.fraud_rejection?) && - (IdentityConfig.store.account_reset_fraud_user_wait_period_days.present?) - end end From 14d28d8a5345ae1d2ce71a92caa05bd51c7a7a8b Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 10:19:13 -0500 Subject: [PATCH 14/33] fraud period --- .../account_reset/grant_requests_and_send_emails.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/account_reset/grant_requests_and_send_emails.rb b/app/services/account_reset/grant_requests_and_send_emails.rb index a1a0ca86f26..73e9a456f57 100644 --- a/app/services/account_reset/grant_requests_and_send_emails.rb +++ b/app/services/account_reset/grant_requests_and_send_emails.rb @@ -53,13 +53,13 @@ def grant_request_and_send_email(arr) def fraud_wait_period_not_met?(arr, now) if (arr.user.fraud_review_pending? || arr.user.fraud_rejection?) && - (fraud_wait_period_days > 0) - return arr.requested_at > (now - fraud_wait_period_days) + (fraud_wait_period_days.present?) + return arr.requested_at > (now - fraud_wait_period_days.days) end end def fraud_wait_period_days - IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + IdentityConfig.store.account_reset_fraud_user_wait_period_days end end end From ab85187832ec6c5209331b74fce64862cf5eb4c3 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 11:04:04 -0500 Subject: [PATCH 15/33] fix concern --- app/controllers/concerns/account_reset_concern.rb | 6 +++--- .../account_reset/grant_requests_and_send_emails.rb | 2 +- spec/controllers/concerns/account_reset_concern_spec.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index 7df32a1eb41..9c97ed228f5 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -7,7 +7,7 @@ def account_reset_deletion_period_interval(user) current_time, current_time + account_reset_wait_period_days(user), true, - accumulate_on: account_reset_time_accumulation, + accumulate_on: account_reset_time_accumulation(user), ) end @@ -28,8 +28,8 @@ def fraud_state?(user) user.fraud_review_pending? || user.fraud_rejection? end - def account_reset_time_accumulation - if account_reset_wait_period_days > 3 + def account_reset_time_accumulation(user) + if account_reset_wait_period_days(user) > 3 :days else :hours diff --git a/app/services/account_reset/grant_requests_and_send_emails.rb b/app/services/account_reset/grant_requests_and_send_emails.rb index 73e9a456f57..59938366d5e 100644 --- a/app/services/account_reset/grant_requests_and_send_emails.rb +++ b/app/services/account_reset/grant_requests_and_send_emails.rb @@ -53,7 +53,7 @@ def grant_request_and_send_email(arr) def fraud_wait_period_not_met?(arr, now) if (arr.user.fraud_review_pending? || arr.user.fraud_rejection?) && - (fraud_wait_period_days.present?) + fraud_wait_period_days.present? return arr.requested_at > (now - fraud_wait_period_days.days) end end diff --git a/spec/controllers/concerns/account_reset_concern_spec.rb b/spec/controllers/concerns/account_reset_concern_spec.rb index 959d85eb6e5..5a026a1b9f9 100644 --- a/spec/controllers/concerns/account_reset_concern_spec.rb +++ b/spec/controllers/concerns/account_reset_concern_spec.rb @@ -26,7 +26,7 @@ def initialize(current_user:) true, accumulate_on: :hours, ) - expect(instance.account_reset_deletion_period_interval). + expect(instance.account_reset_deletion_period_interval(user)). to eq(time_in_hours) end end @@ -41,7 +41,7 @@ def initialize(current_user:) true, accumulate_on: :days, ) - expect(instance.account_reset_deletion_period_interval). + expect(instance.account_reset_deletion_period_interval(user)). to eq(time_in_hours) end end From 82defd1b8bece43afeaea7fec81fc6f2bcaea7f5 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 11:59:11 -0500 Subject: [PATCH 16/33] account reset concern fix --- app/controllers/concerns/account_reset_concern.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index 9c97ed228f5..e3698963398 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -29,7 +29,7 @@ def fraud_state?(user) end def account_reset_time_accumulation(user) - if account_reset_wait_period_days(user) > 3 + if account_reset_wait_period_days(user) > 3.days :days else :hours From 906d91479fef48d7f77124c2687a542440cd0986 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Tue, 5 Mar 2024 13:57:34 -0500 Subject: [PATCH 17/33] fix user mailer --- app/mailers/user_mailer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 86d3a4136ee..5027083feb7 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -148,7 +148,7 @@ def account_reset_request(account_reset) @account_reset_deletion_period_interval = account_reset_deletion_period_interval(user) @header = t( 'user_mailer.account_reset_request.header', - interval: account_reset_deletion_period_interval, + interval: @account_reset_deletion_period_interval, ) mail( to: email_address.email, From 00480e54e877e4bc19ee3f9bcdfac4dea2b1fa4d Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 6 Mar 2024 10:25:50 -0500 Subject: [PATCH 18/33] use the reset concern in pending presenter --- .../account_reset/pending_presenter.rb | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index 4c691110296..8a59c35828d 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -1,5 +1,6 @@ module AccountReset class PendingPresenter + include AccountResetConcern include ActionView::Helpers::DateHelper attr_reader :account_reset_request @@ -9,7 +10,7 @@ def initialize(account_reset_request) end def time_remaining_until_granted(now: Time.zone.now) - wait_time = account_reset_wait_period_days + wait_time = account_reset_wait_period_days(user) distance_of_time_in_words( now, @@ -24,36 +25,14 @@ def account_reset_deletion_period distance_of_time_in_words( current_time, - current_time + account_reset_wait_period_days, + current_time + account_reset_wait_period_days(user), true, - accumulate_on: reset_accumulation_type, + accumulate_on: reset_accumulation_type(user), ) end - def account_reset_wait_period_days - if supports_fraud_account_reset? - IdentityConfig.store.account_reset_fraud_user_wait_period_days.days - else - IdentityConfig.store.account_reset_wait_period_days.days - end - end - - def supports_fraud_account_reset? - (account_reset_request_user.fraud_review_pending? || - account_reset_request_user.fraud_rejection?) && - IdentityConfig.store.account_reset_fraud_user_wait_period_days.present? - end - - def account_reset_request_user + def user account_reset_request.user end - - def reset_accumulation_type - if account_reset_wait_period_days > 3 - :days - else - :hours - end - end end end From fbea98ad0f567ac663fa2bc8352f2be6baf3eb71 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 6 Mar 2024 12:30:18 -0500 Subject: [PATCH 19/33] pending presenter spec --- .../account_reset/pending_presenter_spec.rb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/spec/presenters/account_reset/pending_presenter_spec.rb b/spec/presenters/account_reset/pending_presenter_spec.rb index b4bb776a0aa..4c8420f4816 100644 --- a/spec/presenters/account_reset/pending_presenter_spec.rb +++ b/spec/presenters/account_reset/pending_presenter_spec.rb @@ -20,6 +20,36 @@ describe '#time_remaining_until_granted' do before { I18n.locale = :en } + let(:user) { create(:user, :fraud_review_pending) } + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(10) + end + + context 'fraud user' do + context 'when the remaining time is greater than 1 week' do + let(:requested_at) { 10.days.ago - (9.days + 21.minutes) } + + it 'returns its description in week and days' do + expect(subject.time_remaining_until_granted).to eq '1 week and 2 days' + end + end + context 'when the remaining time is greater than 3 days and less than 1 weeks' do + let(:requested_at) { 10.days.ago - (5.days + 21.hours) } + + it 'returns its description in hours and minutes' do + expect(subject.time_remaining_until_granted).to eq '5 days and 21 hours' + end + end + + context 'when the remaining time is less than 1 day' do + let(:requested_at) { 10.days.ago - (10.hours + 21.minutes) } + + it 'returns its description in hours and minutes' do + expect(subject.time_remaining_until_granted).to eq '10 hours and 21 minutes' + end + end + end context 'when the remaining time is greater than 1 hour' do let(:requested_at) { 24.hours.ago - (2.hours + 21.minutes) } From 30a994a12bbb34cc701a021a7a629f5479c2e3a6 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Thu, 7 Mar 2024 14:47:13 -0500 Subject: [PATCH 20/33] en --- config/locales/account_reset/en.yml | 2 +- config/locales/user_mailer/en.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/account_reset/en.yml b/config/locales/account_reset/en.yml index 0dfd2c8f76b..1a21ecf7eab 100644 --- a/config/locales/account_reset/en.yml +++ b/config/locales/account_reset/en.yml @@ -33,7 +33,7 @@ en: confirm: If you cancel now, you must create a new request and wait another %{interval} to delete your account. header: You requested to delete your account - wait_html: There is a %{waiting_period} waiting period to delete your account. + wait_html: There is a waiting period of %{waiting_period} to delete your account. In %{interval}, you will receive an email with instructions to complete the deletion. recovery_options: diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index 91df158260b..5df4a50e41e 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -20,7 +20,7 @@ en: button: Yes, continue deleting cancel_link_text: please cancel help_html: If you don’t want to delete your account, %{cancel_account_reset_html}. - intro_html: Your %{waiting_period} waiting period has ended. Please complete + intro_html: Your waiting period of %{waiting_period} has ended. Please complete step 2 of the process.

If you’ve been unable to locate your authentication methods, select “confirm deletion” to delete your %{app_name} account.

In the future, if you need to access From 1c9a9c240a4edb90598f8d0a03f2dbe095e34654 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 11 Mar 2024 12:45:42 -0400 Subject: [PATCH 21/33] normalize_yaml --- config/locales/account_reset/en.yml | 4 ++-- config/locales/user_mailer/es.yml | 4 ++-- config/locales/user_mailer/fr.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/locales/account_reset/en.yml b/config/locales/account_reset/en.yml index 1a21ecf7eab..ea9493777fd 100644 --- a/config/locales/account_reset/en.yml +++ b/config/locales/account_reset/en.yml @@ -33,8 +33,8 @@ en: confirm: If you cancel now, you must create a new request and wait another %{interval} to delete your account. header: You requested to delete your account - wait_html: There is a waiting period of %{waiting_period} to delete your account. - In %{interval}, you will receive an email with + wait_html: There is a waiting period of %{waiting_period} to delete your + account. In %{interval}, you will receive an email with instructions to complete the deletion. recovery_options: check_saved_credential: See if you have a saved credential diff --git a/config/locales/user_mailer/es.yml b/config/locales/user_mailer/es.yml index e817c6363d9..7e8ffc9bd65 100644 --- a/config/locales/user_mailer/es.yml +++ b/config/locales/user_mailer/es.yml @@ -22,8 +22,8 @@ es: button: Sí, continúa eliminando cancel_link_text: por favor cancele help_html: Si no desea eliminar su cuenta, %{cancel_account_reset_html}. - intro_html: Su período de espera de %{waiting_period} ha finalizado. Complete el - paso 2 del proceso.

Si no ha podido localizar sus métodos de + intro_html: Su período de espera de %{waiting_period} finalizó. Complete el paso + 2 del proceso.

Si no ha podido localizar sus métodos de autenticación, seleccione “confirmar eliminación” para eliminar su cuenta de %{app_name}.

En el futuro, si necesita acceder a los sitios web gubernamentales participantes que utilizan %{app_name}, puede diff --git a/config/locales/user_mailer/fr.yml b/config/locales/user_mailer/fr.yml index 0c8efc64195..44b76f2b28c 100644 --- a/config/locales/user_mailer/fr.yml +++ b/config/locales/user_mailer/fr.yml @@ -22,7 +22,7 @@ fr: cancel_link_text: veuillez annuler help_html: Si vous ne souhaitez pas supprimer votre compte, %{cancel_account_reset_html}. - intro_html: Votre période d’attente de %{waiting_period} est terminée. Veuillez + intro_html: Votre délai d’attente de %{waiting_period} est terminé. Veuillez terminer l’étape 2 du processus.

Si vous ne parvenez pas à localiser vos méthodes d’authentification, sélectionnez “confirmer la suppression” pour supprimer votre compte %{app_name}.

À From 346dd87d872b2a670b43d4cc0cb8d9ddf8ba5566 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 11 Mar 2024 14:19:40 -0400 Subject: [PATCH 22/33] make sure to use proper naming --- app/controllers/concerns/account_reset_concern.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/concerns/account_reset_concern.rb b/app/controllers/concerns/account_reset_concern.rb index e3698963398..15457c8fb87 100644 --- a/app/controllers/concerns/account_reset_concern.rb +++ b/app/controllers/concerns/account_reset_concern.rb @@ -7,7 +7,7 @@ def account_reset_deletion_period_interval(user) current_time, current_time + account_reset_wait_period_days(user), true, - accumulate_on: account_reset_time_accumulation(user), + accumulate_on: reset_accumulation_type(user), ) end @@ -28,7 +28,7 @@ def fraud_state?(user) user.fraud_review_pending? || user.fraud_rejection? end - def account_reset_time_accumulation(user) + def reset_accumulation_type(user) if account_reset_wait_period_days(user) > 3.days :days else From c9da68769655a39b0f1fc3ee369f7680756443aa Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 13 Mar 2024 09:25:43 -0400 Subject: [PATCH 23/33] move over to grant request --- app/services/account_reset/grant_request.rb | 23 ++++++++++++++++--- .../grant_requests_and_send_emails.rb | 13 ----------- .../account_reset/pending_presenter_spec.rb | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/services/account_reset/grant_request.rb b/app/services/account_reset/grant_request.rb index 0598458378b..ab9d54c8a87 100644 --- a/app/services/account_reset/grant_request.rb +++ b/app/services/account_reset/grant_request.rb @@ -7,9 +7,10 @@ def initialize(user) def call token = SecureRandom.uuid arr = AccountResetRequest.find_by(user_id: @user_id) + return if fraud_user?(arr) && fraud_wait_not_met?(arr) result = arr.with_lock do if !arr.granted_token_valid? - account_reset_request.update( + arr.update( granted_at: Time.zone.now, granted_token: token, ) @@ -21,8 +22,24 @@ def call private - def account_reset_request - AccountResetRequest.create_or_find_by(user_id: @user_id) + def fraud_user?(arr) + arr.user.fraud_review_pending? || + arr.user.fraud_rejection? + end + + def fraud_user_and_fraud_with_not_met(arr) + end + + def fraud_wait_period_not_met?(now) + if fraud_wait_period_days.present? + return arr.requested_at > (now - fraud_wait_period_days.days) + else + false + end + end + + def fraud_wait_period_days + IdentityConfig.store.account_reset_fraud_user_wait_period_days end end end diff --git a/app/services/account_reset/grant_requests_and_send_emails.rb b/app/services/account_reset/grant_requests_and_send_emails.rb index 59938366d5e..8e4f1fa1696 100644 --- a/app/services/account_reset/grant_requests_and_send_emails.rb +++ b/app/services/account_reset/grant_requests_and_send_emails.rb @@ -8,7 +8,6 @@ def perform(now) sql_query_for_users_eligible_to_delete_their_accounts, tvalue: now - IdentityConfig.store.account_reset_wait_period_days.days, ).order('requested_at ASC').each do |arr| - next if fraud_wait_period_not_met?(arr, now) notifications_sent += 1 if grant_request_and_send_email(arr) end @@ -49,17 +48,5 @@ def grant_request_and_send_email(arr) end true end - - def fraud_wait_period_not_met?(arr, now) - if (arr.user.fraud_review_pending? || - arr.user.fraud_rejection?) && - fraud_wait_period_days.present? - return arr.requested_at > (now - fraud_wait_period_days.days) - end - end - - def fraud_wait_period_days - IdentityConfig.store.account_reset_fraud_user_wait_period_days - end end end diff --git a/spec/presenters/account_reset/pending_presenter_spec.rb b/spec/presenters/account_reset/pending_presenter_spec.rb index 4c8420f4816..631d6976dcc 100644 --- a/spec/presenters/account_reset/pending_presenter_spec.rb +++ b/spec/presenters/account_reset/pending_presenter_spec.rb @@ -20,13 +20,13 @@ describe '#time_remaining_until_granted' do before { I18n.locale = :en } - let(:user) { create(:user, :fraud_review_pending) } before do allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). and_return(10) end context 'fraud user' do + let(:user) { create(:user, :fraud_review_pending) } context 'when the remaining time is greater than 1 week' do let(:requested_at) { 10.days.ago - (9.days + 21.minutes) } From 34db8768b4d5fb96c11a9c6ff043fd10110b25a5 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 13 Mar 2024 10:00:16 -0400 Subject: [PATCH 24/33] grant request --- app/services/account_reset/grant_request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/account_reset/grant_request.rb b/app/services/account_reset/grant_request.rb index ab9d54c8a87..ecf043f93b4 100644 --- a/app/services/account_reset/grant_request.rb +++ b/app/services/account_reset/grant_request.rb @@ -7,7 +7,7 @@ def initialize(user) def call token = SecureRandom.uuid arr = AccountResetRequest.find_by(user_id: @user_id) - return if fraud_user?(arr) && fraud_wait_not_met?(arr) + return if fraud_user?(arr) && fraud_wait_period_not_met?(arr) result = arr.with_lock do if !arr.granted_token_valid? arr.update( From d24655dff5258f049bc68acf82d0598642fdcb3b Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 13 Mar 2024 10:50:26 -0400 Subject: [PATCH 25/33] change method to work --- app/services/account_reset/grant_request.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/services/account_reset/grant_request.rb b/app/services/account_reset/grant_request.rb index ecf043f93b4..3e01b5c213b 100644 --- a/app/services/account_reset/grant_request.rb +++ b/app/services/account_reset/grant_request.rb @@ -27,12 +27,9 @@ def fraud_user?(arr) arr.user.fraud_rejection? end - def fraud_user_and_fraud_with_not_met(arr) - end - - def fraud_wait_period_not_met?(now) + def fraud_wait_period_not_met?(arr) if fraud_wait_period_days.present? - return arr.requested_at > (now - fraud_wait_period_days.days) + return arr.requested_at > (Time.zone.now - fraud_wait_period_days.days) else false end From 53dc2c66079b573368bc23ec3d7c7bca7238c6bd Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 18 Mar 2024 08:58:02 -0400 Subject: [PATCH 26/33] commenting presenter to use proper language --- app/presenters/account_reset/pending_presenter.rb | 9 +-------- app/services/account_reset/grant_request.rb | 2 +- config/locales/user_mailer/en.yml | 4 ++-- config/locales/user_mailer/es.yml | 4 ++-- config/locales/user_mailer/fr.yml | 14 +++++++------- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index 8a59c35828d..3325adec06d 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -21,14 +21,7 @@ def time_remaining_until_granted(now: Time.zone.now) end def account_reset_deletion_period - current_time = Time.zone.now - - distance_of_time_in_words( - current_time, - current_time + account_reset_wait_period_days(user), - true, - accumulate_on: reset_accumulation_type(user), - ) + account_reset_deletion_period_interval(user) end def user diff --git a/app/services/account_reset/grant_request.rb b/app/services/account_reset/grant_request.rb index 3e01b5c213b..0dec3f3d27f 100644 --- a/app/services/account_reset/grant_request.rb +++ b/app/services/account_reset/grant_request.rb @@ -7,7 +7,7 @@ def initialize(user) def call token = SecureRandom.uuid arr = AccountResetRequest.find_by(user_id: @user_id) - return if fraud_user?(arr) && fraud_wait_period_not_met?(arr) + return false if fraud_user?(arr) && fraud_wait_period_not_met?(arr) result = arr.with_lock do if !arr.granted_token_valid? arr.update( diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index 5df4a50e41e..df61d8ff64d 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -33,8 +33,8 @@ en: to cancel. header: Your account will be deleted in %{interval} intro_html: 'As a security measure, %{app_name} requires a two-step process to - delete your account:

Step One: There is a %{waiting_period} - waiting period if you have lost access to your authentication methods + delete your account:

Step One: There is a waiting period of + %{waiting_period} if you have lost access to your authentication methods and need to delete your account. If you locate your authentication methods, you can sign in to your %{app_name} account to cancel this request.

Step Two: After your %{waiting_period} waiting period, diff --git a/config/locales/user_mailer/es.yml b/config/locales/user_mailer/es.yml index 7e8ffc9bd65..996950151d2 100644 --- a/config/locales/user_mailer/es.yml +++ b/config/locales/user_mailer/es.yml @@ -35,8 +35,8 @@ es: para cancelar.' header: Su cuenta será eliminada en %{interval} intro_html: 'Como medida de seguridad, %{app_name} requiere un proceso de dos - pasos para eliminar su cuenta:

Paso uno: hay un período de - espera de %{waiting_period} si ha perdido el acceso a sus métodos de + pasos para eliminar su cuenta:

Paso uno: Hay un período de + espera de %{waiting_period} si perdió el acceso a sus métodos de autenticación y necesita eliminar su cuenta. Si encuentra sus métodos de autenticación, puede iniciar sesión en su cuenta %{app_name} para cancelar esta solicitud.

Paso dos: Después de su período de diff --git a/config/locales/user_mailer/fr.yml b/config/locales/user_mailer/fr.yml index 44b76f2b28c..cb7462cce97 100644 --- a/config/locales/user_mailer/fr.yml +++ b/config/locales/user_mailer/fr.yml @@ -36,13 +36,13 @@ fr: %{app_name} pour annuler. header: Votre compte sera supprimé dans %{interval} intro_html: 'Par mesure de sécurité, %{app_name} nécessite un processus en deux - étapes pour supprimer votre compte:

Étape 1: Il y a une - période d’attente de %{waiting_period} si vous avez perdu l’accès à vos - méthodes d’authentification et devez supprimer votre compte. Si vous - trouvez vos méthodes d’authentification, vous pouvez vous connecter à - votre compte %{app_name} pour annuler cette demande.

Deuxième - étape: après votre période d’attente de %{waiting_period}, vous recevrez - un e-mail qui vous demandera de confirmer la suppression de votre compte + étapes pour supprimer votre compte:

Étape 1: Il y a un delai + d’attente de %{waiting_period} si vous avez perdu l’accès à vos méthodes + d’authentification et devez supprimer votre compte. Si vous trouvez vos + méthodes d’authentification, vous pouvez vous connecter à votre compte + %{app_name} pour annuler cette demande.

Deuxième étape: après + votre période d’attente de %{waiting_period}, vous recevrez un e-mail + qui vous demandera de confirmer la suppression de votre compte %{app_name}. Votre compte ne sera pas supprimé tant que vous ne l’aurez pas confirmé.' subject: Comment supprimer votre compte %{app_name} From 9f030ae5dea86b4f161813f8a11962526121dfac Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Mon, 18 Mar 2024 10:24:33 -0400 Subject: [PATCH 27/33] add spec for grant request --- .../account_reset/grant_request_spec.rb | 43 +++++++++++++++++++ .../grant_requests_and_send_emails_spec.rb | 4 +- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/spec/services/account_reset/grant_request_spec.rb b/spec/services/account_reset/grant_request_spec.rb index be3fafbeda7..9e009d98a5b 100644 --- a/spec/services/account_reset/grant_request_spec.rb +++ b/spec/services/account_reset/grant_request_spec.rb @@ -29,5 +29,48 @@ expect(arr.granted_token).to eq(arr.reload.granted_token) end end + + context 'with a fraud user' do + let(:user) { create(:user, :fraud_review_pending) } + let(:user2) { create(:user, :fraud_rejection) } + context 'with deletion period not met' do + it 'does not grant request' do + create_account_reset_request_for(user) + result = AccountReset::GrantRequest.new(user).call + + arr = AccountResetRequest.find_by(user_id: user.id) + expect(arr.granted_at).to_not be_present + expect(arr.granted_token).to_not be_present + expect(result).to eq false + end + end + + context 'with deletion period met' do + it 'grants request for all users' do + before_waiting_the_full_fraud_wait_period(Time.zone.now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + result = AccountReset::GrantRequest.new(user).call + arr = AccountResetRequest.find_by(user_id: user.id) + expect(arr.granted_at).to be_present + expect(arr.granted_token).to be_present + expect(result).to eq true + + result2 = AccountReset::GrantRequest.new(user2).call + arr2 = AccountResetRequest.find_by(user_id: user2.id) + expect(arr2.granted_at).to be_present + expect(arr2.granted_token).to be_present + expect(result2).to eq true + end + end + end + end + def before_waiting_the_full_fraud_wait_period(now) + days = IdentityConfig.store.account_reset_fraud_user_wait_period_days.days + travel_to(now - 1 - days) do + yield + end end end diff --git a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb index ab665d1ced0..27c687e49d6 100644 --- a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb +++ b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb @@ -54,8 +54,8 @@ end context 'possible fraud user' do - let(:user) { create(:user, :gpo_pending_with_fraud_review) } - let(:user2) { create(:user, :gpo_pending_with_fraud_rejection) } + let(:user) { create(:user, :fraud_review_pending) } + let(:user2) { create(:user, :fraud_rejection) } before do allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). and_return(10) From 0a9257636408953da30e069fde42dc521300e714 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Wed, 20 Mar 2024 08:50:24 -0400 Subject: [PATCH 28/33] leverage reset concern --- app/services/account_reset/create_request.rb | 14 ++------------ .../account_reset/find_pending_request_for_user.rb | 3 ++- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/app/services/account_reset/create_request.rb b/app/services/account_reset/create_request.rb index bbe2d05de2b..61da2996239 100644 --- a/app/services/account_reset/create_request.rb +++ b/app/services/account_reset/create_request.rb @@ -1,5 +1,6 @@ module AccountReset class CreateRequest + include AccountResetConcern include ActionView::Helpers::DateHelper def initialize(user, requesting_issuer) @@ -48,23 +49,12 @@ def notify_user_by_sms_if_applicable @telephony_response = Telephony.send_account_reset_notice( to: phone, country_code: Phonelib.parse(phone).country, - interval: account_reset_wait_period, + interval: account_reset_deletion_period_interval(user), ) end def extra_analytics_attributes @telephony_response&.extra&.slice(:request_id, :message_id) || {} end - - def account_reset_wait_period - current_time = Time.zone.now - - distance_of_time_in_words( - current_time, - current_time + IdentityConfig.store.account_reset_wait_period_days, - true, - accumulate_on: :hours, - ) - end end end diff --git a/app/services/account_reset/find_pending_request_for_user.rb b/app/services/account_reset/find_pending_request_for_user.rb index e8d27db2f04..79ca655beba 100644 --- a/app/services/account_reset/find_pending_request_for_user.rb +++ b/app/services/account_reset/find_pending_request_for_user.rb @@ -1,5 +1,6 @@ module AccountReset class FindPendingRequestForUser + include AccountResetConcern attr_reader :user def initialize(user) @@ -13,7 +14,7 @@ def call cancelled_at: nil, ).where( 'requested_at > ?', - IdentityConfig.store.account_reset_wait_period_days.days.ago, + account_reset_wait_period_days(user).ago, ).order(requested_at: :asc).first end end From d083a72f31644d2219a7f93811b81bb9d4f2ba68 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Thu, 21 Mar 2024 19:18:44 -0400 Subject: [PATCH 29/33] Add spec for find pending request fraud check --- ...c.rb => find_pending_request_for_user_spec.rb} | 15 +++++++++++++++ 1 file changed, 15 insertions(+) rename spec/services/account_reset/{find_prending_request_for_user_spec.rb => find_pending_request_for_user_spec.rb} (70%) diff --git a/spec/services/account_reset/find_prending_request_for_user_spec.rb b/spec/services/account_reset/find_pending_request_for_user_spec.rb similarity index 70% rename from spec/services/account_reset/find_prending_request_for_user_spec.rb rename to spec/services/account_reset/find_pending_request_for_user_spec.rb index d2a5fb7ba38..bad22dc2f96 100644 --- a/spec/services/account_reset/find_prending_request_for_user_spec.rb +++ b/spec/services/account_reset/find_pending_request_for_user_spec.rb @@ -45,5 +45,20 @@ it { expect(subject.call).to be_nil } end + + context 'fraud user' do + let(:user) { create(:user, :fraud_review_pending) } + let(:user2) { create(:user, :fraud_rejection) } + context 'when a request exists, and it hasnt been granted yet but over a day' do + let(:requested_at) { 30.hours.ago } + + it { expect(subject.call).to eq(account_reset_request) } + end + context 'when a request has expired' do + let(:requested_at) { 1.year.ago } + + it { expect(subject.call).to be_nil } + end + end end end From 5eb1029b712d0966a79acaff46270907663db332 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Fri, 22 Mar 2024 10:33:24 -0400 Subject: [PATCH 30/33] make sure second step can handle the new step language --- config/locales/user_mailer/en.yml | 8 ++++---- config/locales/user_mailer/es.yml | 8 ++++---- config/locales/user_mailer/fr.yml | 7 +++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index df61d8ff64d..16585668655 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -37,10 +37,10 @@ en: %{waiting_period} if you have lost access to your authentication methods and need to delete your account. If you locate your authentication methods, you can sign in to your %{app_name} account to cancel this - request.

Step Two: After your %{waiting_period} waiting period, - you will receive an email that will ask you to confirm the deletion of - your %{app_name} account. Your account will not be deleted until you - confirm.' + request.

Step Two: After the waiting period of + %{waiting_period}, you will receive an email that will ask you to + confirm the deletion of your %{app_name} account. Your account will not + be deleted until you confirm.' subject: How to delete your %{app_name} account account_verified: change_password_link: change your password diff --git a/config/locales/user_mailer/es.yml b/config/locales/user_mailer/es.yml index 996950151d2..b7c372edafb 100644 --- a/config/locales/user_mailer/es.yml +++ b/config/locales/user_mailer/es.yml @@ -39,10 +39,10 @@ es: espera de %{waiting_period} si perdió el acceso a sus métodos de autenticación y necesita eliminar su cuenta. Si encuentra sus métodos de autenticación, puede iniciar sesión en su cuenta %{app_name} para - cancelar esta solicitud.

Paso dos: Después de su período de - espera de %{waiting_period}, recibirá un correo electrónico que le - pedirá que confirme la eliminación de su cuenta %{app_name}. Su cuenta - no se eliminará hasta que confirme.' + cancelar esta solicitud.

Paso dos: Tras el período de espera de + %{waiting_period}, recibirás un correo electrónico en el que te + pediremos que confirmes la eliminación de tu cuenta %{app_name}. Tu + cuenta no se eliminará hasta que lo confirmes.' subject: Cómo eliminar su cuenta de %{app_name} account_verified: change_password_link: cambiar tu contraseña diff --git a/config/locales/user_mailer/fr.yml b/config/locales/user_mailer/fr.yml index cb7462cce97..b52f7806e2d 100644 --- a/config/locales/user_mailer/fr.yml +++ b/config/locales/user_mailer/fr.yml @@ -41,10 +41,9 @@ fr: d’authentification et devez supprimer votre compte. Si vous trouvez vos méthodes d’authentification, vous pouvez vous connecter à votre compte %{app_name} pour annuler cette demande.

Deuxième étape: après - votre période d’attente de %{waiting_period}, vous recevrez un e-mail - qui vous demandera de confirmer la suppression de votre compte - %{app_name}. Votre compte ne sera pas supprimé tant que vous ne l’aurez - pas confirmé.' + la période d’attente de %{waiting_period}, vous recevrez un e-mail qui + vous demandera de confirmer la suppression de votre compte %{app_name}. + Votre compte ne sera pas supprimé tant que vous n’aurez pas confirmé.' subject: Comment supprimer votre compte %{app_name} account_verified: change_password_link: changer votre mot de passe From bc9e8319ca7168f6faffd1ef6538fbba1a2bb953 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Fri, 22 Mar 2024 13:07:41 -0400 Subject: [PATCH 31/33] LG-11784: add check for when wait period for fraud isnt set --- .../account_reset/grant_request_spec.rb | 33 ++++++++ .../grant_requests_and_send_emails_spec.rb | 75 ++++++++++++++----- 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/spec/services/account_reset/grant_request_spec.rb b/spec/services/account_reset/grant_request_spec.rb index 9e009d98a5b..7cbe0ecb6ab 100644 --- a/spec/services/account_reset/grant_request_spec.rb +++ b/spec/services/account_reset/grant_request_spec.rb @@ -33,6 +33,31 @@ context 'with a fraud user' do let(:user) { create(:user, :fraud_review_pending) } let(:user2) { create(:user, :fraud_rejection) } + context 'with nil being set for fraud time' do + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(nil) + end + + it 'grants request for all users' do + before_waiting_the_full_wait_period(Time.zone.now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + result = AccountReset::GrantRequest.new(user).call + arr = AccountResetRequest.find_by(user_id: user.id) + expect(arr.granted_at).to be_present + expect(arr.granted_token).to be_present + expect(result).to eq true + + result2 = AccountReset::GrantRequest.new(user2).call + arr2 = AccountResetRequest.find_by(user_id: user2.id) + expect(arr2.granted_at).to be_present + expect(arr2.granted_token).to be_present + expect(result2).to eq true + end + end context 'with deletion period not met' do it 'does not grant request' do create_account_reset_request_for(user) @@ -67,6 +92,14 @@ end end end + + def before_waiting_the_full_wait_period(now) + days = IdentityConfig.store.account_reset_wait_period_days.days + travel_to(now - 1 - days) do + yield + end + end + def before_waiting_the_full_fraud_wait_period(now) days = IdentityConfig.store.account_reset_fraud_user_wait_period_days.days travel_to(now - 1 - days) do diff --git a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb index 27c687e49d6..a3585c37a5e 100644 --- a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb +++ b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb @@ -124,30 +124,65 @@ context 'possible fraud user' do let(:user) { create(:user, :fraud_review_pending) } let(:user2) { create(:user, :fraud_rejection) } - it 'does not send notifications before a request wait period is done' do - create_account_reset_request_for(user) - - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(0) - end - - it 'does not send notifications when the request was cancelled' do - create_account_reset_request_for(user) - cancel_request_for(user) - - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - expect(notifications_sent).to eq(0) + context 'with fraud wait period set' do + it 'does not send notifications before a request wait period is done' do + create_account_reset_request_for(user) + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'does not send notifications when the request was cancelled' do + create_account_reset_request_for(user) + cancel_request_for(user) + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'should not send if its in between regular wait period and fraud wait period' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + + expect(notifications_sent).to eq(0) + end end - it 'should not send if its in between regular wait period and fraud wait period' do - before_waiting_the_full_wait_period(now) do + context 'with fraud wait period not set' do + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(nil) + end + it 'does not send notifications before a request wait period is done' do create_account_reset_request_for(user) - create_account_reset_request_for(user2) + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) end - - notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - - expect(notifications_sent).to eq(0) + + it 'does not send notifications when the request was cancelled' do + create_account_reset_request_for(user) + cancel_request_for(user) + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + expect(notifications_sent).to eq(0) + end + + it 'should send if its after regular wait period' do + before_waiting_the_full_wait_period(now) do + create_account_reset_request_for(user) + create_account_reset_request_for(user2) + end + + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) + + expect(notifications_sent).to eq(2) + end + end end end From bfdaa9eb683297d6141843ddc8473f5f28703809 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Fri, 22 Mar 2024 13:10:40 -0400 Subject: [PATCH 32/33] Regular wait period check for fraud users resetting --- .../account_reset/pending_controller_spec.rb | 23 ++++++++++++++++ .../account_reset/grant_request_spec.rb | 2 +- .../grant_requests_and_send_emails_spec.rb | 27 +++++++++---------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/spec/controllers/account_reset/pending_controller_spec.rb b/spec/controllers/account_reset/pending_controller_spec.rb index b143043ab9a..fa9d0793f21 100644 --- a/spec/controllers/account_reset/pending_controller_spec.rb +++ b/spec/controllers/account_reset/pending_controller_spec.rb @@ -41,6 +41,29 @@ context 'fraud user' do let(:user) { create(:user, :fraud_review_pending) } + context 'fraud wait period not set' do + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(nil) + end + + it 'should have @account_reset_deletion_period to match regular wait period' do + create_account_reset_request_for(user) + + get :confirm + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(controller.view_assigns['account_reset_deletion_period_interval']). + to eq(time_in_hours) + + end + end + it 'should have @account_reset_deletion_period_interval to match fraud wait period' do create_account_reset_request_for(user) diff --git a/spec/services/account_reset/grant_request_spec.rb b/spec/services/account_reset/grant_request_spec.rb index 7cbe0ecb6ab..f87bd5803ea 100644 --- a/spec/services/account_reset/grant_request_spec.rb +++ b/spec/services/account_reset/grant_request_spec.rb @@ -38,7 +38,7 @@ allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). and_return(nil) end - + it 'grants request for all users' do before_waiting_the_full_wait_period(Time.zone.now) do create_account_reset_request_for(user) diff --git a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb index a3585c37a5e..5311dc5e3c3 100644 --- a/spec/services/account_reset/grant_requests_and_send_emails_spec.rb +++ b/spec/services/account_reset/grant_requests_and_send_emails_spec.rb @@ -127,27 +127,27 @@ context 'with fraud wait period set' do it 'does not send notifications before a request wait period is done' do create_account_reset_request_for(user) - + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) expect(notifications_sent).to eq(0) end - + it 'does not send notifications when the request was cancelled' do create_account_reset_request_for(user) cancel_request_for(user) - + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) expect(notifications_sent).to eq(0) end - + it 'should not send if its in between regular wait period and fraud wait period' do before_waiting_the_full_wait_period(now) do create_account_reset_request_for(user) create_account_reset_request_for(user2) end - + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - + expect(notifications_sent).to eq(0) end end @@ -155,34 +155,33 @@ context 'with fraud wait period not set' do before do allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). - and_return(nil) + and_return(nil) end it 'does not send notifications before a request wait period is done' do create_account_reset_request_for(user) - + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) expect(notifications_sent).to eq(0) end - + it 'does not send notifications when the request was cancelled' do create_account_reset_request_for(user) cancel_request_for(user) - + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) expect(notifications_sent).to eq(0) end - + it 'should send if its after regular wait period' do before_waiting_the_full_wait_period(now) do create_account_reset_request_for(user) create_account_reset_request_for(user2) end - + notifications_sent = AccountReset::GrantRequestsAndSendEmails.new.perform(now) - + expect(notifications_sent).to eq(2) end - end end end From dfd065f34f866a73da8eabb7fea87333ea5a86b7 Mon Sep 17 00:00:00 2001 From: Malick Diarra Date: Fri, 22 Mar 2024 13:17:26 -0400 Subject: [PATCH 33/33] Add spec checks for when account reset is nil --- .../account_reset/pending_controller_spec.rb | 5 ++-- .../account_reset/request_controller_spec.rb | 23 +++++++++++++++++++ .../concerns/account_reset_concern_spec.rb | 21 ++++++++++++++++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/spec/controllers/account_reset/pending_controller_spec.rb b/spec/controllers/account_reset/pending_controller_spec.rb index fa9d0793f21..3155f6f56a2 100644 --- a/spec/controllers/account_reset/pending_controller_spec.rb +++ b/spec/controllers/account_reset/pending_controller_spec.rb @@ -44,7 +44,7 @@ context 'fraud wait period not set' do before do allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). - and_return(nil) + and_return(nil) end it 'should have @account_reset_deletion_period to match regular wait period' do @@ -60,10 +60,9 @@ ) expect(controller.view_assigns['account_reset_deletion_period_interval']). to eq(time_in_hours) - end end - + it 'should have @account_reset_deletion_period_interval to match fraud wait period' do create_account_reset_request_for(user) diff --git a/spec/controllers/account_reset/request_controller_spec.rb b/spec/controllers/account_reset/request_controller_spec.rb index 71f9e03ba5f..5077481222c 100644 --- a/spec/controllers/account_reset/request_controller_spec.rb +++ b/spec/controllers/account_reset/request_controller_spec.rb @@ -53,6 +53,29 @@ context 'fraud user' do let(:user) { create(:user, :fraud_review_pending) } + + context 'fraud wait period not set' do + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(nil) + end + + it 'should have @account_reset_deletion_period to match regular wait period' do + stub_sign_in_before_2fa(user) + + get :show + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(controller.view_assigns['account_reset_deletion_period_interval']). + to eq(time_in_hours) + end + end + it 'should have @account_reset_deletion_period_interval to match fraud wait period' do stub_sign_in_before_2fa(user) diff --git a/spec/controllers/concerns/account_reset_concern_spec.rb b/spec/controllers/concerns/account_reset_concern_spec.rb index 5a026a1b9f9..f19a2c97ad1 100644 --- a/spec/controllers/concerns/account_reset_concern_spec.rb +++ b/spec/controllers/concerns/account_reset_concern_spec.rb @@ -33,7 +33,7 @@ def initialize(current_user:) context 'fraud user' do let(:user) { create(:user, :fraud_review_pending) } - it 'should return regular wait time' do + it 'should return fraud wait time' do current_time = Time.zone.now time_in_hours = distance_of_time_in_words( current_time, @@ -44,6 +44,25 @@ def initialize(current_user:) expect(instance.account_reset_deletion_period_interval(user)). to eq(time_in_hours) end + + context 'when account_reset_fraud_user_wait_period_days is nil' do + before do + allow(IdentityConfig.store).to receive(:account_reset_fraud_user_wait_period_days). + and_return(nil) + end + + it 'should return standard reset wait time' do + current_time = Time.zone.now + time_in_hours = distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + expect(instance.account_reset_deletion_period_interval(user)). + to eq(time_in_hours) + end + end end end end