diff --git a/app/controllers/sign_up/completions_controller.rb b/app/controllers/sign_up/completions_controller.rb index 8acd5911a23..84f702abc2a 100644 --- a/app/controllers/sign_up/completions_controller.rb +++ b/app/controllers/sign_up/completions_controller.rb @@ -12,6 +12,7 @@ def show Analytics::USER_REGISTRATION_AGENCY_HANDOFF_PAGE_VISIT, analytics_attributes(''), ) + @multiple_factors_enabled = MfaPolicy.new(current_user).multiple_factors_enabled? @presenter = completions_presenter end diff --git a/app/controllers/users/two_factor_authentication_setup_controller.rb b/app/controllers/users/two_factor_authentication_setup_controller.rb index 2db72b6c6e4..c1067d4ad30 100644 --- a/app/controllers/users/two_factor_authentication_setup_controller.rb +++ b/app/controllers/users/two_factor_authentication_setup_controller.rb @@ -56,6 +56,7 @@ def handle_empty_selection def confirm_user_needs_2fa_setup return unless mfa_policy.two_factor_enabled? + return if params.has_key?(:multiple_mfa_setup) return if service_provider_mfa_policy.user_needs_sp_auth_method_setup? redirect_to after_mfa_setup_path end diff --git a/app/views/mfa_confirmation/index.html.erb b/app/views/mfa_confirmation/index.html.erb index 51037ed4c69..d46e018e7f7 100644 --- a/app/views/mfa_confirmation/index.html.erb +++ b/app/views/mfa_confirmation/index.html.erb @@ -4,18 +4,18 @@ <% title t('titles.mfa_setup.first_authentication_method') %> <%= render AlertComponent.new(type: :success, class: 'margin-bottom-4') do %> - <%= t('multi_factor_authentication.method_confirmation.face_id') %> + <%= t('mfa.method_confirmation.face_id') %> <% end %> <%= image_tag asset_url('user-signup-ial1.svg'), width: 107, height: 119, alt: '', class: 'margin-bottom-4' %> <%= render PageHeadingComponent.new.with_content(t('headings.mfa_setup.first_authentication_method')) %> -

<%= t('multi_factor_authentication.cta') %>

+

<%= t('mfa.cta') %>

<%= button_to( account_reset_pending_cancel_path, class: 'usa-button usa-button--wide usa-button--big margin-bottom-3', - ) { t('multi_factor_authentication.add') } %> + ) { t('mfa.add') } %> -<%= link_to t('multi_factor_authentication.skip'), root_url %> \ No newline at end of file +<%= link_to t('mfa.skip'), root_url %> \ No newline at end of file diff --git a/app/views/sign_up/completions/show.html.erb b/app/views/sign_up/completions/show.html.erb index e69491a46b0..81b1a968500 100644 --- a/app/views/sign_up/completions/show.html.erb +++ b/app/views/sign_up/completions/show.html.erb @@ -24,6 +24,15 @@ sp: content_tag(:strong, decorated_session.sp_name), ) %>

+<% if !@multiple_factors_enabled && IdentityConfig.store.select_multiple_mfa_options %> + <%= render(AlertComponent.new(type: :warning, class: 'margin-bottom-4')) do %> + <%= link_to( + t('mfa.second_method_warning.link'), + two_factor_options_url(multiple_mfa_setup: ''), + ) %> + <%= t('mfa.second_method_warning.text') %> + <% end %> +<% end %>

<%= validated_form_for(:idv_form, url: sign_up_completed_path) do %> <%= submit_tag t('sign_up.agree_and_continue'), class: 'usa-button usa-button--big usa-button--wide' %> diff --git a/app/views/users/two_factor_authentication_setup/index.html.erb b/app/views/users/two_factor_authentication_setup/index.html.erb index 022de130cac..b5c060a52be 100644 --- a/app/views/users/two_factor_authentication_setup/index.html.erb +++ b/app/views/users/two_factor_authentication_setup/index.html.erb @@ -18,7 +18,7 @@ <% if IdentityConfig.store.select_multiple_mfa_options %> <%= render AlertComponent.new(type: :info, class: 'margin-bottom-4') do %> - <%= t('multi_factor_authentication.info') %> + <%= t('mfa.info') %> <% end %> <% end %> diff --git a/config/locales/multi_factor_authentication/en.yml b/config/locales/mfa/en.yml similarity index 68% rename from config/locales/multi_factor_authentication/en.yml rename to config/locales/mfa/en.yml index e7857596af0..16ac718e808 100644 --- a/config/locales/multi_factor_authentication/en.yml +++ b/config/locales/mfa/en.yml @@ -1,6 +1,6 @@ --- en: - multi_factor_authentication: + mfa: add: Add another method cta: Adding another authentication method prevents you from getting locked out of your account if you lose one of your methods. @@ -8,4 +8,8 @@ en: backup if you lose one of your chosen authentication devices. method_confirmation: face_id: Face ID has been added to your account + second_method_warning: + link: Add a second authentication method. + text: You will have to delete your account and start over if you lose your only + authentication method. skip: Skip for now diff --git a/config/locales/multi_factor_authentication/es.yml b/config/locales/mfa/es.yml similarity index 68% rename from config/locales/multi_factor_authentication/es.yml rename to config/locales/mfa/es.yml index 91628b18912..448026c1e8a 100644 --- a/config/locales/multi_factor_authentication/es.yml +++ b/config/locales/mfa/es.yml @@ -1,6 +1,6 @@ --- es: - multi_factor_authentication: + mfa: add: Agregar otro método cta: Agregar otro método de autenticación evita que se le bloquee el acceso a su cuenta si pierde uno de sus métodos. @@ -9,4 +9,8 @@ es: autenticación elegidos. method_confirmation: face_id: Se ha agregado Face ID a su cuenta + second_method_warning: + link: Agregue un segundo método de autenticación. + text: Deberá eliminar su cuenta y comenzar de nuevo si pierde su único método de + autenticación. skip: Saltar por ahora diff --git a/config/locales/multi_factor_authentication/fr.yml b/config/locales/mfa/fr.yml similarity index 69% rename from config/locales/multi_factor_authentication/fr.yml rename to config/locales/mfa/fr.yml index d317e7ebbe7..19f604c2033 100644 --- a/config/locales/multi_factor_authentication/fr.yml +++ b/config/locales/mfa/fr.yml @@ -1,6 +1,6 @@ --- fr: - multi_factor_authentication: + mfa: add: Agregar otro método cta: L’ajout d’une autre méthode d’authentification vous empêche d’être bloqué sur votre compte si vous perdez l’une de vos méthodes. @@ -9,4 +9,8 @@ fr: dispositifs d’authentification choisis. method_confirmation: face_id: Face ID a été ajouté à votre compte + second_method_warning: + link: Ajoutez une deuxième méthode d’authentification. + text: Vous devrez supprimer votre compte et recommencer si vous perdez votre + seule méthode d’authentification. skip: Ignorer pour l’instant diff --git a/spec/features/multi_factor_authentication/mfa_cta_spec.rb b/spec/features/multi_factor_authentication/mfa_cta_spec.rb new file mode 100644 index 00000000000..d214ab970f9 --- /dev/null +++ b/spec/features/multi_factor_authentication/mfa_cta_spec.rb @@ -0,0 +1,61 @@ +require 'rails_helper' + +feature 'mfa cta banner' do + include DocAuthHelper + include SamlAuthHelper + + context 'When multiple factor authentication feature is disabled' do + it 'does not display a banner as the feature is disabled' do + visit_idp_from_sp_with_ial1(:oidc) + user = sign_up_and_set_password + select_2fa_option('backup_code') + click_continue + + expect(MfaPolicy.new(user).multiple_factors_enabled?).to eq false + expect(page).to have_current_path(sign_up_completed_path) + expect(page).not_to have_content(t('mfa.second_method_warning.text')) + end + end + + context 'When the multiple factor authentication feature is enabled' do + before do + allow(IdentityConfig.store).to receive(:select_multiple_mfa_options).and_return(true) + end + + it 'displays a banner after configuring a single MFA method' do + visit_idp_from_sp_with_ial1(:oidc) + user = sign_up_and_set_password + select_2fa_option('backup_code') + click_continue + + expect(page).to have_current_path(sign_up_completed_path) + expect(MfaPolicy.new(user).multiple_factors_enabled?).to eq false + expect(page).to have_content(t('mfa.second_method_warning.text')) + end + + it 'does not display a banner after configuring multiple MFA methods' do + visit_idp_from_sp_with_ial1(:oidc) + sign_up_and_set_password + check t('two_factor_authentication.two_factor_choice_options.phone') + check t('two_factor_authentication.two_factor_choice_options.backup_code') + click_continue + + expect(page).to have_current_path(phone_setup_path) + set_up_mfa_with_valid_phone + expect(page).to have_current_path(backup_code_setup_path) + set_up_mfa_with_backup_codes + expect(page).to have_current_path(sign_up_completed_path) + expect(page).not_to have_content(t('mfa.second_method_warning.text')) + end + + it 'redirects user to select additional authentication methods' do + visit_idp_from_sp_with_ial1(:oidc) + sign_up_and_set_password + select_2fa_option('backup_code') + click_continue + expect(page).to have_current_path(sign_up_completed_path) + click_on(t('mfa.second_method_warning.link')) + expect(page).to have_content(t('two_factor_authentication.two_factor_choice')) + end + end +end diff --git a/spec/support/features/session_helper.rb b/spec/support/features/session_helper.rb index 931eabe6d07..7f3361bd324 100644 --- a/spec/support/features/session_helper.rb +++ b/spec/support/features/session_helper.rb @@ -507,6 +507,18 @@ def set_up_2fa_with_valid_phone click_submit_default end + def set_up_mfa_with_valid_phone + fill_in 'new_phone_form[phone]', with: '202-555-1212' + click_send_security_code + fill_in_code_with_last_phone_otp + click_submit_default + end + + def set_up_mfa_with_backup_codes + click_on t('forms.buttons.continue') + click_on t('forms.buttons.continue') + end + def register_user(email = 'test@test.com') confirm_email_and_password(email) set_up_2fa_with_valid_phone diff --git a/spec/views/mfa_confirmation/index.html.erb_spec.rb b/spec/views/mfa_confirmation/index.html.erb_spec.rb index 06e849f09de..701fdbbc128 100644 --- a/spec/views/mfa_confirmation/index.html.erb_spec.rb +++ b/spec/views/mfa_confirmation/index.html.erb_spec.rb @@ -16,12 +16,12 @@ it 'provides a call to action to add another MFA method' do render - expect(rendered).to have_selector('p', text: t('multi_factor_authentication.cta')) + expect(rendered).to have_selector('p', text: t('mfa.cta')) end it 'has a button with the next step' do render - expect(rendered).to have_selector('button', text: t('multi_factor_authentication.add')) + expect(rendered).to have_selector('button', text: t('mfa.add')) end end diff --git a/spec/views/sign_up/completions/show.html.erb_spec.rb b/spec/views/sign_up/completions/show.html.erb_spec.rb index d8b475b6872..0ab46031ad7 100644 --- a/spec/views/sign_up/completions/show.html.erb_spec.rb +++ b/spec/views/sign_up/completions/show.html.erb_spec.rb @@ -90,4 +90,59 @@ expect(rendered).to include('9**-**-***6') end end + + describe 'MFA CTA banner' do + let(:multiple_factors_enabled) { nil } + let(:select_multiple_mfa_options) { nil } + + before do + allow(IdentityConfig.store).to receive(:select_multiple_mfa_options). + and_return(select_multiple_mfa_options) + @multiple_factors_enabled = multiple_factors_enabled + end + + context 'with multiple factors disabled' do + let(:multiple_factors_enabled) { false } + + context 'with multiple MFA feature flag disabled' do + let(:select_multiple_mfa_options) { false } + + it 'does not show a banner' do + render + expect(rendered).not_to have_content(t('mfa.second_method_warning.text')) + end + end + + context 'with multiple MFA feature flag enabled' do + let(:select_multiple_mfa_options) { true } + + it 'shows a banner if the user selects one MFA option' do + render + expect(rendered).to have_content(t('mfa.second_method_warning.text')) + end + end + end + + context 'with multiple factors enabled' do + let(:multiple_factors_enabled) { true } + + context 'with multiple MFA feature flag disabled' do + let(:select_multiple_mfa_options) { false } + + it 'does not show a banner' do + render + expect(rendered).not_to have_content(t('mfa.second_method_warning.text')) + end + end + + context 'with multiple MFA feature flag enabled' do + let(:select_multiple_mfa_options) { true } + + it 'does not show a banner' do + render + expect(rendered).not_to have_content(t('mfa.second_method_warning.text')) + end + end + end + end end