diff --git a/app/components/vendor_outage_alert_component.rb b/app/components/vendor_outage_alert_component.rb index dbf7a21d104..822ff103efa 100644 --- a/app/components/vendor_outage_alert_component.rb +++ b/app/components/vendor_outage_alert_component.rb @@ -37,6 +37,6 @@ def outages end def vendor_status - @vendor_status ||= VendorStatus.new + @vendor_status ||= OutageStatus.new end end diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index 9e1acd7dce2..4f3dd6402a7 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -114,7 +114,7 @@ def async_state_done(current_async_state) move_applicant_to_idv_session idv_session.mark_verify_info_step_complete! idv_session.invalidate_steps_after_verify_info! - redirect_to idv_phone_url + redirect_to next_step_url else idv_session.invalidate_verify_info_step! end @@ -122,6 +122,11 @@ def async_state_done(current_async_state) analytics.idv_doc_auth_verify_proofing_results(**form_response.to_h) end + def next_step_url + return idv_gpo_url if OutageStatus.new.gpo_only? + idv_phone_url + end + def summarize_result_and_throttle_failures(summary_result) if summary_result.success? add_proofing_components diff --git a/app/controllers/idv/doc_auth_controller.rb b/app/controllers/idv/doc_auth_controller.rb index 2861a53eb7f..b2e55231a30 100644 --- a/app/controllers/idv/doc_auth_controller.rb +++ b/app/controllers/idv/doc_auth_controller.rb @@ -70,11 +70,30 @@ def flow_session end def check_for_outage - if VendorStatus.new.any_ial2_vendor_outage? - session[:vendor_outage_redirect] = current_step - session[:vendor_outage_redirect_from_idv] = true - redirect_to vendor_outage_url - end + return if flow_session[:skip_vendor_outage] + + return redirect_for_proofing_vendor_outage if OutageStatus.new.any_idv_vendor_outage? + return redirect_for_gpo_only if FeatureManagement.idv_gpo_only? + end + + def redirect_for_proofing_vendor_outage + session[:vendor_outage_redirect] = current_step + session[:vendor_outage_redirect_from_idv] = true + + redirect_to vendor_outage_url + end + + def redirect_for_gpo_only + return redirect_to vendor_outage_url unless FeatureManagement.gpo_verification_enabled? + + # During a phone outage, skip the hybrid handoff + # step and go straight to document upload + flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow? + + session[:vendor_outage_redirect] = current_step + session[:vendor_outage_redirect_from_idv] = true + + redirect_to idv_mail_only_warning_url end end end diff --git a/app/controllers/idv/gpo_only_warning_controller.rb b/app/controllers/idv/gpo_only_warning_controller.rb new file mode 100644 index 00000000000..8735f8fa13f --- /dev/null +++ b/app/controllers/idv/gpo_only_warning_controller.rb @@ -0,0 +1,17 @@ +module Idv + class GpoOnlyWarningController < ApplicationController + include IdvSession + include StepIndicatorConcern + + before_action :confirm_two_factor_authenticated + + def show + user_session['idv/doc_auth'][:skip_vendor_outage] = true + render :show, locals: { current_sp:, exit_url: } + end + + def exit_url + current_sp&.return_to_sp_url || account_path + end + end +end diff --git a/app/controllers/idv/phone_controller.rb b/app/controllers/idv/phone_controller.rb index ab424f8da29..6afe9035396 100644 --- a/app/controllers/idv/phone_controller.rb +++ b/app/controllers/idv/phone_controller.rb @@ -62,7 +62,7 @@ def throttle def redirect_to_next_step if phone_confirmation_required? - if VendorStatus.new.all_phone_vendor_outage? + if OutageStatus.new.all_phone_vendor_outage? redirect_to vendor_outage_path(from: :idv_phone) else send_phone_confirmation_otp_and_handle_result @@ -182,7 +182,7 @@ def new_phone_added? def gpo_letter_available return @gpo_letter_available if defined?(@gpo_letter_available) - @gpo_letter_available ||= FeatureManagement.enable_gpo_verification? && + @gpo_letter_available ||= FeatureManagement.gpo_verification_enabled? && !Idv::GpoMail.new(current_user).mail_spammed? end diff --git a/app/controllers/idv/phone_errors_controller.rb b/app/controllers/idv/phone_errors_controller.rb index 31cfab5e2ec..fed541d4730 100644 --- a/app/controllers/idv/phone_errors_controller.rb +++ b/app/controllers/idv/phone_errors_controller.rb @@ -56,7 +56,7 @@ def track_event(type:) # rubocop:disable Naming/MemoizedInstanceVariableName def set_gpo_letter_available return @gpo_letter_available if defined?(@gpo_letter_available) - @gpo_letter_available ||= FeatureManagement.enable_gpo_verification? && + @gpo_letter_available ||= FeatureManagement.gpo_verification_enabled? && !Idv::GpoMail.new(current_user).mail_spammed? end # rubocop:enable Naming/MemoizedInstanceVariableName diff --git a/app/controllers/sign_up/registrations_controller.rb b/app/controllers/sign_up/registrations_controller.rb index 19204b5c997..51a9ddb7e71 100644 --- a/app/controllers/sign_up/registrations_controller.rb +++ b/app/controllers/sign_up/registrations_controller.rb @@ -72,7 +72,7 @@ def sp_request_id end def redirect_if_ial2_and_vendor_outage - return unless ial2_requested? && VendorStatus.new.any_ial2_vendor_outage? + return unless ial2_requested? && OutageStatus.new.any_idv_vendor_outage? session[:vendor_outage_redirect] = CREATE_ACCOUNT return redirect_to vendor_outage_url diff --git a/app/controllers/users/phones_controller.rb b/app/controllers/users/phones_controller.rb index 22c3210acd9..ca4f3988773 100644 --- a/app/controllers/users/phones_controller.rb +++ b/app/controllers/users/phones_controller.rb @@ -31,7 +31,7 @@ def create private def redirect_if_phone_vendor_outage - return unless VendorStatus.new.all_phone_vendor_outage? + return unless OutageStatus.new.all_phone_vendor_outage? redirect_to vendor_outage_path(from: :users_phones) end diff --git a/app/controllers/users/two_factor_authentication_controller.rb b/app/controllers/users/two_factor_authentication_controller.rb index 7b152845a77..b413a5bc881 100644 --- a/app/controllers/users/two_factor_authentication_controller.rb +++ b/app/controllers/users/two_factor_authentication_controller.rb @@ -43,7 +43,7 @@ def non_phone_redirect end def phone_redirect - return unless phone_enabled? && !VendorStatus.new.any_phone_vendor_outage? + return unless phone_enabled? && !OutageStatus.new.any_phone_vendor_outage? validate_otp_delivery_preference_and_send_code true end @@ -145,7 +145,7 @@ def redirect_if_blank_phone end def redirect_to_vendor_outage_if_phone_only - return unless VendorStatus.new.all_phone_vendor_outage? && + return unless OutageStatus.new.all_phone_vendor_outage? && phone_enabled? && !MfaPolicy.new(current_user).multiple_factors_enabled? redirect_to vendor_outage_path(from: :two_factor_authentication) diff --git a/app/controllers/vendor_outage_controller.rb b/app/controllers/vendor_outage_controller.rb index ab47989c85e..fdc023b203f 100644 --- a/app/controllers/vendor_outage_controller.rb +++ b/app/controllers/vendor_outage_controller.rb @@ -1,6 +1,6 @@ class VendorOutageController < ApplicationController def show - vendor_status = VendorStatus.new( + vendor_status = OutageStatus.new( sp: current_sp, from: session.delete(:vendor_outage_redirect), from_idv: session.delete(:vendor_outage_redirect_from_idv), @@ -17,7 +17,7 @@ def from_idv_phone? end def gpo_letter_available? - FeatureManagement.enable_gpo_verification? && + FeatureManagement.gpo_verification_enabled? && current_user && !Idv::GpoMail.new(current_user).mail_spammed? end diff --git a/app/forms/new_phone_form.rb b/app/forms/new_phone_form.rb index af4f76885e0..068310eafea 100644 --- a/app/forms/new_phone_form.rb +++ b/app/forms/new_phone_form.rb @@ -46,11 +46,11 @@ def submit(params) end def delivery_preference_sms? - !VendorStatus.new.vendor_outage?(:sms) + !OutageStatus.new.vendor_outage?(:sms) end def delivery_preference_voice? - VendorStatus.new.vendor_outage?(:sms) || setup_voice_preference? + OutageStatus.new.vendor_outage?(:sms) || setup_voice_preference? end # @return [Telephony::PhoneNumberInfo, nil] diff --git a/app/presenters/idv/gpo_presenter.rb b/app/presenters/idv/gpo_presenter.rb index 1ee0cb8ed12..9c7b210bb3e 100644 --- a/app/presenters/idv/gpo_presenter.rb +++ b/app/presenters/idv/gpo_presenter.rb @@ -18,6 +18,7 @@ def button end def fallback_back_path + return idv_verify_info_path if OutageStatus.new.any_phone_vendor_outage? user_needs_address_otp_verification? ? idv_gpo_verify_path : idv_phone_path end @@ -25,6 +26,22 @@ def resend_requested? current_user.decorate.pending_profile_requires_verification? end + def back_or_cancel_partial + if OutageStatus.new.gpo_only? + 'idv/doc_auth/cancel' + else + 'idv/shared/back' + end + end + + def back_or_cancel_parameters + if OutageStatus.new.gpo_only? + { step: 'gpo' } + else + { fallback_path: fallback_back_path } + end + end + private def user_needs_address_otp_verification? diff --git a/app/presenters/two_factor_authentication/phone_selection_presenter.rb b/app/presenters/two_factor_authentication/phone_selection_presenter.rb index f452e2142e1..1954589607c 100644 --- a/app/presenters/two_factor_authentication/phone_selection_presenter.rb +++ b/app/presenters/two_factor_authentication/phone_selection_presenter.rb @@ -21,7 +21,7 @@ def mfa_configuration_count end def disabled? - VendorStatus.new.all_phone_vendor_outage? || user&.phone_configurations&.any? + OutageStatus.new.all_phone_vendor_outage? || user&.phone_configurations&.any? end end end diff --git a/app/presenters/two_factor_authentication/sms_selection_presenter.rb b/app/presenters/two_factor_authentication/sms_selection_presenter.rb index 081efd9d847..3226ae6adc3 100644 --- a/app/presenters/two_factor_authentication/sms_selection_presenter.rb +++ b/app/presenters/two_factor_authentication/sms_selection_presenter.rb @@ -16,7 +16,7 @@ def info end def disabled? - VendorStatus.new.vendor_outage?(:sms) + OutageStatus.new.vendor_outage?(:sms) end end end diff --git a/app/presenters/two_factor_authentication/voice_selection_presenter.rb b/app/presenters/two_factor_authentication/voice_selection_presenter.rb index b2e4a061785..369878c5e5d 100644 --- a/app/presenters/two_factor_authentication/voice_selection_presenter.rb +++ b/app/presenters/two_factor_authentication/voice_selection_presenter.rb @@ -16,7 +16,7 @@ def info end def disabled? - VendorStatus.new.vendor_outage?(:voice) + OutageStatus.new.vendor_outage?(:voice) end end end diff --git a/app/services/idv/steps/welcome_step.rb b/app/services/idv/steps/welcome_step.rb index 1a5744a5e94..67116884635 100644 --- a/app/services/idv/steps/welcome_step.rb +++ b/app/services/idv/steps/welcome_step.rb @@ -12,7 +12,10 @@ def self.analytics_submitted_event end def call + flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow? + return no_camera_redirect if params[:no_camera] + create_document_capture_session(document_capture_session_uuid_key) cancel_previous_in_person_enrollments end diff --git a/app/services/vendor_status.rb b/app/services/outage_status.rb similarity index 82% rename from app/services/vendor_status.rb rename to app/services/outage_status.rb index 32af74b2370..33a7950ba54 100644 --- a/app/services/vendor_status.rb +++ b/app/services/outage_status.rb @@ -1,4 +1,4 @@ -class VendorStatus +class OutageStatus include ActionView::Helpers::TranslationHelper def initialize(from: nil, from_idv: nil, sp: nil) @@ -7,9 +7,9 @@ def initialize(from: nil, from_idv: nil, sp: nil) @sp = sp end - IAL2_VENDORS = %i[acuant lexisnexis_instant_verify lexisnexis_trueid].freeze + IDV_VENDORS = %i[acuant lexisnexis_instant_verify lexisnexis_trueid].freeze PHONE_VENDORS = %i[sms voice].freeze - ALL_VENDORS = (IAL2_VENDORS + PHONE_VENDORS).freeze + ALL_VENDORS = (IDV_VENDORS + PHONE_VENDORS).freeze def vendor_outage?(vendor) status = case vendor @@ -37,8 +37,8 @@ def all_vendor_outage?(vendors = ALL_VENDORS) vendors.all? { |vendor| vendor_outage?(vendor) } end - def any_ial2_vendor_outage? - any_vendor_outage?(IAL2_VENDORS) + def any_idv_vendor_outage? + any_vendor_outage?(IDV_VENDORS) end def any_phone_vendor_outage? @@ -49,6 +49,16 @@ def all_phone_vendor_outage? all_vendor_outage?(PHONE_VENDORS) end + def gpo_only? + IdentityConfig.store.feature_idv_force_gpo_verification_enabled || + any_phone_vendor_outage? + end + + def allow_hybrid_flow? + IdentityConfig.store.feature_idv_hybrid_flow_enabled && + !any_phone_vendor_outage? + end + def from_idv? from_idv end @@ -58,7 +68,7 @@ def from_idv? # # @return [String, nil] the localized message. def outage_message - if any_ial2_vendor_outage? + if any_idv_vendor_outage? if from_idv? if sp t('vendor_outage.blocked.idv.with_sp', service_provider: sp.friendly_name) diff --git a/app/views/idv/gpo/index.html.erb b/app/views/idv/gpo/index.html.erb index ac0e48dd06b..69ec0f3f07b 100644 --- a/app/views/idv/gpo/index.html.erb +++ b/app/views/idv/gpo/index.html.erb @@ -42,4 +42,4 @@ ], ) %> -<%= render 'idv/shared/back', fallback_path: @presenter.fallback_back_path %> +<%= render @presenter.back_or_cancel_partial, @presenter.back_or_cancel_parameters %> diff --git a/app/views/idv/gpo_only_warning/show.html.erb b/app/views/idv/gpo_only_warning/show.html.erb new file mode 100644 index 00000000000..78e7a4c77e0 --- /dev/null +++ b/app/views/idv/gpo_only_warning/show.html.erb @@ -0,0 +1,53 @@ +<%= render StepIndicatorComponent.new( + steps: step_indicator_steps, + current_step: :getting_started, + locale_scope: 'idv', + class: 'margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4', + ) %> + +<%= render StatusPageComponent.new(status: :warning) do |c| %> + <% c.header { t('vendor_outage.alerts.pinpoint.idv.header') } %> +

+ <%= t('vendor_outage.alerts.pinpoint.idv.message_html', app_name: APP_NAME, sp_name: current_sp&.friendly_name || APP_NAME) %> +

+ <%= t('vendor_outage.alerts.pinpoint.idv.options_prompt') %> + + <% c.action_button( + action: ->(**tag_options, &block) do + link_to(idv_doc_auth_step_path(step: :welcome), **tag_options, &block) + end, + big: true, + wide: true, + class: 'usa-button', + ).with_content(t('doc_auth.buttons.continue')) %> + <% c.action_button( + action: ->(**tag_options, &block) do + link_to(exit_url, **tag_options, &block) + end, + big: true, + wide: true, + outline: true, + class: 'usa-button', + ).with_content(t('links.exit_login', app_name: APP_NAME)) %> + <% c.troubleshooting_options do |tc| %> + <% tc.header { t('components.troubleshooting_options.default_heading') } %> + <% tc.option( + url: StatusPage.base_url, + new_tab: true, + ).with_content(t('vendor_outage.get_updates_on_status_page')) %> + <% if decorated_session.sp_name %> + <% tc.option( + url: current_sp.return_to_sp_url, + new_tab: true, + ).with_content( + t('idv.troubleshooting.options.get_help_at_sp', sp_name: decorated_session.sp_name), + ) %> + <% end %> + <% end %> +<% end %> diff --git a/app/views/idv/gpo_verify/index.html.erb b/app/views/idv/gpo_verify/index.html.erb index 3b57f850770..e9921d693a0 100644 --- a/app/views/idv/gpo_verify/index.html.erb +++ b/app/views/idv/gpo_verify/index.html.erb @@ -41,7 +41,7 @@ <% end %> -<% if FeatureManagement.enable_gpo_verification? && !@mail_spammed %> +<% if FeatureManagement.gpo_verification_enabled? && !@mail_spammed %> <%= link_to t('idv.messages.gpo.resend'), idv_gpo_path, class: 'display-block margin-bottom-2' %> <% end %> diff --git a/app/views/idv/phone/new.html.erb b/app/views/idv/phone/new.html.erb index e0a34dec849..2c6e5f38dfc 100644 --- a/app/views/idv/phone/new.html.erb +++ b/app/views/idv/phone/new.html.erb @@ -71,8 +71,8 @@ <%= f.radio_button( :otp_delivery_preference, :sms, - checked: !VendorStatus.new.vendor_outage?(:sms), # We want SMS to be default checked - disabled: VendorStatus.new.vendor_outage?(:sms), + checked: !OutageStatus.new.vendor_outage?(:sms), # We want SMS to be default checked + disabled: OutageStatus.new.vendor_outage?(:sms), class: 'usa-radio__input usa-radio__input--bordered', ) %> <%= f.label :otp_delivery_preference_sms, t('two_factor_authentication.otp_delivery_preference.sms'), class: 'usa-radio__label width-full' %> @@ -81,7 +81,7 @@ <%= f.radio_button( :otp_delivery_preference, :voice, - disabled: VendorStatus.new.vendor_outage?(:voice), + disabled: OutageStatus.new.vendor_outage?(:voice), class: 'usa-radio__input usa-radio__input--bordered', ) %> <%= f.label :otp_delivery_preference_voice, t('two_factor_authentication.otp_delivery_preference.voice'), class: 'usa-radio__label width-full' %> diff --git a/app/views/users/shared/_otp_delivery_preference_selection.html.erb b/app/views/users/shared/_otp_delivery_preference_selection.html.erb index cc3bb484104..3727d029215 100644 --- a/app/views/users/shared/_otp_delivery_preference_selection.html.erb +++ b/app/views/users/shared/_otp_delivery_preference_selection.html.erb @@ -14,7 +14,7 @@ form_name_label, :sms, form_obj.delivery_preference_sms?, - disabled: VendorStatus.new.vendor_outage?(:sms), + disabled: OutageStatus.new.vendor_outage?(:sms), class: 'js-otp-delivery-preference usa-radio__input usa-radio__input--bordered', ) %>