Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
dffef2e
Update query timeout in duplicate SSN report (LG-11963) (#9818)
zachmargolis Dec 21, 2023
9b45bda
Turn off DocumentCapture exit survey in development (#9821)
soniaconnolly Dec 21, 2023
02ead1b
LG-11839 Don't delete proofing_component on password reset for profil…
theabrad Dec 21, 2023
099ef6b
LG-11873: doc auth w/ selfie in non-prod hosted envs (#9729)
amirbey Dec 21, 2023
8b93f73
LG-11845: feature flag doc_auth_custom_ui_enabled. (#9822)
dawei-nava Dec 21, 2023
59d8673
LG-11655: Added the ability to email IdV reports (#9792)
theabrad Dec 21, 2023
0a79dcc
LG-10396 Update PII Validation for State/Territory (#9797)
charleyf Dec 21, 2023
c532802
LG-10423: Update PII Validation to Validate Document ID Number (#9777)
charleyf Dec 22, 2023
7ea3971
Remove unused flags images (#9817)
aduth Dec 22, 2023
e4472f2
Update Lookbook to latest version (2.2) (#9824)
aduth Dec 22, 2023
ea63df2
Ensure vendor folder exists (#9828)
Dec 22, 2023
c5f9fdd
updated headers to allow for iframe in dev docs (#9786)
nprimak Dec 27, 2023
b97970e
Jmax/lg 11942 update mock doc auth client to support selfie flag (#9833)
jmax-gsa Dec 27, 2023
b430ac9
Update data pull script documentation (#9834)
Dec 27, 2023
173519b
LG-11906 Update Review Step UI with Selfie to Match Document Step wit…
charleyf Dec 28, 2023
c9fd9ca
Rework `review-step` Typing to use Shared Types and Utilities (#9836)
charleyf Dec 29, 2023
3ed51e9
Bump libphonenumber-js from 1.10.52 to 1.10.53 (#9832)
dependabot[bot] Dec 29, 2023
cf30024
LG-11893: Prep by Continuing Unifying `document-capture` and `review-…
charleyf Dec 29, 2023
9091437
Lg 11929 update daily email recipients (#9830)
ThatSpaceGuy Jan 1, 2024
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
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ gem 'jsbundling-rails', '~> 1.1.2'
gem 'jwe'
gem 'jwt'
gem 'lograge', '>= 0.11.2'
gem 'lookbook', '~> 2.0.0', require: false
gem 'lookbook', '~> 2.2', require: false
gem 'lru_redux'
gem 'mail'
gem 'msgpack', '~> 1.6'
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ GEM
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
lookbook (2.0.5)
lookbook (2.2.0)
activemodel
css_parser
htmlbeautifier (~> 1.3)
Expand Down Expand Up @@ -781,7 +781,7 @@ DEPENDENCIES
letter_opener (~> 1.8)
listen
lograge (>= 0.11.2)
lookbook (~> 2.0.0)
lookbook (~> 2.2)
lru_redux
mail
maxminddb
Expand Down
1 change: 1 addition & 0 deletions app/controllers/idv/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def extra_view_variables
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
skip_doc_auth: idv_session.skip_doc_auth,
opted_in_to_in_person_proofing: idv_session.opted_in_to_in_person_proofing,
doc_auth_selfie_capture: decorated_sp_session.selfie_required?,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def extra_view_variables
flow_path: 'hybrid',
document_capture_session_uuid: document_capture_session_uuid,
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
doc_auth_selfie_capture: decorated_sp_session.selfie_required?,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
Expand Down
12 changes: 1 addition & 11 deletions app/controllers/idv/image_uploads_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module Idv
class ImageUploadsController < ApplicationController
include ApplicationHelper # for liveness_checking_enabled?

respond_to :json

def create
Expand All @@ -20,12 +18,12 @@ def create
def image_upload_form
@image_upload_form ||= Idv::ApiImageUploadForm.new(
params,
liveness_checking_enabled: liveness_checking_enabled?,
service_provider: current_sp,
analytics: analytics,
uuid_prefix: current_sp&.app_id,
irs_attempts_api_tracker: irs_attempts_api_tracker,
store_encrypted_images: store_encrypted_images?,
liveness_checking_required: decorated_sp_session.selfie_required?,
)
end

Expand All @@ -36,13 +34,5 @@ def store_encrypted_images?
def liveness_checking_enabled?
IdentityConfig.store.doc_auth_selfie_capture_enabled
end

def ial_context
@ial_context ||= IalContext.new(
ial: sp_session_ial,
service_provider: current_sp,
user: current_user,
)
end
end
end
4 changes: 4 additions & 0 deletions app/decorators/null_service_provider_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def request_url_params
{}
end

def selfie_required?
false
end

private

attr_reader :view_context
Expand Down
2 changes: 2 additions & 0 deletions app/decorators/service_provider_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ def sp_issuer
end

def selfie_required?
return false if Identity::Hostdata.env == 'prod'

!!(IdentityConfig.store.doc_auth_selfie_capture_enabled &&
sp_session[:biometric_comparison_required])
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def update_user
end

def mark_profile_inactive
return if user.active_profile.blank?

user.active_profile&.deactivate(:password_reset)
Funnel::DocAuth::ResetSteps.call(@user.id)
user.proofing_component&.destroy
Expand Down
16 changes: 8 additions & 8 deletions app/forms/idv/api_image_upload_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ class ApiImageUploadForm

validates_presence_of :front
validates_presence_of :back
validates_presence_of :selfie, if: :liveness_checking_enabled
validates_presence_of :selfie, if: :liveness_checking_required
validates_presence_of :document_capture_session

validate :validate_images
validate :validate_duplicate_images, if: :image_resubmission_check?
validate :limit_if_rate_limited

def initialize(params, service_provider:, analytics: nil,
uuid_prefix: nil, irs_attempts_api_tracker: nil, store_encrypted_images: false,
liveness_checking_enabled: false)
uuid_prefix: nil, irs_attempts_api_tracker: nil,
store_encrypted_images: false, liveness_checking_required: false)
@params = params
@service_provider = service_provider
@analytics = analytics
@readable = {}
@uuid_prefix = uuid_prefix
@irs_attempts_api_tracker = irs_attempts_api_tracker
@store_encrypted_images = store_encrypted_images
@liveness_checking_enabled = liveness_checking_enabled
@liveness_checking_required = liveness_checking_required
end

def submit
Expand Down Expand Up @@ -54,7 +54,7 @@ def submit
private

attr_reader :params, :analytics, :service_provider, :form_response, :uuid_prefix,
:irs_attempts_api_tracker, :liveness_checking_enabled
:irs_attempts_api_tracker, :liveness_checking_required

def increment_rate_limiter!
return unless document_capture_session
Expand Down Expand Up @@ -83,11 +83,11 @@ def post_images_to_client
doc_auth_client.post_images(
front_image: front_image_bytes,
back_image: back_image_bytes,
selfie_image: liveness_checking_enabled ? selfie_image_bytes : nil,
selfie_image: liveness_checking_required ? selfie_image_bytes : nil,
image_source: image_source,
user_uuid: user_uuid,
uuid_prefix: uuid_prefix,
liveness_checking_enabled: liveness_checking_enabled,
liveness_checking_required: liveness_checking_required,
)
end

Expand Down Expand Up @@ -370,7 +370,7 @@ def add_costs(response)
Db::AddDocumentVerificationAndSelfieCosts.
new(user_id: user_id,
service_provider: service_provider,
liveness_checking_enabled: liveness_checking_enabled).
liveness_checking_enabled: liveness_checking_required).
call(response)
end

Expand Down
20 changes: 10 additions & 10 deletions app/forms/idv/doc_pii_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,23 @@ class DocPiiForm
validates_presence_of :address1, { message: proc {
I18n.t('doc_auth.errors.alerts.address_check')
} }
validates_length_of :state, { is: 2,
message: proc {
I18n.t('doc_auth.errors.general.no_liveness')
} }
validates :zipcode, format: {
with: /\A[0-9]{5}(?:-[0-9]{4})?\z/,
message: proc {
I18n.t('doc_auth.errors.general.no_liveness')
},
}
validates :jurisdiction, :state, inclusion: { in: Idp::Constants::STATE_AND_TERRITORY_CODES,
message: proc {
I18n.t('doc_auth.errors.general.no_liveness')
} }

validates :jurisdiction, inclusion: { in: Idp::Constants::STATE_AND_TERRITORY_CODES,
message: proc {
I18n.t('doc_auth.errors.general.no_liveness')
} }
validates_presence_of :state_id_number, { message: proc {
I18n.t('doc_auth.errors.general.no_liveness')
} }

attr_reader :first_name, :last_name, :dob, :address1, :state, :zipcode, :attention_with_barcode,
:jurisdiction
:jurisdiction, :state_id_number
alias_method :attention_with_barcode?, :attention_with_barcode

def initialize(pii:, attention_with_barcode: false)
Expand All @@ -36,6 +35,7 @@ def initialize(pii:, attention_with_barcode: false)
@state = pii[:state]
@zipcode = pii[:zipcode]
@jurisdiction = pii[:state_id_jurisdiction]
@state_id_number = pii[:state_id_number]
@attention_with_barcode = attention_with_barcode
end

Expand All @@ -54,7 +54,7 @@ def submit

def self.pii_like_keypaths
keypaths = [[:pii]]
attrs = %i[name dob dob_min_age address1 state zipcode jurisdiction]
attrs = %i[name dob dob_min_age address1 state zipcode jurisdiction state_id_number]
attrs.each do |k|
keypaths << [:errors, k]
keypaths << [:error_details, k]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import { useContext } from 'react';
import { PageHeading } from '@18f/identity-components';
import {
FormStepError,
FormStepsButton,
OnErrorCallback,
RegisterFieldCallback,
} from '@18f/identity-form-steps';
import { FormStepsButton } from '@18f/identity-form-steps';
import { Cancel } from '@18f/identity-verify-flow';
import { useI18n } from '@18f/identity-react-i18n';
import type { FormStepComponentProps } from '@18f/identity-form-steps';
import UnknownError from './unknown-error';
import TipList from './tip-list';
import DocumentSideAcuantCapture from './document-side-acuant-capture';
import DocumentCaptureNotReady from './document-capture-not-ready';
import { FeatureFlagContext } from '../context';
import DocumentCaptureAbandon from './document-capture-abandon';
import {
DocumentCaptureSubheaderOne,
SelfieCaptureWithHeader,
DocumentFrontAndBackCapture,
} from './documents-step';
import type { ReviewIssuesStepValue } from './review-issues-step';

interface DocumentCaptureReviewIssuesProps {
interface DocumentCaptureReviewIssuesProps
extends Omit<FormStepComponentProps<ReviewIssuesStepValue>, 'toPreviousStep'> {
isFailedDocType: boolean;
remainingAttempts: number;
captureHints: boolean;
registerField: RegisterFieldCallback;
value: { string: Blob | string | null | undefined } | {};
unknownFieldErrors: FormStepError<any>[];
errors: FormStepError<any>[];
onChange: (...args: any) => void;
onError: OnErrorCallback;
hasDismissed: boolean;
}

type DocumentSide = 'front' | 'back' | 'selfie';

function DocumentCaptureReviewIssues({
isFailedDocType,
remainingAttempts = Infinity,
Expand All @@ -39,21 +33,24 @@ function DocumentCaptureReviewIssues({
errors = [],
onChange = () => undefined,
onError = () => undefined,
value = {},
value,
hasDismissed,
}: DocumentCaptureReviewIssuesProps) {
const { t } = useI18n();
const { notReadySectionEnabled, exitQuestionSectionEnabled, selfieCaptureEnabled } =
useContext(FeatureFlagContext);

// Sides of document to present as file input.
const documentSides: DocumentSide[] = selfieCaptureEnabled
? ['front', 'back', 'selfie']
: ['front', 'back'];
const defaultSideProps = {
registerField,
onChange,
errors,
onError,
};

return (
<>
<PageHeading>{t('doc_auth.headings.review_issues')}</PageHeading>
<DocumentCaptureSubheaderOne selfieCaptureEnabled={selfieCaptureEnabled} />
<UnknownError
unknownFieldErrors={unknownFieldErrors}
remainingAttempts={remainingAttempts}
Expand All @@ -73,18 +70,10 @@ function DocumentCaptureReviewIssues({
]}
/>
)}
{documentSides.map((side) => (
<DocumentSideAcuantCapture
key={side}
side={side}
registerField={registerField}
value={value[side]}
onChange={onChange}
errors={errors}
onError={onError}
className="document-capture-review-issues-step__input"
/>
))}
<DocumentFrontAndBackCapture defaultSideProps={defaultSideProps} value={value} />
{selfieCaptureEnabled && (
<SelfieCaptureWithHeader defaultSideProps={defaultSideProps} selfieValue={value.selfie} />
)}
<FormStepsButton.Submit />
{notReadySectionEnabled && <DocumentCaptureNotReady />}
{exitQuestionSectionEnabled && <DocumentCaptureAbandon />}
Expand Down
Loading