diff --git a/app/assets/stylesheets/components/_spinner.scss b/app/assets/stylesheets/components/_spinner.scss new file mode 100644 index 00000000000..d86fd6a0b2c --- /dev/null +++ b/app/assets/stylesheets/components/_spinner.scss @@ -0,0 +1,5 @@ +.spinner { + margin-left: auto; + margin-right: auto; + width: 144px; +} diff --git a/app/assets/stylesheets/components/_util.scss b/app/assets/stylesheets/components/_util.scss index e7eae1c18a6..c81c2666c03 100644 --- a/app/assets/stylesheets/components/_util.scss +++ b/app/assets/stylesheets/components/_util.scss @@ -6,6 +6,8 @@ .invisible { visibility: hidden; } +.hidden { display: none; } + .truncate-inline { max-width: 80%; overflow: hidden; diff --git a/app/assets/stylesheets/components/all.scss b/app/assets/stylesheets/components/all.scss index 1165aafc80f..bb7b20f5809 100644 --- a/app/assets/stylesheets/components/all.scss +++ b/app/assets/stylesheets/components/all.scss @@ -23,6 +23,7 @@ @import 'accordion'; @import 'util'; @import 'verification-badge'; +@import 'spinner'; @import 'space-addon'; @import 'space-misc'; diff --git a/app/views/shared/_spinner.html.slim b/app/views/shared/_spinner.html.slim new file mode 100644 index 00000000000..1a0ae2c6689 --- /dev/null +++ b/app/views/shared/_spinner.html.slim @@ -0,0 +1,18 @@ +.spinner.hidden + div + = image_tag(asset_url('spinner.gif'), + srcset: asset_url('spinner@2x.gif'), + height: 144, + width: 144, + alt: '') +- nonce = content_security_policy_script_nonce += nonced_javascript_tag do + | var nonce="#{ nonce }"; + | document.addEventListener('DOMContentLoaded', () => { + | const button = document.querySelector('.no-spinner'); + | const info = document.querySelector('.spinner'); + | button.addEventListener('click', () => { + | button.classList.add('hidden'); + | info.classList.remove('hidden'); + | }); + | }); diff --git a/app/views/two_factor_authentication/piv_cac_verification/show.html.slim b/app/views/two_factor_authentication/piv_cac_verification/show.html.slim index eb7143187c1..544211b0c88 100644 --- a/app/views/two_factor_authentication/piv_cac_verification/show.html.slim +++ b/app/views/two_factor_authentication/piv_cac_verification/show.html.slim @@ -1,11 +1,12 @@ - title t('titles.present_piv_cac') h1.h3.my0 = @presenter.header -p.mt-tiny.mb3 = @presenter.help_text - -= link_to @presenter.piv_cac_capture_text, - @presenter.piv_cac_service_link, - class: 'btn btn-primary' +.no-spinner + p.mt-tiny.mb3 = @presenter.help_text + = link_to @presenter.piv_cac_capture_text, + @presenter.piv_cac_service_link, + class: 'btn btn-primary activate-spinner' += render 'shared/spinner' = render 'shared/fallback_links', presenter: @presenter = render 'shared/cancel', link: @presenter.cancel_link diff --git a/app/views/users/piv_cac_authentication_setup/new.html.slim b/app/views/users/piv_cac_authentication_setup/new.html.slim index 51f1aba2252..dff8a0ead84 100644 --- a/app/views/users/piv_cac_authentication_setup/new.html.slim +++ b/app/views/users/piv_cac_authentication_setup/new.html.slim @@ -1,11 +1,12 @@ - title @presenter.title h1.h3.my0 = @presenter.heading -p.mt-tiny.mb3 = @presenter.description +.no-spinner + p.mt-tiny.mb3 = @presenter.description -= link_to @presenter.piv_cac_capture_text, - @presenter.piv_cac_service_link, - class: 'btn btn-primary' -= render 'shared/cancel_or_back_to_options' + = link_to @presenter.piv_cac_capture_text, + @presenter.piv_cac_service_link, + class: 'btn btn-primary activate-spinner' -== javascript_pack_tag 'clipboard' += render 'shared/spinner' += render 'shared/cancel_or_back_to_options' diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 02a59f0e42d..0f56c8f2fa3 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -103,6 +103,7 @@ ignore_unused: - 'devise.two_factor_authentication.max_otp_login_attempts_reached' - 'devise.two_factor_authentication.max_otp_requests_reached' - 'devise.two_factor_authentication.max_personal_key_login_attempts_reached' + - 'devise.two_factor_authentication.max_piv_cac_login_attempts_reached' - 'devise.two_factor_authentication.phone_sms_info_html' - 'devise.two_factor_authentication.phone_sms_label' - 'devise.two_factor_authentication.phone_voice_info_html' diff --git a/config/locales/devise/en.yml b/config/locales/devise/en.yml index bea36b559c3..2f25bd393b2 100644 --- a/config/locales/devise/en.yml +++ b/config/locales/devise/en.yml @@ -97,6 +97,9 @@ en: max_personal_key_login_attempts_reached: For your security, your account is temporarily locked because you have entered the personal key incorrectly too many times. + max_piv_cac_login_attempts_reached: For your security, your account is temporarily + locked because you have presented your piv/cac credential incorrectly too + many times. otp_delivery_preference: instruction: You can change this selection the next time you log in. If you entered a landline, please select "Phone call" below. diff --git a/config/locales/devise/es.yml b/config/locales/devise/es.yml index a6e6b540d1e..ab6d32c6982 100644 --- a/config/locales/devise/es.yml +++ b/config/locales/devise/es.yml @@ -99,6 +99,7 @@ es: max_personal_key_login_attempts_reached: Para su seguridad, su cuenta ha sido bloqueada temporalmente porque ha ingresado incorrectamente la clave personal demasiadas veces. + max_piv_cac_login_attempts_reached: NOT TRANSLATED YET otp_delivery_preference: instruction: Puede cambiar esta selección la próxima vez que inicie sesión. phone_unsupported: NOT TRANSLATED YET diff --git a/config/locales/devise/fr.yml b/config/locales/devise/fr.yml index 5c9e2ffea5f..07d87cb707b 100644 --- a/config/locales/devise/fr.yml +++ b/config/locales/devise/fr.yml @@ -106,6 +106,7 @@ fr: max_personal_key_login_attempts_reached: Pour votre sécurité, votre compte est temporairement verrouillé, car vous avez entré le code de sécurité à utilisation unique de façon erronée à de trop nombreuses reprises. + max_piv_cac_login_attempts_reached: NOT TRANSLATED YET otp_delivery_preference: instruction: Vous pouvez changer cette sélection la prochaine fois que vous vous connectez.