diff --git a/app/forms/two_factor_options_form.rb b/app/forms/two_factor_options_form.rb index 57166649c50..491c2344ade 100644 --- a/app/forms/two_factor_options_form.rb +++ b/app/forms/two_factor_options_form.rb @@ -60,7 +60,13 @@ def has_no_configured_mfa? mfa_user.enabled_mfa_methods_count == 0 end + def platform_auth_only_option? + mfa_user.enabled_mfa_methods_count == 1 && + mfa_user.webauthn_platform_configurations.count == 1 + end + def has_no_mfa_or_in_required_flow? - has_no_configured_mfa? || in_phishing_resistant_or_piv_cac_required_flow? + has_no_configured_mfa? || in_phishing_resistant_or_piv_cac_required_flow? || + platform_auth_only_option? end end diff --git a/spec/features/remember_device/webauthn_spec.rb b/spec/features/remember_device/webauthn_spec.rb index 3d4b7f78fc1..dbe6a964564 100644 --- a/spec/features/remember_device/webauthn_spec.rb +++ b/spec/features/remember_device/webauthn_spec.rb @@ -97,17 +97,48 @@ def remember_device_and_sign_out_user end context 'sign up' do + before do + allow(IdentityConfig.store).to receive(:platform_auth_set_up_enabled).and_return(true) + allow(IdentityConfig.store). + to receive(:show_unsupported_passkey_platform_authentication_setup). + and_return(true) + end + + def click_2fa_option(option) + find("label[for='two_factor_options_form_selection_#{option}']").click + end + def remember_device_and_sign_out_user mock_webauthn_setup_challenge user = sign_up_and_set_password user.password = Features::SessionHelper::VALID_PASSWORD # webauthn option is hidden in browsers that don't support it - select_2fa_option('webauthn', visible: :all) + select_2fa_option('webauthn_platform', visible: :all) fill_in_nickname_and_click_continue check t('forms.messages.remember_device') mock_press_button_on_hardware_key_on_setup - skip_second_mfa_prompt + + expect(page).to_not have_button(t('mfa.skip')) + + click_link t('mfa.add') + + expect(page).to have_current_path(second_mfa_setup_path) + + click_2fa_option('phone') + + click_continue + + expect(page). + to have_content t('titles.phone_setup') + + expect(current_path).to eq phone_setup_path + + fill_in 'new_phone_form_phone', with: '703-555-1212' + click_send_one_time_code + + fill_in_code_with_last_phone_otp + click_submit_default first(:link, t('links.sign_out')).click user diff --git a/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb b/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb index 7584acf90f3..6b279175f13 100644 --- a/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb +++ b/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb @@ -1,6 +1,8 @@ require 'rails_helper' RSpec.feature 'Multi Two Factor Authentication' do + include WebAuthnHelper + describe 'When the user has not set up 2FA' do scenario 'user can set up 2 MFA methods properly' do sign_in_before_2fa @@ -135,6 +137,41 @@ expect(page).to have_current_path(account_path) end + + scenario 'user cannot select Platform Auth as only MFA and must select second mfa setup' do + allow(IdentityConfig.store).to receive(:platform_auth_set_up_enabled).and_return(true) + allow(IdentityConfig.store). + to receive(:show_unsupported_passkey_platform_authentication_setup). + and_return(true) + mock_webauthn_setup_challenge + user = sign_up_and_set_password + user.password = Features::SessionHelper::VALID_PASSWORD + expect(current_path).to eq authentication_methods_setup_path + # webauthn option is hidden in browsers that don't support it + select_2fa_option('webauthn_platform', visible: :all) + + click_continue + + expect(page).to have_current_path webauthn_setup_path(platform: true) + + fill_in_nickname_and_click_continue + mock_press_button_on_hardware_key_on_setup + + expect(page).to have_current_path( + auth_method_confirmation_path, + ) + + expect(page).to_not have_button(t('mfa.skip')) + + click_link t('mfa.add') + + expect(page).to have_current_path(second_mfa_setup_path) + + click_continue + + expect(page).to have_current_path(second_mfa_setup_path) + expect(page).to have_content(t('errors.two_factor_auth_setup.must_select_additional_option')) + end end context 'when backup codes are the only selected option' do diff --git a/spec/forms/two_factor_options_form_spec.rb b/spec/forms/two_factor_options_form_spec.rb index a03e1685621..5fb12016609 100644 --- a/spec/forms/two_factor_options_form_spec.rb +++ b/spec/forms/two_factor_options_form_spec.rb @@ -48,6 +48,13 @@ expect(result.success?).to eq true end + it 'is unsuccessful if user has 1 method and its platform auth and no option' do + create(:webauthn_configuration, :platform_authenticator, user: user) + + result = subject.submit(selection: []) + expect(result.success?).to eq false + end + it 'includes analytics hash with a methods count of zero' do result = subject.submit(selection: 'piv_cac')