diff --git a/app/controllers/account_reset/pending_controller.rb b/app/controllers/account_reset/pending_controller.rb index 77ca7da3f05..855a6e12452 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 ActionView::Helpers::DateHelper before_action :authenticate_user before_action :confirm_account_reset_request_exists @@ -10,7 +11,9 @@ def show @pending_presenter = AccountReset::PendingPresenter.new(pending_account_reset_request) end - def confirm; end + def confirm + @account_reset_deletion_period_interval = account_reset_deletion_period_interval + end def cancel analytics.pending_account_reset_cancelled @@ -29,5 +32,16 @@ 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 9c0f9dd3099..afc55e4df98 100644 --- a/app/controllers/account_reset/request_controller.rb +++ b/app/controllers/account_reset/request_controller.rb @@ -1,11 +1,13 @@ module AccountReset class RequestController < ApplicationController include TwoFactorAuthenticatable + include ActionView::Helpers::DateHelper before_action :confirm_two_factor_enabled def show analytics.account_reset_visit + @account_reset_deletion_period_interval = account_reset_deletion_period_interval end def create @@ -39,5 +41,16 @@ 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/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index cc49ebb6a47..486a77e9d5b 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 ActionView::Helpers::DateHelper class UserEmailAddressMismatchError < StandardError; end @@ -149,7 +150,11 @@ def personal_key_regenerated def account_reset_request(account_reset) with_user_locale(user) do @token = account_reset&.request_token - @header = t('user_mailer.account_reset_request.header') + @account_reset_deletion_period_hours = account_reset_deletion_period_hours + @header = t( + 'user_mailer.account_reset_request.header', + interval: account_reset_deletion_period_interval, + ) mail( to: email_address.email, subject: t('user_mailer.account_reset_request.subject', app_name: APP_NAME), @@ -161,6 +166,8 @@ 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_token_valid_period = account_reset_token_valid_period mail( to: email_address.email, subject: t('user_mailer.account_reset_granted.subject', app_name: APP_NAME), @@ -430,4 +437,30 @@ def email_should_receive_nonessential_notifications?(email) modified_email = email.gsub(/\+[^@]+@/, '@') !banlist.include?(modified_email) 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 + + def account_reset_deletion_period_hours + IdentityConfig.store.account_reset_wait_period_days.days.in_hours.to_i + end + + def account_reset_token_valid_period + current_time = Time.zone.now + + distance_of_time_in_words( + current_time, + current_time + IdentityConfig.store.account_reset_token_valid_for_days.days, + true, + accumulate_on: :hours, + ) + end end diff --git a/app/presenters/account_reset/pending_presenter.rb b/app/presenters/account_reset/pending_presenter.rb index c93eca3a809..636b7bcd081 100644 --- a/app/presenters/account_reset/pending_presenter.rb +++ b/app/presenters/account_reset/pending_presenter.rb @@ -18,5 +18,9 @@ def time_remaining_until_granted(now: Time.zone.now) highest_measures: 2, ) end + + def account_reset_deletion_period_hours + IdentityConfig.store.account_reset_wait_period_days.days.in_hours.to_i + end end end diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index da9b171d195..0d9556a4168 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -115,7 +115,10 @@ def account_reset_url(locale:) def account_reset_cancel_link safe_join( [ - t('two_factor_authentication.account_reset.pending'), + t( + 'two_factor_authentication.account_reset.pending', + interval: account_reset_deletion_period_interval, + ), @view.link_to( t('two_factor_authentication.account_reset.cancel_link'), account_reset_cancel_url(token: account_reset_token), @@ -140,4 +143,15 @@ 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 + IdentityConfig.store.account_reset_wait_period_days.days, + true, + accumulate_on: :hours, + ) + end end diff --git a/app/services/account_reset/create_request.rb b/app/services/account_reset/create_request.rb index 7d2dba04e4e..bbe2d05de2b 100644 --- a/app/services/account_reset/create_request.rb +++ b/app/services/account_reset/create_request.rb @@ -1,5 +1,7 @@ module AccountReset class CreateRequest + include ActionView::Helpers::DateHelper + def initialize(user, requesting_issuer) @user = user @requesting_issuer = requesting_issuer @@ -46,11 +48,23 @@ 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, ) 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/views/account_reset/pending/confirm.html.erb b/app/views/account_reset/pending/confirm.html.erb index b94afed79bc..3c94e90c97c 100644 --- a/app/views/account_reset/pending/confirm.html.erb +++ b/app/views/account_reset/pending/confirm.html.erb @@ -1,6 +1,6 @@ <% self.title = t('account_reset.cancel_request.title') %> -

<%= t('account_reset.pending.confirm') %>

+

<%= t('account_reset.pending.confirm', interval: @account_reset_deletion_period_interval) %>

<%= button_to( account_reset_pending_cancel_path, diff --git a/app/views/account_reset/pending/show.html.erb b/app/views/account_reset/pending/show.html.erb index 14e2f17e86d..ceb730fe1fc 100644 --- a/app/views/account_reset/pending/show.html.erb +++ b/app/views/account_reset/pending/show.html.erb @@ -5,6 +5,7 @@

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

diff --git a/app/views/account_reset/request/show.html.erb b/app/views/account_reset/request/show.html.erb index 58f60653804..9abfd4eab7f 100644 --- a/app/views/account_reset/request/show.html.erb +++ b/app/views/account_reset/request/show.html.erb @@ -8,7 +8,7 @@

<%= t('account_reset.request.delete_account') %>

-<% t('account_reset.request.delete_account_info').each do |info_p| %> +<% t('account_reset.request.delete_account_info', interval: @account_reset_deletion_period_interval).each do |info_p| %>

<%= info_p %>

<% end %> diff --git a/app/views/user_mailer/account_reset_granted.html.erb b/app/views/user_mailer/account_reset_granted.html.erb index d4406c1cec3..70d608be1d9 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', app_name: link_to(APP_NAME, IdentityConfig.store.mailer_domain_name, class: 'gray')) %> + <%= 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')) %>

@@ -47,7 +47,7 @@

- <%= t('user_mailer.email_confirmation_instructions.footer', confirmation_period: '24 hours') %> + <%= t('user_mailer.email_confirmation_instructions.footer', confirmation_period: @account_reset_token_valid_period) %>

<%= t( diff --git a/app/views/user_mailer/account_reset_request.html.erb b/app/views/user_mailer/account_reset_request.html.erb index 6a01b4c808e..d486d654efc 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')) %> + <%= 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) %>

diff --git a/config/locales/account_reset/en.yml b/config/locales/account_reset/en.yml index 39163c283d8..f3fe9cf0d60 100644 --- a/config/locales/account_reset/en.yml +++ b/config/locales/account_reset/en.yml @@ -30,10 +30,10 @@ en: pending: cancel_request: Cancel request cancelled: We have cancelled your request to delete your account. - confirm: If you cancel now, you must create a new request and wait another 24 - hours to delete your account. + 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 24-hour waiting period to delete your account. In + wait_html: There is a %{hours}-hour waiting period to delete your account. In %{interval}, you will receive an email with instructions to complete the deletion. recovery_options: @@ -61,8 +61,8 @@ en: to your account and you will need to restore each connection. - If you continue, you will first receive an email confirmation. As a security measure, you will receive another email with the link to - continue deleting your account 24 hours after the initial confirmation - email arrives. + continue deleting your account %{interval} after the initial + confirmation email arrives. info: - If you can’t access your account using the authentication methods you set up previously, deleting your account and creating a new one is the diff --git a/config/locales/account_reset/es.yml b/config/locales/account_reset/es.yml index 80b4214f4a3..9f8f1dc4317 100644 --- a/config/locales/account_reset/es.yml +++ b/config/locales/account_reset/es.yml @@ -31,11 +31,11 @@ es: pending: cancel_request: Cancelar petición cancelled: Hemos cancelado su solicitud para eliminar su cuenta. - confirm: Si cancela ahora, debe crear una nueva solicitud y esperar otras 24 - horas para eliminar su cuenta. + 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 24 horas para eliminar su cuenta. En - %{interval}, recibirá un correo electrónico con + wait_html: Hay un período de espera de %{hours} horas 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 @@ -65,8 +65,9 @@ es: conexión. - Si continúas, tú primero recibirá una confirmación por correo electrónico. Como medida de seguridad, lo hará reciba otro correo - electrónico con el enlace para seguir eliminando su cuenta las 24 - horas después del correo electrónico de confirmación inicial llega. + electrónico con el enlace para seguir eliminando su cuenta las + %{interval} después del correo electrónico de confirmación inicial + llega. info: - Si no puede acceder a su cuenta a través de las opciones de seguridad que configuró anteriormente, eliminar la cuenta y crear una nueva es diff --git a/config/locales/account_reset/fr.yml b/config/locales/account_reset/fr.yml index 90a29cbe5e0..cd52a50fa08 100644 --- a/config/locales/account_reset/fr.yml +++ b/config/locales/account_reset/fr.yml @@ -32,11 +32,11 @@ fr: cancel_request: Demande d’annulation cancelled: Nous avons annulé votre demande de suppression de votre compte. confirm: Si vous annulez maintenant, vous devez créer une nouvelle demande et - attendre encore 24 heures pour supprimer votre compte. + 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 24 heures 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} heures 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 @@ -65,8 +65,8 @@ fr: devrez restaurer chaque connexion. - Si vous continuez, vous recevra d’abord un email de confirmation. Par mesure de sécurité, vous devrez recevoir un autre e-mail avec le lien - pour continuer la suppression de votre compte 24 heures après l’email - de confirmation initial arrive. + pour continuer la suppression de votre compte %{interval} après + l’email de confirmation initial arrive. info: - Si vous ne pouvez pas accéder à votre compte via les options de sécurité que vous avez définies auparavant, la suppression de votre diff --git a/config/locales/telephony/en.yml b/config/locales/telephony/en.yml index d38ea371145..c8a6b95d05c 100644 --- a/config/locales/telephony/en.yml +++ b/config/locales/telephony/en.yml @@ -3,8 +3,8 @@ en: telephony: account_reset_cancellation_notice: Your request to delete your %{app_name} account has been cancelled. account_reset_notice: As requested, your %{app_name} account will be deleted in - 24 hours. Don't want to delete your account? Sign in to your %{app_name} - account to cancel. + %{interval}. Don't want to delete your account? Sign in to your + %{app_name} account to cancel. authentication_otp: sms: |- %{app_name}: Your one-time code is %{code}. It expires in %{expiration} minutes. Don't share this code with anyone. diff --git a/config/locales/telephony/es.yml b/config/locales/telephony/es.yml index 14b60b64948..37a022203a2 100644 --- a/config/locales/telephony/es.yml +++ b/config/locales/telephony/es.yml @@ -3,7 +3,7 @@ es: telephony: account_reset_cancellation_notice: Su solicitud para eliminar su cuenta de %{app_name} ha sido cancelada. account_reset_notice: Según lo solicitado, su cuenta %{app_name} se eliminará en - 24 horas. ¿No quieres eliminar tu cuenta? Inicie sesión en su cuenta + %{interval}. ¿No quieres eliminar tu cuenta? Inicie sesión en su cuenta %{app_name} para cancelar. authentication_otp: sms: |- diff --git a/config/locales/telephony/fr.yml b/config/locales/telephony/fr.yml index 5e936074fd4..013d8e60358 100644 --- a/config/locales/telephony/fr.yml +++ b/config/locales/telephony/fr.yml @@ -3,8 +3,8 @@ fr: telephony: account_reset_cancellation_notice: Votre demande de suppression de votre compte %{app_name} a été annulée. account_reset_notice: Comme demandé, votre compte %{app_name} sera supprimé dans - les 24 heures. Vous ne voulez pas supprimer votre compte? Connectez-vous à - votre compte %{app_name} pour le annuler. + les %{interval}. Vous ne voulez pas supprimer votre compte? Connectez-vous + à votre compte %{app_name} pour le annuler. authentication_otp: sms: |- %{app_name}: Votre code à usage unique est %{code}. Il est valable pendant %{expiration} minutes. Vous ne devez pas partager ce code avec personne. diff --git a/config/locales/two_factor_authentication/en.yml b/config/locales/two_factor_authentication/en.yml index 58a35387be8..ce76ea169cf 100644 --- a/config/locales/two_factor_authentication/en.yml +++ b/config/locales/two_factor_authentication/en.yml @@ -11,7 +11,7 @@ en: cancel_link: Cancel your request link: deleting your account pending: You currently have a pending request to delete your account. It takes - 24 hours from the time you made the request to complete the process. + %{interval} from the time you made the request to complete the process. Please check back later. successful_cancel: Thank you. Your request to delete your %{app_name} account has been cancelled. diff --git a/config/locales/two_factor_authentication/es.yml b/config/locales/two_factor_authentication/es.yml index 82c91b63c8c..a2c3917f26f 100644 --- a/config/locales/two_factor_authentication/es.yml +++ b/config/locales/two_factor_authentication/es.yml @@ -11,7 +11,7 @@ es: cancel_link: Cancelar su solicitud link: eliminando su cuenta pending: Actualmente tiene una solicitud pendiente para eliminar su cuenta. Se - necesitan 24 horas desde el momento en que realizó la solicitud para + necesitan %{interval} desde el momento en que realizó la solicitud para completar el proceso. Por favor, vuelva más tarde. successful_cancel: Gracias. Su solicitud para eliminar su cuenta de %{app_name} ha sido cancelada. diff --git a/config/locales/two_factor_authentication/fr.yml b/config/locales/two_factor_authentication/fr.yml index 7dce721c210..f6506249522 100644 --- a/config/locales/two_factor_authentication/fr.yml +++ b/config/locales/two_factor_authentication/fr.yml @@ -13,7 +13,7 @@ fr: cancel_link: Annuler votre demande link: supprimer votre compte pending: Vous avez actuellement une demande en attente pour supprimer votre - compte. Il faut compter 24 heures à partir du moment où vous avez fait + compte. Il faut compter %{interval} à partir du moment où vous avez fait la demande pour terminer le processus. Veuillez vérifier plus tard. successful_cancel: Je vous remercie. Votre demande de suppression de votre compte %{app_name} a été annulée. diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index aaa84453c1f..cf40ca71f44 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -20,26 +20,26 @@ 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 24 hour 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 new - %{app_name} account using the same email address after your account is - deleted.

+ intro_html: Your %{hours} hour 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 + new %{app_name} account using the same email address after your account + is deleted.

subject: Delete your %{app_name} account account_reset_request: cancel: Don’t want to delete your account? Sign in to your %{app_name} account to cancel. - header: Your account will be deleted in 24 hours + 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 24 hour 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 24 hour 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 %{hours} hour 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 + 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 7c63447255d..81426f955b4 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 24 horas 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 %{hours} horas 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 sitios web gubernamentales participantes que utilizan %{app_name}, puede @@ -33,15 +33,15 @@ es: account_reset_request: cancel: '¿No quieres eliminar tu cuenta? Inicie sesión en su cuenta %{app_name} para cancelar.' - header: Su cuenta será eliminada en 24 horas + 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 24 horas si ha perdido el acceso a sus métodos de + espera de %{hours} horas 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 24 horas, recibirá un correo electrónico que le pedirá que - confirme la eliminación de su cuenta %{app_name}. Su cuenta no se + espera de %{hours} horas, 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: diff --git a/config/locales/user_mailer/fr.yml b/config/locales/user_mailer/fr.yml index b0a9337a88a..8b7b7c95872 100644 --- a/config/locales/user_mailer/fr.yml +++ b/config/locales/user_mailer/fr.yml @@ -22,28 +22,29 @@ 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 24 heures 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}.

À l’avenir, si vous - devez accéder aux sites Web gouvernementaux participants qui utilisent - %{app_name}, vous pouvez créer un nouveau compte %{app_name} en - utilisant la même adresse e-mail après la suppression de votre - compte.

+ intro_html: Votre période d’attente de %{hours} heures 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}.

À + l’avenir, si vous devez accéder aux sites Web gouvernementaux + participants qui utilisent %{app_name}, vous pouvez créer un nouveau + compte %{app_name} en utilisant la même adresse e-mail après la + suppression de votre compte.

subject: Supprimer votre compte %{app_name} account_reset_request: cancel: Vous ne voulez pas supprimer votre compte? Connectez-vous à votre compte %{app_name} pour annuler. - header: Votre compte sera supprimé dans 24 heures + 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 24 heures 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 24 heures, 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é.' + période d’attente de %{hours} heures 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 + 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} account_verified: change_password_link: changer votre mot de passe diff --git a/lib/telephony/alert_sender.rb b/lib/telephony/alert_sender.rb index 9771a7d5975..b202e5bbfc1 100644 --- a/lib/telephony/alert_sender.rb +++ b/lib/telephony/alert_sender.rb @@ -2,8 +2,11 @@ module Telephony class AlertSender SMS_MAX_LENGTH = 160 - def send_account_reset_notice(to:, country_code:) - message = I18n.t('telephony.account_reset_notice', app_name: APP_NAME) + def send_account_reset_notice(to:, country_code:, interval:) + message = I18n.t( + 'telephony.account_reset_notice', app_name: APP_NAME, + interval: interval + ) response = adapter.deliver(message: message, to: to, country_code: country_code) log_response(response, context: __method__.to_s.gsub(/^send_/, '')) response @@ -86,4 +89,15 @@ def log_warning(alert, context:) ) end end + + def confirmation_period + current_time = Time.zone.now + + view.distance_of_time_in_words( + current_time, + current_time + Devise.confirm_within, + true, + accumulate_on: :hours, + ) + end end diff --git a/spec/lib/telephony/alert_sender_spec.rb b/spec/lib/telephony/alert_sender_spec.rb index f13cf648adf..01616c6e797 100644 --- a/spec/lib/telephony/alert_sender_spec.rb +++ b/spec/lib/telephony/alert_sender_spec.rb @@ -3,6 +3,7 @@ RSpec.describe Telephony::AlertSender do let(:configured_adapter) { :test } let(:recipient) { '+1 (202) 555-5000' } + let(:interval) { '24 hours' } before do allow(Telephony.config).to receive(:adapter).and_return(configured_adapter) @@ -11,12 +12,12 @@ describe 'send_account_reset_notice' do it 'sends the correct message' do - subject.send_account_reset_notice(to: recipient, country_code: 'US') + subject.send_account_reset_notice(to: recipient, country_code: 'US', interval: interval) last_message = Telephony::Test::Message.messages.last expect(last_message.to).to eq(recipient) expect(last_message.body).to eq( - I18n.t('telephony.account_reset_notice', app_name: APP_NAME), + I18n.t('telephony.account_reset_notice', app_name: APP_NAME, interval: interval), ) end end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index a49ff10a5d1..730aa2eb257 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -339,6 +339,8 @@ def expect_email_body_to_have_help_and_contact_links end let(:account_reset) { user.account_reset_request } + let(:interval) { '24 hours' } + let(:account_reset_deletion_period_hours) { 24 } it_behaves_like 'a system email' it_behaves_like 'an email that respects user email locale preference' @@ -354,11 +356,19 @@ def expect_email_body_to_have_help_and_contact_links it 'renders the body' do expect(mail.html_part.body).to have_content( strip_tags( - t('user_mailer.account_reset_request.intro_html', app_name: APP_NAME), + t( + 'user_mailer.account_reset_request.intro_html', app_name: APP_NAME, + interval: interval, + hours: + account_reset_deletion_period_hours + ), ), ) end + it 'renders the footer' do + end + it 'does not render the subject in the body' do expect(mail.html_part.body).not_to have_content( strip_tags( @@ -370,7 +380,7 @@ def expect_email_body_to_have_help_and_contact_links it 'renders the header within the body' do expect(mail.html_part.body).to have_content( strip_tags( - t('user_mailer.account_reset_request.header'), + t('user_mailer.account_reset_request.header', interval: interval), ), ) end @@ -381,6 +391,8 @@ 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(:token_expiration_interval) { '24 hours' } it_behaves_like 'a system email' it_behaves_like 'an email that respects user email locale preference' @@ -390,13 +402,33 @@ def expect_email_body_to_have_help_and_contact_links end it 'renders the subject' do - expect(mail.subject).to eq t('user_mailer.account_reset_granted.subject', app_name: APP_NAME) + expect(mail.subject).to eq t( + 'user_mailer.account_reset_granted.subject', app_name: APP_NAME + ) end it 'renders the body' do expect(mail.html_part.body).to \ have_content( - strip_tags(t('user_mailer.account_reset_granted.intro_html', app_name: APP_NAME)), + strip_tags( + t( + 'user_mailer.account_reset_granted.intro_html', app_name: APP_NAME, + hours: + account_reset_deletion_period_hours + ), + ), + ) + end + + it 'renders the footer' do + expect(mail.html_part.body).to \ + have_content( + strip_tags( + t( + 'user_mailer.email_confirmation_instructions.footer', + confirmation_period: token_expiration_interval, + ), + ), ) end end diff --git a/spec/presenters/two_factor_login_options_presenter_spec.rb b/spec/presenters/two_factor_login_options_presenter_spec.rb index 79be918a647..14da580896f 100644 --- a/spec/presenters/two_factor_login_options_presenter_spec.rb +++ b/spec/presenters/two_factor_login_options_presenter_spec.rb @@ -55,14 +55,12 @@ end it 'supplies a cancel link when the token is valid' do - allow_any_instance_of(TwoFactorLoginOptionsPresenter).to \ - receive(:account_reset_token_valid?).and_return(true) - - allow_any_instance_of(TwoFactorLoginOptionsPresenter).to \ - receive(:account_reset_token).and_return('foo') + allow(presenter).to receive(:account_reset_token).and_return('foo') + allow(presenter).to receive(:account_reset_token_valid?).and_return(true) + allow(presenter).to receive(:confirmation_period).and_return('24 hours') expect(presenter.account_reset_or_cancel_link).to eq( - t('two_factor_authentication.account_reset.pending') + ' ' + + t('two_factor_authentication.account_reset.pending', interval: '24 hours') + ' ' + view.link_to( t('two_factor_authentication.account_reset.cancel_link'), account_reset_cancel_url(token: 'foo'),