From 71520d1b32e65e45c871cb247727a1960df22064 Mon Sep 17 00:00:00 2001 From: Steve Urciuoli Date: Wed, 27 Mar 2019 00:32:49 -0400 Subject: [PATCH 1/4] LG-1045 Fix doc auth doc error handling **Why**: So users can get clear instructions on how to retry documents upon failure **How**: Create a generic error condition for document errors and reset the flow to start at the front image upon failure. --- app/services/flow/base_flow.rb | 11 +++++------ app/services/flow/base_step.rb | 2 +- app/services/flow/flow_state_machine.rb | 4 ++-- app/services/idv/flows/capture_doc_flow.rb | 4 ++-- app/services/idv/flows/doc_auth_flow.rb | 4 ++-- app/services/idv/flows/recovery_flow.rb | 4 ++-- app/services/idv/steps/recover_doc_success_step.rb | 1 + config/locales/recover/en.yml | 3 +++ config/locales/recover/es.yml | 3 +++ config/locales/recover/fr.yml | 3 +++ 10 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/services/flow/base_flow.rb b/app/services/flow/base_flow.rb index e559055b4e6..0fa5f735feb 100644 --- a/app/services/flow/base_flow.rb +++ b/app/services/flow/base_flow.rb @@ -3,11 +3,10 @@ class BaseFlow attr_accessor :flow_session attr_reader :steps, :actions, :current_user, :params, :request - def initialize(steps, actions, session, current_user) - @current_user = current_user + def initialize(controller, steps, actions, session) + @controller = controller @steps = steps.with_indifferent_access @actions = actions.with_indifferent_access - @params = nil @redirect = nil @flow_session = session end @@ -24,12 +23,10 @@ def redirect_to(url) @redirect = url end - def handle(step, request, params) + def handle(step) @flow_session[:error_message] = nil handler = steps[step] || actions[step] return failure("Unhandled step #{step}") unless handler - @params = params - @request = request wrap_send(handler) end @@ -46,5 +43,7 @@ def form_response(obj, value) obj.mark_step_complete if response.success? response end + + delegate :flash, :session, :current_user, :params, :request, to: :@controller end end diff --git a/app/services/flow/base_step.rb b/app/services/flow/base_step.rb index 88041485d21..d6370acde1b 100644 --- a/app/services/flow/base_step.rb +++ b/app/services/flow/base_step.rb @@ -51,6 +51,6 @@ def reset @flow.flow_session = {} end - delegate :session, :flow_session, :current_user, :params, :steps, :request, to: :@flow + delegate :flash, :session, :flow_session, :current_user, :params, :steps, :request, to: :@flow end end diff --git a/app/services/flow/flow_state_machine.rb b/app/services/flow/flow_state_machine.rb index 0f2f0346a43..06c23d8d729 100644 --- a/app/services/flow/flow_state_machine.rb +++ b/app/services/flow/flow_state_machine.rb @@ -21,7 +21,7 @@ def show def update step = params[:step] - result = flow.handle(step, request, params) + result = flow.handle(step) analytics.track_event(analytics_submitted, result.to_h.merge(step: step)) if @analytics_id flow_finish and return unless next_step render_update(step, result) @@ -34,7 +34,7 @@ def fsm_initialize @name = klass.name.underscore.gsub('_controller', '') klass::FSM_SETTINGS.each { |key, value| instance_variable_set("@#{key}", value) } current_session[@name] ||= {} - @flow = @flow.new(current_session, current_user, @name) + @flow = @flow.new(self, current_session, @name) end def render_update(step, result) diff --git a/app/services/idv/flows/capture_doc_flow.rb b/app/services/idv/flows/capture_doc_flow.rb index adaf2342e89..5cbff7ca052 100644 --- a/app/services/idv/flows/capture_doc_flow.rb +++ b/app/services/idv/flows/capture_doc_flow.rb @@ -11,8 +11,8 @@ class CaptureDocFlow < Flow::BaseFlow reset: Idv::Actions::ResetAction, }.freeze - def initialize(session, current_user, _name) - super(STEPS, ACTIONS, session, current_user) + def initialize(controller, session, _name) + super(controller, STEPS, ACTIONS, session) end end end diff --git a/app/services/idv/flows/doc_auth_flow.rb b/app/services/idv/flows/doc_auth_flow.rb index 493b7561800..3d5edcc8f96 100644 --- a/app/services/idv/flows/doc_auth_flow.rb +++ b/app/services/idv/flows/doc_auth_flow.rb @@ -23,9 +23,9 @@ class DocAuthFlow < Flow::BaseFlow attr_reader :idv_session # this is needed to support (and satisfy) the current LOA3 flow - def initialize(session, current_user, name) + def initialize(controller, session, name) @idv_session = self.class.session_idv(session) - super(STEPS, ACTIONS, session[name], current_user) + super(controller, STEPS, ACTIONS, session[name]) end def self.session_idv(session) diff --git a/app/services/idv/flows/recovery_flow.rb b/app/services/idv/flows/recovery_flow.rb index 1e14c0695df..c8ae7852804 100644 --- a/app/services/idv/flows/recovery_flow.rb +++ b/app/services/idv/flows/recovery_flow.rb @@ -24,10 +24,10 @@ class RecoveryFlow < Flow::BaseFlow attr_reader :idv_session, :session # needed to support (and satisfy) the current LOA3 flow - def initialize(session, current_user, name) + def initialize(controller, session, name) @session = session @idv_session = self.class.session_idv(session) - super(STEPS, ACTIONS, session[name], current_user) + super(controller, STEPS, ACTIONS, session[name]) end def self.session_idv(session) diff --git a/app/services/idv/steps/recover_doc_success_step.rb b/app/services/idv/steps/recover_doc_success_step.rb index fe2b5a0fa06..726273169e2 100644 --- a/app/services/idv/steps/recover_doc_success_step.rb +++ b/app/services/idv/steps/recover_doc_success_step.rb @@ -7,6 +7,7 @@ def call return unless pii_matches_data_on_file?(pii_from_doc, decrypted_pii) mark_step_complete(:recover_fail) + flash[:success] = I18n.t('recover.reverify.success') redirect_to account_url session['need_two_factor_authentication'] = false end diff --git a/config/locales/recover/en.yml b/config/locales/recover/en.yml index 4ad4deea951..7c256ba9315 100644 --- a/config/locales/recover/en.yml +++ b/config/locales/recover/en.yml @@ -20,3 +20,6 @@ en: fail: Recover fail instructions: We want to make sure you, and only you, have access to your account reverify: Next, let's re-verify your identity + success: You have successfully recovered your account. To prevent having to + recover your account in the future, please add another security option from + the two-factor authentication options below. diff --git a/config/locales/recover/es.yml b/config/locales/recover/es.yml index 7a6e8a2f5e7..9bc6ee65de5 100644 --- a/config/locales/recover/es.yml +++ b/config/locales/recover/es.yml @@ -22,3 +22,6 @@ es: instructions: Queremos asegurarnos de que usted, y solo usted, tenga acceso a su cuenta reverify: A continuación, volvamos a verificar su identidad + success: Has recuperado exitosamente tu cuenta. Para evitar tener que recuperar + su cuenta en el futuro, agregue otra opción de seguridad de las siguientes + opciones de autenticación de dos factores. diff --git a/config/locales/recover/fr.yml b/config/locales/recover/fr.yml index 1fba2e2461a..608871c8653 100644 --- a/config/locales/recover/fr.yml +++ b/config/locales/recover/fr.yml @@ -21,3 +21,6 @@ fr: instructions: Nous voulons nous assurer que vous et seulement vous avez accès à votre compte reverify: Ensuite, revérifions votre identité + success: Vous avez bien récupéré votre compte. Pour éviter de devoir récupérer + votre compte à l'avenir, veuillez ajouter une autre option de sécurité parmi + les options d'authentification à deux facteurs ci-dessous. From 454f7d1b465aec30eb931bc1502203f89ebb61ca Mon Sep 17 00:00:00 2001 From: Steve Urciuoli Date: Wed, 27 Mar 2019 00:46:19 -0400 Subject: [PATCH 2/4] Remove redundant spec --- spec/services/idv/flows/doc_auth_flow_spec.rb | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 spec/services/idv/flows/doc_auth_flow_spec.rb diff --git a/spec/services/idv/flows/doc_auth_flow_spec.rb b/spec/services/idv/flows/doc_auth_flow_spec.rb deleted file mode 100644 index dbd0fc0e15a..00000000000 --- a/spec/services/idv/flows/doc_auth_flow_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'rails_helper' - -describe Idv::Flows::DocAuthFlow do - include DocAuthHelper - - let(:user) { create(:user) } - let(:new_session) { { doc_auth: {} } } - let(:name) { :doc_auth } - - describe '#next_step' do - it 'returns welcome as the first step' do - subject = Idv::Flows::DocAuthFlow.new(new_session, user, name) - result = subject.next_step - - expect(result).to eq('welcome') - end - - it 'returns upload after the welcome step' do - expect_next_step(:welcome, :upload) - end - - it 'returns back_image after the front image step' do - expect_next_step(:front_image, :back_image) - end - end - - describe '#handle' do - it 'handles the next step and returns a form response object' do - subject = Idv::Flows::DocAuthFlow.new(new_session, user, name) - params = ActionController::Parameters.new(doc_auth: { ssn: '111111111' }) - expect_any_instance_of(Idv::Steps::SsnStep).to receive(:call).exactly(:once) - - result = subject.handle(:ssn, {}, params) - expect(result.class).to eq(FormResponse) - expect(result.success?).to eq(true) - end - end - - def expect_next_step(step, next_step) - session = session_from_completed_flow_steps(step) - subject = Idv::Flows::DocAuthFlow.new(session, user, name) - result = subject.next_step - - expect(result.to_s).to eq(next_step.to_s) - end -end From 4174dc83723bccf8b85f7edb1f81e2a95925d580 Mon Sep 17 00:00:00 2001 From: Steve Urciuoli Date: Wed, 27 Mar 2019 00:57:55 -0400 Subject: [PATCH 3/4] Lint --- app/services/idv/steps/recover_doc_success_step.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/services/idv/steps/recover_doc_success_step.rb b/app/services/idv/steps/recover_doc_success_step.rb index 726273169e2..d5247820e33 100644 --- a/app/services/idv/steps/recover_doc_success_step.rb +++ b/app/services/idv/steps/recover_doc_success_step.rb @@ -6,14 +6,18 @@ def call decrypted_pii = JSON.parse(saved_pii) return unless pii_matches_data_on_file?(pii_from_doc, decrypted_pii) + recovery_success + end + + private + + def recovery_success mark_step_complete(:recover_fail) flash[:success] = I18n.t('recover.reverify.success') redirect_to account_url session['need_two_factor_authentication'] = false end - private - def saved_pii session['decrypted_pii'] end From 3c3c1d4bdd16cd6c7344baff684c35f88b7b83c0 Mon Sep 17 00:00:00 2001 From: Steve Urciuoli Date: Wed, 27 Mar 2019 01:45:18 -0400 Subject: [PATCH 4/4] Fix what formats we accept --- config/locales/doc_auth/en.yml | 2 +- config/locales/doc_auth/es.yml | 2 +- config/locales/doc_auth/fr.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index d5d8b135b03..7c7adebf44c 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -46,7 +46,7 @@ en: use a scanner to capture images of your ID upload_from_phone: Upload pictures directly from your phone camera upload_image: We only use your ID to verify your identity, and we will not save - any images. We accept PDF, PNG, and JPG formats. + any images. We accept BMP, PNG, TIFF, and JPG formats. welcome: We verify your identity to make sure you are you—not someone pretending to be you. Verifying your identity also allows you to access services that handle Personal Identifiable Information. diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index 6a453af3946..7a6512d502e 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -48,7 +48,7 @@ es: o use un escáner para capturar imágenes de su identificación upload_from_phone: Sube imágenes directamente desde la cámara de tu teléfono upload_image: Solo utilizamos su ID para verificar su identidad y no guardaremos - ninguna imagen. Aceptamos formatos PDF, PNG, y JPG. + ninguna imagen. Aceptamos los formatos BMP, PNG, TIFF y JPG. welcome: Verificamos su identidad para asegurarnos de que usted es usted, y no alguien que pretende ser usted. La verificación de su identidad también le permite acceder a servicios que manejan información de identificación personal. diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 218ec5c755c..94cb4834d97 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -55,8 +55,8 @@ fr: upload_from_phone: Téléchargez des images directement depuis l'appareil photo de votre téléphone upload_image: Nous n'utilisons votre identifiant que pour vérifier votre identité, - et nous n'enregistrerons aucune image. Nous acceptons les formats PDF, PNG - et JPG. + et nous n'enregistrerons aucune image. Nous acceptons les formats BMP, PNG, + TIFF et JPG. welcome: Nous vérifions votre identité pour nous assurer que vous êtes bien, et non quelqu'un prétendant être vous. La vérification de votre identité vous permet également d'accéder à des services traitant des informations personnelles