diff --git a/app/policies/service_provider_mfa_policy.rb b/app/policies/service_provider_mfa_policy.rb
index 156bc9882a5..fdf62e5a694 100644
--- a/app/policies/service_provider_mfa_policy.rb
+++ b/app/policies/service_provider_mfa_policy.rb
@@ -50,12 +50,6 @@ def piv_cac_required?
piv_cac_requested?
end
- def allow_user_to_switch_method?
- return false if piv_cac_required?
- return true unless phishing_resistant_required?
- piv_cac_enabled? && webauthn_enabled?
- end
-
def multiple_factors_enabled?
mfa_context.enabled_mfa_methods_count > 1
end
diff --git a/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb b/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb
index 5e353266e90..5bb04e1b33c 100644
--- a/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb
+++ b/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb
@@ -4,7 +4,7 @@ class GenericDeliveryPresenter
include ActionView::Helpers::TranslationHelper
include Rails.application.routes.url_helpers
- attr_reader :code_value, :reauthn
+ attr_reader :code_value, :reauthn, :service_provider
def initialize(data:, view:, service_provider:, remember_device_default: true)
data.each do |key, value|
@@ -19,26 +19,18 @@ def header
raise NotImplementedError
end
- def link_text
- t('two_factor_authentication.login_options_link_text')
- end
-
- def link_path
- login_two_factor_options_path
- end
-
def redirect_location_step; end
def troubleshooting_options
[
choose_another_method_troubleshooting_option,
learn_more_about_authentication_options_troubleshooting_option,
- ].select(&:present?)
+ ]
end
def choose_another_method_troubleshooting_option
- return if link_path.blank?
- BlockLinkComponent.new(url: link_path).with_content(link_text)
+ BlockLinkComponent.new(url: login_two_factor_options_path).
+ with_content(t('two_factor_authentication.login_options_link_text'))
end
def learn_more_about_authentication_options_troubleshooting_option
diff --git a/app/presenters/two_factor_auth_code/piv_cac_authentication_presenter.rb b/app/presenters/two_factor_auth_code/piv_cac_authentication_presenter.rb
index d1d13877e87..4e77b7851ad 100644
--- a/app/presenters/two_factor_auth_code/piv_cac_authentication_presenter.rb
+++ b/app/presenters/two_factor_auth_code/piv_cac_authentication_presenter.rb
@@ -6,55 +6,10 @@ def header
t('two_factor_authentication.piv_cac_header_text')
end
- def piv_cac_help
- if service_provider_mfa_policy.phishing_resistant_required? &&
- service_provider_mfa_policy.allow_user_to_switch_method?
- t('instructions.mfa.piv_cac.confirm_piv_cac_or_aal3')
- elsif service_provider_mfa_policy.phishing_resistant_required? ||
- service_provider_mfa_policy.piv_cac_required?
- t('instructions.mfa.piv_cac.confirm_piv_cac_only')
- else
- t('instructions.mfa.piv_cac.confirm_piv_cac')
- end
- end
-
def piv_cac_capture_text
t('forms.piv_cac_mfa.submit')
end
- def link_text
- if service_provider_mfa_policy.phishing_resistant_required?
- if service_provider_mfa_policy.allow_user_to_switch_method?
- t('two_factor_authentication.piv_cac_webauthn_available')
- else
- ''
- end
- else
- super
- end
- end
-
- def link_path
- if service_provider_mfa_policy.phishing_resistant_required?
- if service_provider_mfa_policy.allow_user_to_switch_method?
- login_two_factor_webauthn_url
- else
- ''
- end
- else
- super
- end
- end
-
- def troubleshooting_options
- options = []
- if service_provider_mfa_policy.allow_user_to_switch_method?
- options << choose_another_method_troubleshooting_option
- end
- options << learn_more_about_authentication_options_troubleshooting_option
- options
- end
-
def cancel_link
if reauthn
account_path
diff --git a/app/presenters/two_factor_auth_code/webauthn_authentication_presenter.rb b/app/presenters/two_factor_auth_code/webauthn_authentication_presenter.rb
index 8778ad578a9..392f2a06d91 100644
--- a/app/presenters/two_factor_auth_code/webauthn_authentication_presenter.rb
+++ b/app/presenters/two_factor_auth_code/webauthn_authentication_presenter.rb
@@ -17,12 +17,7 @@ def initialize(data:, view:, service_provider:, remember_device_default: true,
end
def webauthn_help
- if service_provider_mfa_policy.phishing_resistant_required? &&
- service_provider_mfa_policy.allow_user_to_switch_method?
- t('instructions.mfa.webauthn.confirm_webauthn_or_aal3')
- elsif service_provider_mfa_policy.phishing_resistant_required?
- t('instructions.mfa.webauthn.confirm_webauthn_only')
- elsif platform_authenticator?
+ if platform_authenticator?
t('instructions.mfa.webauthn.confirm_webauthn_platform', app_name: APP_NAME)
else
t('instructions.mfa.webauthn.confirm_webauthn')
@@ -45,32 +40,8 @@ def header
end
end
- def link_text
- if service_provider_mfa_policy.phishing_resistant_required?
- if service_provider_mfa_policy.allow_user_to_switch_method?
- t('two_factor_authentication.webauthn_piv_available')
- else
- ''
- end
- else
- super
- end
- end
-
- def link_path
- if service_provider_mfa_policy.phishing_resistant_required?
- if service_provider_mfa_policy.allow_user_to_switch_method?
- login_two_factor_piv_cac_url
- else
- ''
- end
- else
- super
- end
- end
-
def troubleshooting_options
- options = [choose_another_method_troubleshooting_option].select(&:present?)
+ options = [choose_another_method_troubleshooting_option]
if platform_authenticator?
options << BlockLinkComponent.new(
url: help_center_redirect_path(
diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb
index fca7e808f19..355e06fc5ad 100644
--- a/app/presenters/two_factor_login_options_presenter.rb
+++ b/app/presenters/two_factor_login_options_presenter.rb
@@ -1,7 +1,10 @@
class TwoFactorLoginOptionsPresenter < TwoFactorAuthCode::GenericDeliveryPresenter
include ActionView::Helpers::TranslationHelper
- attr_reader :user
+ attr_reader :user, :phishing_resistant_required, :piv_cac_required
+
+ alias_method :phishing_resistant_required?, :phishing_resistant_required
+ alias_method :piv_cac_required?, :piv_cac_required
def initialize(
user:,
@@ -31,6 +34,14 @@ def info
t('two_factor_authentication.login_intro')
end
+ def restricted_options_warning_text
+ if piv_cac_required?
+ t('two_factor_authentication.aal2_request.piv_cac_only_html', sp_name:)
+ elsif phishing_resistant_required?
+ t('two_factor_authentication.aal2_request.phishing_resistant_html', sp_name:)
+ end
+ end
+
def options
mfa = MfaContext.new(user)
@@ -107,4 +118,12 @@ def account_reset_token
def account_reset_token_valid?
user&.account_reset_request&.granted_token_valid?
end
+
+ def sp_name
+ if service_provider
+ service_provider.friendly_name
+ else
+ APP_NAME
+ end
+ end
end
diff --git a/app/views/two_factor_authentication/options/index.html.erb b/app/views/two_factor_authentication/options/index.html.erb
index 6983bca9aba..63d8d8ab883 100644
--- a/app/views/two_factor_authentication/options/index.html.erb
+++ b/app/views/two_factor_authentication/options/index.html.erb
@@ -8,6 +8,12 @@
<%= @presenter.info %>
+<% if @presenter.restricted_options_warning_text.present? %>
+ <%= render AlertComponent.new(type: :warning, class: 'margin-top-4') do %>
+ <%= @presenter.restricted_options_warning_text %>
+ <% end %>
+<% end %>
+
<%= simple_form_for(
@two_factor_options_form,
html: { autocomplete: 'off' },
diff --git a/app/views/two_factor_authentication/piv_cac_verification/show.html.erb b/app/views/two_factor_authentication/piv_cac_verification/show.html.erb
index b1938bb4afb..2608296466a 100644
--- a/app/views/two_factor_authentication/piv_cac_verification/show.html.erb
+++ b/app/views/two_factor_authentication/piv_cac_verification/show.html.erb
@@ -3,7 +3,7 @@
<%= render PageHeadingComponent.new.with_content(@presenter.header) %>
- <%= @presenter.piv_cac_help %>
+ <%= t('instructions.mfa.piv_cac.confirm_piv_cac') %>
diff --git a/config/locales/instructions/en.yml b/config/locales/instructions/en.yml
index b09dda48ba9..b414a32ed19 100644
--- a/config/locales/instructions/en.yml
+++ b/config/locales/instructions/en.yml
@@ -37,12 +37,6 @@ en:
you think this is an error, %{try_again_html}.
back_to_sign_in: Go back to sign in
confirm_piv_cac: Present the PIV/CAC that you associated with your account.
- confirm_piv_cac_only: This app requires a higher level of security. You need to
- verify your identity using a government employee ID that you
- previously set up to access your information.
- confirm_piv_cac_or_aal3: This app requires a higher level of security. You need
- to verify your identity using a physical device such as a security key
- or government employee ID (PIV or CAC) to access your information.
did_not_work_html: Please %{please_try_again_html}. If this problem continues,
contact your agency administrator.
http_failure: The server took too long to respond. Please try again.
@@ -72,12 +66,6 @@ en:
code will expire in %{expiration} minutes.
webauthn:
confirm_webauthn: Present the security key that you associated with your account.
- confirm_webauthn_only: This app requires a higher level of security. You need to
- verify your identity using a security key that you previously set up
- to access your information.
- confirm_webauthn_or_aal3: This app requires a higher level of security. You need
- to verify your identity using a physical device such as a security key
- or government employee ID (PIV or CAC) to access your information.
confirm_webauthn_platform: You have face or touch unlock enabled for your %{app_name} account.
webauthn_platform:
learn_more_help: Learn more about face or touch unlock
diff --git a/config/locales/instructions/es.yml b/config/locales/instructions/es.yml
index d98d0e83add..e18e74d0dd2 100644
--- a/config/locales/instructions/es.yml
+++ b/config/locales/instructions/es.yml
@@ -39,13 +39,6 @@ es:
día. Si cree que se trata de un error, %{try_again_html}.
back_to_sign_in: Regrese para iniciar sesión
confirm_piv_cac: Presenta la PIV/CAC que asociaste con tu cuenta.
- confirm_piv_cac_only: Esta aplicación requiere un mayor nivel de seguridad. Debe
- verificar su identidad con una identificación de empleado del Gobierno
- que haya configurado previamente para acceder a su información.
- confirm_piv_cac_or_aal3: Esta aplicación requiere un mayor nivel de seguridad.
- Debe verificar su identidad con un dispositivo físico, como una llave
- de seguridad o una identificación de empleado del Gobierno (PIV o CAC)
- para acceder a su información.
did_not_work_html: '%{please_try_again_html}. Comuníquese con el encargado de su
organismo si persiste este problema.'
http_failure: El servidor tardó demasiado en responder. Inténtalo de nuevo.
@@ -75,13 +68,6 @@ es:
%{number_html}. Este código expirará en %{expiration} minutos.
webauthn:
confirm_webauthn: Presente la clave de seguridad que asoció con su cuenta.
- confirm_webauthn_only: Esta aplicación requiere un mayor nivel de seguridad.
- Debe verificar su identidad con una llave de seguridad que haya
- configurado previamente para acceder a su información.
- confirm_webauthn_or_aal3: Esta aplicación requiere un mayor nivel de seguridad.
- Debe verificar su identidad con un dispositivo físico, como una llave
- de seguridad o una identificación de empleado del Gobierno (PIV o CAC)
- para acceder a su información.
confirm_webauthn_platform: Tiene activado el desbloqueo facial o táctil para su
cuenta de %{app_name}.
webauthn_platform:
diff --git a/config/locales/instructions/fr.yml b/config/locales/instructions/fr.yml
index 15a7213007c..dddca997dd2 100644
--- a/config/locales/instructions/fr.yml
+++ b/config/locales/instructions/fr.yml
@@ -45,14 +45,6 @@ fr:
back_to_sign_in: Retourner à vous connecter
confirm_piv_cac: Veuillez présenter la carte PIV/CAC que vous avez associée à
votre compte.
- confirm_piv_cac_only: Cette application nécessite un niveau de sécurité plus
- élevé. Vous devez vérifier votre identité à l’aide d’un badge
- d’employé du gouvernement que vous avez précédemment configuré pour
- accéder à vos informations.
- confirm_piv_cac_or_aal3: Cette application nécessite un niveau de sécurité plus
- élevé. Vous devez vérifier votre identité à l’aide d’un dispositif
- physique tel qu’une clé de sécurité ou un badge d’employé du
- gouvernement (PIV ou CAC) pour accéder à vos informations.
did_not_work_html: Veuillez %{please_try_again_html}. Si ce problème persiste,
contactez l’administrateur de votre agence.
http_failure: Le serveur a mis trop de temps à répondre. Veuillez réessayer.
@@ -85,14 +77,6 @@ fr:
%{number_html}. Ce code expirera dans %{expiration} minutes.
webauthn:
confirm_webauthn: Présentez la clé de sécurité associée à votre compte.
- confirm_webauthn_only: Cette application nécessite un niveau de sécurité plus
- élevé. Vous devez vérifier votre identité à l’aide d’une clé de
- sécurité que vous avez précédemment configurée pour accéder à vos
- informations.
- confirm_webauthn_or_aal3: Cette application nécessite un niveau de sécurité plus
- élevé. Vous devez vérifier votre identité à l’aide d’un dispositif
- physique tel qu’une clé de sécurité ou un badge d’employé du
- gouvernement (PIV ou CAC) pour accéder à vos informations.
confirm_webauthn_platform: Vous avez activé le déverrouillage facial ou tactile
pour votre compte %{app_name}.
webauthn_platform:
diff --git a/config/locales/two_factor_authentication/en.yml b/config/locales/two_factor_authentication/en.yml
index 047133f4f0e..aef059683ee 100644
--- a/config/locales/two_factor_authentication/en.yml
+++ b/config/locales/two_factor_authentication/en.yml
@@ -1,6 +1,12 @@
---
en:
two_factor_authentication:
+ aal2_request:
+ phishing_resistant_html: '%{sp_name} requires a high-security
+ authentication method, such as face or touch unlock, a security key or a
+ government employee ID.'
+ piv_cac_only_html: '%{sp_name} requires your government
+ employee ID, a high-security authentication method.'
account_reset:
cancel_link: Cancel your request
link: deleting your account
@@ -124,7 +130,6 @@ en:
change_number: Use another phone number
code_not_received: I didn’t receive my one-time code
piv_cac_header_text: Present your PIV/CAC
- piv_cac_webauthn_available: Use your security key
please_try_again_html: Please try again in %{countdown}.
read_about_two_factor_authentication: Read about two-factor authentication
recaptcha:
@@ -178,7 +183,6 @@ en:
additional_methods_link: choose another authentication method
try_again: Face or touch unlock was unsuccessful. Please try again or %{link}.
webauthn_header_text: Connect your security key
- webauthn_piv_available: Use your PIV or CAC
webauthn_platform_header_text: Use face or touch unlock
webauthn_platform_use_key: Use face or touch unlock
webauthn_use_key: Use security key
diff --git a/config/locales/two_factor_authentication/es.yml b/config/locales/two_factor_authentication/es.yml
index 86482e50eb4..d597d6d7673 100644
--- a/config/locales/two_factor_authentication/es.yml
+++ b/config/locales/two_factor_authentication/es.yml
@@ -1,6 +1,12 @@
---
es:
two_factor_authentication:
+ aal2_request:
+ phishing_resistant_html: '%{sp_name} requiere un método de
+ autenticación de alta seguridad, como el desbloqueo facial o táctil, una
+ llave de seguridad o una identificación de empleado público.'
+ piv_cac_only_html: '%{sp_name} requiere su identificación de
+ empleado público, un método de autenticación de alta seguridad.'
account_reset:
cancel_link: Cancelar su solicitud
link: eliminando su cuenta
@@ -132,7 +138,6 @@ es:
change_number: Utilice otro número de teléfono.
code_not_received: No recibí mi código de un solo uso.
piv_cac_header_text: Presenta tu PIV/CAC
- piv_cac_webauthn_available: Utilice su llave de seguridad
please_try_again_html: Inténtelo de nuevo en %{countdown}.
read_about_two_factor_authentication: Conozca la autenticación de dos factores
recaptcha:
@@ -193,7 +198,6 @@ es:
try_again: El desbloqueo facial o táctil no fue exitoso. Por favor, inténtelo de
nuevo o %{link}.
webauthn_header_text: Conecte su llave de seguridad
- webauthn_piv_available: Utilice su PIV o CAC
webauthn_platform_header_text: Usar desbloqueo facial o táctil
webauthn_platform_use_key: Usar desbloqueo facial o táctil
webauthn_use_key: Usar llave de seguridad
diff --git a/config/locales/two_factor_authentication/fr.yml b/config/locales/two_factor_authentication/fr.yml
index 8701f807602..040cb780cf4 100644
--- a/config/locales/two_factor_authentication/fr.yml
+++ b/config/locales/two_factor_authentication/fr.yml
@@ -1,6 +1,14 @@
---
fr:
two_factor_authentication:
+ aal2_request:
+ phishing_resistant_html: '%{sp_name} nécessite une méthode
+ d’authentification de haute sécurité, telle que le déverrouillage du
+ visage ou du tactile, une clé de sécurité ou un identifiant d’employé du
+ gouvernement.'
+ piv_cac_only_html: '%{sp_name} nécessite votre identifiant
+ d’employé du gouvernement, une méthode d’authentification de haute
+ sécurité.'
account_reset:
cancel_link: Annuler votre demande
link: supprimer votre compte
@@ -138,7 +146,6 @@ fr:
change_number: Utilisez un autre numéro de téléphone
code_not_received: Je n’ai pas reçu mon code à usage unique
piv_cac_header_text: Veuillez présenter votre carte PIV/CAC
- piv_cac_webauthn_available: Utilisez votre clé de sécurité
please_try_again_html: Veuillez essayer de nouveau dans %{countdown}.
read_about_two_factor_authentication: En savoir plus sur l’authentification à deux facteurs
recaptcha:
@@ -199,7 +206,6 @@ fr:
try_again: Le déverrouillage facial ou tactile n’a pas fonctionné. Veuillez
réessayer ou %{link}.
webauthn_header_text: Connectez votre clé de sécurité
- webauthn_piv_available: Utilisez votre PIV ou CAC
webauthn_platform_header_text: Utilisez le déverrouillage facial ou tactile
webauthn_platform_use_key: Utilisez le déverrouillage facial ou tactile
webauthn_use_key: Utiliser la clé de sécurité
diff --git a/spec/policies/service_provider_mfa_policy_spec.rb b/spec/policies/service_provider_mfa_policy_spec.rb
index f16cc9ab66e..8a30d8a1ee7 100644
--- a/spec/policies/service_provider_mfa_policy_spec.rb
+++ b/spec/policies/service_provider_mfa_policy_spec.rb
@@ -197,61 +197,6 @@
end
end
- describe '#allow_user_to_switch_method?' do
- context 'phishing-resistant required' do
- let(:aal_level_requested) { 3 }
-
- context 'the user has more than one phishing-resistant method' do
- before do
- setup_user_webauthn_token
- setup_user_piv
- end
-
- it { expect(policy.allow_user_to_switch_method?).to eq(true) }
- end
-
- context 'the user does not have more than one aal3 method' do
- before do
- setup_user_webauthn_token
- end
-
- it { expect(policy.allow_user_to_switch_method?).to eq(false) }
- end
- end
-
- context 'piv/cac required' do
- let(:aal_level_requested) { 3 }
- let(:piv_cac_requested) { true }
-
- context 'the user has a PIV' do
- before { setup_user_piv }
-
- it { expect(policy.allow_user_to_switch_method?).to eq(false) }
- end
-
- context 'the user does not have a PIV' do
- before { setup_user_webauthn_token }
-
- it { expect(policy.allow_user_to_switch_method?).to eq(false) }
- end
-
- context 'the user has a PIV and webauthn token' do
- before do
- setup_user_webauthn_token
- setup_user_piv
- end
-
- it { expect(policy.allow_user_to_switch_method?).to eq(false) }
- end
- end
-
- context 'there are no MFA reqirements' do
- before { setup_user_phone }
-
- it { expect(policy.allow_user_to_switch_method?).to eq(true) }
- end
- end
-
def setup_user_phone
user.phone_configurations << build(:phone_configuration)
user.save!
diff --git a/spec/presenters/two_factor_auth_code/generic_delivery_presenter_spec.rb b/spec/presenters/two_factor_auth_code/generic_delivery_presenter_spec.rb
index 348c8621eeb..62ec8588ee5 100644
--- a/spec/presenters/two_factor_auth_code/generic_delivery_presenter_spec.rb
+++ b/spec/presenters/two_factor_auth_code/generic_delivery_presenter_spec.rb
@@ -19,26 +19,13 @@
c.content == t('two_factor_authentication.login_options_link_text')
end
expect(presenter.troubleshooting_options[1]).to satisfy do |c|
- c.content == t('two_factor_authentication.learn_more') && c.new_tab?
- end
- end
-
- context 'with blank link path' do
- before do
- allow(presenter).to receive(:link_path).and_return('')
- end
-
- it 'includes default troubleshooting options' do
- expect(presenter.troubleshooting_options.size).to eq(1)
- expect(presenter.troubleshooting_options[0]).to satisfy do |c|
+ c.content == t('two_factor_authentication.learn_more') &&
c.new_tab? &&
- c.content == t('two_factor_authentication.learn_more') &&
- c.url == help_center_redirect_path(
- category: 'get-started',
- article: 'authentication-options',
- flow: :two_factor_authentication,
- )
- end
+ c.url == help_center_redirect_path(
+ category: 'get-started',
+ article: 'authentication-options',
+ flow: :two_factor_authentication,
+ )
end
end
end
diff --git a/spec/presenters/two_factor_auth_code/piv_cac_authentication_presenter_spec.rb b/spec/presenters/two_factor_auth_code/piv_cac_authentication_presenter_spec.rb
index 55b49b5be80..2f73a7e8da2 100644
--- a/spec/presenters/two_factor_auth_code/piv_cac_authentication_presenter_spec.rb
+++ b/spec/presenters/two_factor_auth_code/piv_cac_authentication_presenter_spec.rb
@@ -8,7 +8,6 @@
let(:reauthn) {}
let(:presenter) { presenter_with(reauthn: reauthn) }
- let(:allow_user_to_switch_method) { false }
let(:phishing_resistant_required) { true }
let(:piv_cac_required) { false }
let(:service_provider_mfa_policy) do
@@ -16,7 +15,6 @@
ServiceProviderMfaPolicy,
phishing_resistant_required?: phishing_resistant_required,
piv_cac_required?: piv_cac_required,
- allow_user_to_switch_method?: allow_user_to_switch_method,
)
end
@@ -32,117 +30,6 @@
it { expect(presenter.header).to eq expected_header }
end
- describe '#piv_cac_help' do
- let(:phishing_resistant_required) { false }
- let(:piv_cac_required) { false }
-
- it 'returns help text' do
- expect(presenter.piv_cac_help).to eq(t('instructions.mfa.piv_cac.confirm_piv_cac'))
- end
-
- context 'with PIV/CAC only requested' do
- let(:phishing_resistant_required) { true }
- let(:piv_cac_required) { true }
-
- context 'with a user who only has a PIV' do
- let(:allow_user_to_switch_method) { false }
-
- it 'returns the PIV only help text' do
- expect(presenter.piv_cac_help).to eq(
- t('instructions.mfa.piv_cac.confirm_piv_cac_only'),
- )
- end
- end
-
- context 'with a user who has a PIV and security key' do
- let(:allow_user_to_switch_method) { false }
-
- it 'returns the PIV only help text' do
- expect(presenter.piv_cac_help).to eq(
- t('instructions.mfa.piv_cac.confirm_piv_cac_only'),
- )
- end
- end
- end
-
- context 'with phishing-resistant requested' do
- let(:phishing_resistant_required) { true }
- let(:piv_cac_required) { false }
-
- context 'with a user who only has a PIV' do
- let(:allow_user_to_switch_method) { false }
-
- it 'returns the PIV only help text' do
- expect(presenter.piv_cac_help).to eq(
- t('instructions.mfa.piv_cac.confirm_piv_cac_only'),
- )
- end
- end
-
- context 'with a user who has a PIV and security key' do
- let(:allow_user_to_switch_method) { true }
-
- it 'returns the PIV or phishing-resistant help text' do
- expect(presenter.piv_cac_help).to eq(
- t('instructions.mfa.piv_cac.confirm_piv_cac_or_aal3'),
- )
- end
- end
- end
- end
-
- describe '#link_text' do
- let(:phishing_resistant_required) { true }
-
- context 'with multiple phishing-resistant methods' do
- let(:allow_user_to_switch_method) { true }
-
- it 'supplies link text' do
- expect(presenter.link_text).to eq(t('two_factor_authentication.piv_cac_webauthn_available'))
- end
- end
- context 'with only one phishing-resistant method do' do
- let(:allow_user_to_switch_method) { false }
-
- it ' supplies no link text' do
- expect(presenter.link_text).to eq('')
- end
- end
- end
-
- describe '#troubleshooting_options' do
- context 'when the user can switch to a different method' do
- let(:allow_user_to_switch_method) { true }
- let(:phishing_resistant_required) { false }
-
- it 'includes option to choose another authentication method' do
- expect(presenter.troubleshooting_options.size).to eq(2)
- expect(presenter.troubleshooting_options.first).to satisfy do |c|
- c.url == login_two_factor_options_path &&
- c.content == t('two_factor_authentication.login_options_link_text')
- end
- end
-
- context 'when phishing resistant method is required' do
- let(:phishing_resistant_required) { true }
-
- it 'includes option to use another phishing resistant method' do
- expect(presenter.troubleshooting_options.size).to eq(2)
- expect(presenter.troubleshooting_options.first).to satisfy do |c|
- c.url == login_two_factor_webauthn_url &&
- c.content == t('two_factor_authentication.piv_cac_webauthn_available')
- end
- end
- end
- end
-
- context 'when the user cannot switch to a different method' do
- let(:allow_user_to_switch_method) { false }
-
- it { expect(presenter.troubleshooting_options.size).to eq(1) }
- end
- end
-
describe '#piv_cac_capture_text' do
let(:expected_text) { t('forms.piv_cac_mfa.submit') }
diff --git a/spec/presenters/two_factor_auth_code/webauthn_authentication_presenter_spec.rb b/spec/presenters/two_factor_auth_code/webauthn_authentication_presenter_spec.rb
index 51f6cadf39a..c5bc98967cf 100644
--- a/spec/presenters/two_factor_auth_code/webauthn_authentication_presenter_spec.rb
+++ b/spec/presenters/two_factor_auth_code/webauthn_authentication_presenter_spec.rb
@@ -15,7 +15,6 @@
)
end
- let(:allow_user_to_switch_method) { false }
let(:phishing_resistant_required) { false }
let(:platform_authenticator) { false }
let(:multiple_factors_enabled) { false }
@@ -23,7 +22,6 @@
instance_double(
ServiceProviderMfaPolicy,
phishing_resistant_required?: phishing_resistant_required,
- allow_user_to_switch_method?: allow_user_to_switch_method,
multiple_factors_enabled?: multiple_factors_enabled,
)
end
@@ -33,38 +31,10 @@
end
describe '#webauthn_help' do
- context 'with phishing-resistant required' do
- let(:phishing_resistant_required) { true }
+ let(:phishing_resistant_required) { false }
- context 'the user only has a security key enabled' do
- let(:allow_user_to_switch_method) { false }
-
- it 'returns the help text for just the security key' do
- expect(presenter.webauthn_help).to eq(
- t('instructions.mfa.webauthn.confirm_webauthn_only'),
- )
- end
- end
-
- context 'the user has a security key and PIV enabled' do
- let(:allow_user_to_switch_method) { true }
-
- it 'returns the help text for the security key or PIV' do
- expect(presenter.webauthn_help).to eq(
- t('instructions.mfa.webauthn.confirm_webauthn_or_aal3'),
- )
- end
- end
- end
-
- context 'with phishing-resistant not required' do
- let(:phishing_resistant_required) { false }
-
- it 'displays the help text' do
- expect(presenter.webauthn_help).to eq(
- t('instructions.mfa.webauthn.confirm_webauthn'),
- )
- end
+ it 'returns the help text for security key' do
+ expect(presenter.webauthn_help).to eq(t('instructions.mfa.webauthn.confirm_webauthn'))
end
context 'with a platform authenticator' do
@@ -137,67 +107,27 @@
end
end
- describe '#link_text' do
- let(:phishing_resistant_required) { true }
-
- context 'with multiple phishing-resistant methods' do
- let(:allow_user_to_switch_method) { true }
-
- it 'supplies link text' do
- expect(presenter.link_text).to eq(t('two_factor_authentication.webauthn_piv_available'))
- end
- end
-
- context 'with only one phishing-resistant method do' do
- it 'supplies no link text' do
- expect(presenter.link_text).to eq('')
- end
- end
- end
-
describe '#troubleshooting_options' do
- context 'when the user can switch to a different method' do
- let(:allow_user_to_switch_method) { true }
- let(:phishing_resistant_required) { false }
-
- it 'includes option to choose another authentication method' do
- expect(presenter.troubleshooting_options.size).to eq(2)
- expect(presenter.troubleshooting_options.first).to satisfy do |c|
- c.url == login_two_factor_options_path &&
- c.content == t('two_factor_authentication.login_options_link_text')
- end
- end
+ let(:phishing_resistant_required) { false }
- context 'with platform authenticator' do
- let(:platform_authenticator) { true }
-
- it 'includes option to learn more about face or touch unlock' do
- expect(presenter.troubleshooting_options.size).to eq(3)
- expect(presenter.troubleshooting_options[1]).to satisfy do |c|
- c.content == t('instructions.mfa.webauthn_platform.learn_more_help')
- end
- end
+ it 'includes option to choose another authentication method' do
+ expect(presenter.troubleshooting_options.size).to eq(2)
+ expect(presenter.troubleshooting_options.first).to satisfy do |c|
+ c.url == login_two_factor_options_path &&
+ c.content == t('two_factor_authentication.login_options_link_text')
end
+ end
- context 'when phishing resistant method is required' do
- let(:phishing_resistant_required) { true }
+ context 'with platform authenticator' do
+ let(:platform_authenticator) { true }
- it 'includes option to use another phishing resistant method' do
- expect(presenter.troubleshooting_options.size).to eq(2)
- expect(presenter.troubleshooting_options.first).to satisfy do |c|
- c.url == login_two_factor_piv_cac_url &&
- c.content == t('two_factor_authentication.webauthn_piv_available')
- end
+ it 'includes option to learn more about face or touch unlock' do
+ expect(presenter.troubleshooting_options.size).to eq(3)
+ expect(presenter.troubleshooting_options[1]).to satisfy do |c|
+ c.content == t('instructions.mfa.webauthn_platform.learn_more_help')
end
end
end
-
- context 'when the user cannot switch to a different method' do
- let(:allow_user_to_switch_method) { false }
- let(:phishing_resistant_required) { true }
-
- it { expect(presenter.troubleshooting_options.size).to eq(1) }
- end
end
describe '#cancel_link' do
diff --git a/spec/presenters/two_factor_login_options_presenter_spec.rb b/spec/presenters/two_factor_login_options_presenter_spec.rb
index 576a363ece6..926e6204f88 100644
--- a/spec/presenters/two_factor_login_options_presenter_spec.rb
+++ b/spec/presenters/two_factor_login_options_presenter_spec.rb
@@ -8,15 +8,16 @@
let(:phishing_resistant_required) { false }
let(:piv_cac_required) { false }
let(:reauthentication_context) { false }
+ let(:service_provider) { nil }
subject(:presenter) do
TwoFactorLoginOptionsPresenter.new(
user: user,
view: view,
reauthentication_context: reauthentication_context,
- service_provider: nil,
- phishing_resistant_required: false,
- piv_cac_required: false,
+ service_provider: service_provider,
+ phishing_resistant_required: phishing_resistant_required,
+ piv_cac_required: piv_cac_required,
)
end
@@ -75,6 +76,81 @@
end
end
+ describe '#restricted_options_warning_text' do
+ subject(:restricted_options_warning_text) { presenter.restricted_options_warning_text }
+
+ it { should be_nil }
+
+ context 'phishing resistant required' do
+ let(:phishing_resistant_required) { true }
+
+ it 'returns phishing resistant required warning text for app' do
+ expect(restricted_options_warning_text).to eq(
+ t('two_factor_authentication.aal2_request.phishing_resistant_html', sp_name: APP_NAME),
+ )
+ end
+
+ context 'piv cac required' do
+ let(:piv_cac_required) { true }
+
+ it 'returns piv cac required warning text for app' do
+ expect(restricted_options_warning_text).to eq(
+ t('two_factor_authentication.aal2_request.piv_cac_only_html', sp_name: APP_NAME),
+ )
+ end
+
+ context 'with sp' do
+ let(:service_provider) { build(:service_provider) }
+
+ it 'returns piv cac required warning text for service provider' do
+ expect(restricted_options_warning_text).to eq(
+ t(
+ 'two_factor_authentication.aal2_request.piv_cac_only_html',
+ sp_name: service_provider.friendly_name,
+ ),
+ )
+ end
+ end
+ end
+
+ context 'with sp' do
+ let(:service_provider) { build(:service_provider) }
+
+ it 'returns phishing resistant required warning text for service provider' do
+ expect(restricted_options_warning_text).to eq(
+ t(
+ 'two_factor_authentication.aal2_request.phishing_resistant_html',
+ sp_name: service_provider.friendly_name,
+ ),
+ )
+ end
+ end
+ end
+
+ context 'piv cac required' do
+ let(:piv_cac_required) { true }
+
+ it 'returns piv cac required warning text for app' do
+ expect(restricted_options_warning_text).to eq(
+ t('two_factor_authentication.aal2_request.piv_cac_only_html', sp_name: APP_NAME),
+ )
+ end
+
+ context 'with sp' do
+ let(:service_provider) { build(:service_provider) }
+
+ it 'returns piv cac required warning text for service provider' do
+ expect(restricted_options_warning_text).to eq(
+ t(
+ 'two_factor_authentication.aal2_request.piv_cac_only_html',
+ sp_name: service_provider.friendly_name,
+ ),
+ )
+ end
+ end
+ end
+ end
+
describe '#cancel_link' do
subject(:cancel_link) { presenter.cancel_link }
diff --git a/spec/views/two_factor_authentication/options/index.html.erb_spec.rb b/spec/views/two_factor_authentication/options/index.html.erb_spec.rb
index e418a0a30a1..929a427f88d 100644
--- a/spec/views/two_factor_authentication/options/index.html.erb_spec.rb
+++ b/spec/views/two_factor_authentication/options/index.html.erb_spec.rb
@@ -2,6 +2,9 @@
RSpec.describe 'two_factor_authentication/options/index.html.erb' do
let(:user) { User.new }
+ let(:phishing_resistant_required) { false }
+ let(:piv_cac_required) { false }
+
before do
allow(view).to receive(:user_session).and_return({})
allow(view).to receive(:current_user).and_return(User.new)
@@ -11,8 +14,8 @@
view: view,
reauthentication_context: false,
service_provider: nil,
- phishing_resistant_required: false,
- piv_cac_required: false,
+ phishing_resistant_required: phishing_resistant_required,
+ piv_cac_required: piv_cac_required,
)
@two_factor_options_form = TwoFactorLoginOptionsForm.new(user)
end
@@ -64,4 +67,34 @@
)
end
end
+
+ context 'with phishing resistant required' do
+ let(:phishing_resistant_required) { true }
+
+ before { render }
+
+ it 'displays warning text' do
+ expect(rendered).to have_selector(
+ '.usa-alert.usa-alert--warning',
+ text: strip_tags(
+ t('two_factor_authentication.aal2_request.phishing_resistant_html', sp_name: APP_NAME),
+ ),
+ )
+ end
+ end
+
+ context 'with piv cac required' do
+ let(:piv_cac_required) { true }
+
+ before { render }
+
+ it 'displays warning text' do
+ expect(rendered).to have_selector(
+ '.usa-alert.usa-alert--warning',
+ text: strip_tags(
+ t('two_factor_authentication.aal2_request.piv_cac_only_html', sp_name: APP_NAME),
+ ),
+ )
+ end
+ end
end
diff --git a/spec/views/two_factor_authentication/webauthn_verification/show.html.erb_spec.rb b/spec/views/two_factor_authentication/webauthn_verification/show.html.erb_spec.rb
index 6379cc04f80..56ffa23f8d9 100644
--- a/spec/views/two_factor_authentication/webauthn_verification/show.html.erb_spec.rb
+++ b/spec/views/two_factor_authentication/webauthn_verification/show.html.erb_spec.rb
@@ -64,24 +64,4 @@
)
end
end
-
- context 'with phishing-resistant MFA requirement' do
- let(:phishing_resistant_required) { true }
-
- it 'does not include a troubleshooting link for using another MFA method' do
- expect(rendered).to have_css('.troubleshooting-options li', count: 1)
- end
-
- context 'with user having PIV/CAC configured' do
- let(:user) { build(:user, :with_piv_or_cac, :with_webauthn) }
-
- it 'includes troubleshooting link to use PIV/CAC' do
- expect(rendered).to have_css('.troubleshooting-options li', count: 2)
- expect(rendered).to have_link(
- t('two_factor_authentication.webauthn_piv_available'),
- href: login_two_factor_piv_cac_url,
- )
- end
- end
- end
end