Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ GIT

GIT
remote: https://github.com/18F/identity-idp-functions.git
revision: 1ffdce9da7fd2d69de2b51a04873bc8bbd9c3f4b
ref: 1ffdce9da7fd2d69de2b51a04873bc8bbd9c3f4b
revision: d32d49bc27c62a510695c6fe498c6d9b8942f6be
ref: d32d49bc27c62a510695c6fe498c6d9b8942f6be
specs:
identity-idp-functions (0.3.0)
identity-idp-functions (0.3.2)
retries (>= 0.0.5)

GIT
remote: https://github.com/18F/identity-lexisnexis-api-client-gem.git
Expand Down
31 changes: 24 additions & 7 deletions app/controllers/idv/phone_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,27 @@ class PhoneController < ApplicationController
before_action :set_idv_form

def new
analytics.track_event(Analytics::IDV_PHONE_RECORD_VISIT)
async_state = step.async_state

case async_state.status
when :none
analytics.track_event(Analytics::IDV_PHONE_RECORD_VISIT)
render :new
when :in_progress
render :wait
when :timed_out
render :new
when :done
async_state_done(async_state)
end
end

def create
result = idv_form.submit(step_params)
analytics.track_event(Analytics::IDV_PHONE_CONFIRMATION_FORM, result.to_h)
return render(:new) unless result.success?
submit_proofing_attempt
redirect_to idv_phone_path
end

private
Expand All @@ -34,14 +47,11 @@ def phone_confirmation_required?
end

def submit_proofing_attempt
idv_result = step.submit(step_params.to_h)
analytics.track_event(Analytics::IDV_PHONE_CONFIRMATION_VENDOR, idv_result.to_h)
redirect_to_next_step and return if idv_result.success?
handle_proofing_failure
step.submit(step_params.to_h)
end

def handle_proofing_failure
idv_session.previous_phone_step_params = step_params.to_h
def handle_proofing_failure(pii)
idv_session.previous_phone_step_params = { 'phone' => pii[:phone] }
redirect_to failure_url(step.failure_reason)
end

Expand Down Expand Up @@ -80,5 +90,12 @@ def failure_url(reason)
idv_phone_errors_failure_url
end
end

def async_state_done(async_state)
form_result = step.async_state_done(async_state)
analytics.track_event(Analytics::IDV_PHONE_CONFIRMATION_VENDOR, form_result.to_h)
redirect_to_next_step and return if async_state.result[:success]
handle_proofing_failure(async_state.pii)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class AddressProofResultController < AuthTokenController
def create
dcs = DocumentCaptureSession.new
dcs.result_id = result_id_parameter
dcs.store_proofing_result(address_result_parameter)
dcs.store_proofing_result(address_result_parameter.to_h)
end

private
Expand All @@ -13,7 +13,8 @@ def result_id_parameter
end

def address_result_parameter
params.require(:address_result)
params.require(:address_result).permit(:exception, :success, :timed_out,
errors: {}, context: {})
end

def config_auth_token
Expand Down
16 changes: 13 additions & 3 deletions app/services/idv/agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@ def proof_resolution(should_proof_state_id:)
submit_applicant(vendor: vendor, results: results)
end

def proof_address
vendor = Idv::Proofer.address_vendor.new
submit_applicant(vendor: vendor, results: init_results)
def proof_address(document_capture_session)
callback_url = Rails.application.routes.url_helpers.address_proof_result_url(
document_capture_session.result_id,
)

LambdaJobs::Runner.new(
job_name: nil, job_class: Idv::Proofer.address_job_class,
args: { applicant_pii: @applicant, callback_url: callback_url }
).run do |idv_result|
document_capture_session.store_proofing_result(idv_result[:address_result])

nil
end
end

private
Expand Down
69 changes: 51 additions & 18 deletions app/services/idv/phone_step.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@ def initialize(idv_session:)
def submit(step_params)
self.step_params = step_params
proof_address
increment_attempts_count unless failed_due_to_timeout_or_exception?
success = idv_result[:success]
handle_successful_proofing_attempt if success
FormResponse.new(
success: success, errors: idv_result[:errors],
extra: extra_analytics_attributes
)
end

def failure_reason
Expand All @@ -23,6 +16,36 @@ def failure_reason
return :warning if idv_result[:success] != true
end

def async_state
dcs_uuid = idv_session.idv_phone_step_document_capture_session_uuid
dcs = DocumentCaptureSession.find_by(uuid: dcs_uuid)
return ProofingDocumentCaptureSessionResult.none if dcs_uuid.nil?
return ProofingDocumentCaptureSessionResult.timed_out if dcs.nil?

proofing_job_result = dcs.load_proofing_result
return ProofingDocumentCaptureSessionResult.timed_out if proofing_job_result.nil?

if proofing_job_result.result
proofing_job_result.done
elsif proofing_job_result.pii
ProofingDocumentCaptureSessionResult.in_progress
end
end

def async_state_done(async_state)
@idv_result = async_state.result
pii = async_state.pii

increment_attempts_count unless failed_due_to_timeout_or_exception?
success = idv_result[:success]
handle_successful_proofing_attempt(pii) if success
idv_session.idv_phone_step_document_capture_session_uuid = nil
FormResponse.new(
success: success, errors: idv_result[:errors],
extra: extra_analytics_attributes
)
end

private

attr_accessor :idv_session, :step_params, :idv_result
Expand All @@ -32,13 +55,19 @@ def idv_max_attempts
end

def proof_address
self.idv_result = Idv::Agent.new(applicant).proof_address
document_capture_session = DocumentCaptureSession.create(user_id: idv_session.current_user.id,
requested_at: Time.zone.now)

document_capture_session.store_proofing_pii_from_doc(applicant)
idv_session.idv_phone_step_document_capture_session_uuid = document_capture_session.uuid

run_job(document_capture_session)
add_proofing_cost
end

def handle_successful_proofing_attempt
update_idv_session
start_phone_confirmation_session
def handle_successful_proofing_attempt(successful_applicant)
update_idv_session(successful_applicant)
start_phone_confirmation_session(successful_applicant)
end

def add_proofing_cost
Expand Down Expand Up @@ -81,24 +110,24 @@ def failed_due_to_timeout_or_exception?
idv_result[:timed_out] || idv_result[:exception]
end

def update_idv_session
def update_idv_session(successful_applicant)
idv_session.address_verification_mechanism = :phone
idv_session.applicant = applicant
idv_session.applicant = successful_applicant
idv_session.vendor_phone_confirmation = true
idv_session.user_phone_confirmation = phone_matches_user_phone?
idv_session.user_phone_confirmation = phone_matches_user_phone?(successful_applicant[:phone])
Db::ProofingComponent::Add.call(idv_session.current_user.id, :address_check,
'lexis_nexis_address')
end

def start_phone_confirmation_session
def start_phone_confirmation_session(successful_applicant)
idv_session.user_phone_confirmation_session = PhoneConfirmation::ConfirmationSession.start(
phone: PhoneFormatter.format(applicant[:phone]),
phone: PhoneFormatter.format(successful_applicant[:phone]),
delivery_method: :sms,
)
end

def phone_matches_user_phone?
applicant_phone = PhoneFormatter.format(applicant[:phone])
def phone_matches_user_phone?(phone)
applicant_phone = PhoneFormatter.format(phone)
return false if applicant_phone.blank?
user_phones.include?(applicant_phone)
end
Expand All @@ -116,5 +145,9 @@ def extra_analytics_attributes
vendor: idv_result.except(:errors, :success),
}
end

def run_job(document_capture_session)
Idv::Agent.new(applicant).proof_address(document_capture_session)
end
end
end
15 changes: 9 additions & 6 deletions app/services/idv/proofer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ module Proofer

class << self
def validate_vendors!
if mock_fallback_enabled?
require 'identity-idp-functions/proof_address_mock'
else
require 'identity-idp-functions/proof_address'
end

resolution_vendor.new
state_id_vendor.new
address_vendor.new
end

def resolution_vendor
Expand All @@ -25,16 +30,14 @@ def state_id_vendor
end
end

def address_vendor
def address_job_class
if mock_fallback_enabled?
AddressMock
IdentityIdpFunctions::ProofAddressMock
else
LexisNexis::PhoneFinder::Proofer
IdentityIdpFunctions::ProofAddress
end
end

private

def mock_fallback_enabled?
Figaro.env.proofer_mock_fallback == 'true'
end
Expand Down
1 change: 1 addition & 0 deletions app/services/idv/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class Session
VALID_SESSION_ATTRIBUTES = %i[
address_verification_mechanism
applicant
idv_phone_step_document_capture_session_uuid
vendor_phone_confirmation
user_phone_confirmation
pii
Expand Down
32 changes: 5 additions & 27 deletions app/services/idv/steps/verify_wait_step_show.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
module Idv
module Steps
class VerifyWaitStepShow < VerifyBaseStep
State = Struct.new(:status, :pii, :result, keyword_init: true) do
def self.none
new(status: :none)
end

def self.timed_out
new(status: :timed_out)
end

def self.in_progress
new(status: :in_progress)
end

def self.done(pii:, result:)
new(status: :done, pii: pii, result: result)
end

private_class_method :new
end

def call
poll_with_meta_refresh(Figaro.env.poll_rate_for_verify_in_seconds.to_i)

Expand Down Expand Up @@ -59,18 +39,16 @@ def async_state_done(current_async_state)
def async_state
dcs_uuid = flow_session[:idv_verify_step_document_capture_session_uuid]
dcs = DocumentCaptureSession.find_by(uuid: dcs_uuid)
return State.none if dcs_uuid.nil?
return State.timed_out if dcs.nil?
return ProofingDocumentCaptureSessionResult.none if dcs_uuid.nil?
return ProofingDocumentCaptureSessionResult.timed_out if dcs.nil?

proofing_job_result = dcs.load_proofing_result
return State.timed_out if proofing_job_result.nil?
return ProofingDocumentCaptureSessionResult.timed_out if proofing_job_result.nil?

if proofing_job_result.result
proofing_job_result.result.deep_symbolize_keys!
proofing_job_result.pii.deep_symbolize_keys!
State.done(pii: proofing_job_result.pii, result: proofing_job_result.result)
proofing_job_result.done
elsif proofing_job_result.pii
State.in_progress
ProofingDocumentCaptureSessionResult.in_progress
end
end

Expand Down
2 changes: 1 addition & 1 deletion app/services/lambda_jobs/git_ref.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module LambdaJobs
GIT_REF = '1ffdce9da7fd2d69de2b51a04873bc8bbd9c3f4b'
GIT_REF = 'd32d49bc27c62a510695c6fe498c6d9b8942f6be'
end
2 changes: 1 addition & 1 deletion app/services/lambda_jobs/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def run(&local_callback)
)
else
job_class.handle(
event: { body: args.to_json },
event: { 'body' => args.to_json },
context: nil,
&local_callback
)
Expand Down
23 changes: 22 additions & 1 deletion app/services/proofing_document_capture_session_result.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
# frozen_string_literal: true

ProofingDocumentCaptureSessionResult = Struct.new(:id, :pii, :result, keyword_init: true) do
ProofingDocumentCaptureSessionResult = Struct.new(:id, :pii, :result, :status,
keyword_init: true) do
def self.redis_key_prefix
'dcs-proofing:result'
end

def self.none
new(status: :none)
end

def self.timed_out
new(status: :timed_out)
end

def self.in_progress
new(status: :in_progress)
end

def done
ProofingDocumentCaptureSessionResult.new(
pii: pii.deep_symbolize_keys,
result: result.deep_symbolize_keys,
status: :done,
)
end
end
3 changes: 3 additions & 0 deletions app/views/idv/phone/wait.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<% title t('doc_auth.titles.doc_auth') %>

<h1 class="h3 my0"><%= t('doc_auth.info.interstitial_eta') %></h1>
Loading