Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a5a3e17
New GettingStartedController copied from WelcomeController
soniaconnolly Jul 14, 2023
1d36aad
Remove StepIndicator from GettingStartedController
soniaconnolly Jul 14, 2023
d06a4f1
Add GettingStartedAbTestConcern and before action in WelcomeController
soniaconnolly Jul 14, 2023
8b0d1dc
Specs for ABTest behavior
soniaconnolly Jul 14, 2023
8e72759
Add config flag and ABTestBucket.
soniaconnolly Jul 14, 2023
21020aa
Update getting_started_controller_spec and analytics
soniaconnolly Jul 14, 2023
ca77d16
Add agreement checkbox and specs
soniaconnolly Jul 14, 2023
35e5a83
Change the setup in getting_started_ab_test_concern_spec
soniaconnolly Jul 17, 2023
9ef7308
Remove unneeded components from Getting Started template and add feat…
soniaconnolly Jul 17, 2023
ed8f9f9
Add new translation keys
soniaconnolly Jul 17, 2023
394c55d
Add new translation text and page formatting
soniaconnolly Jul 17, 2023
c2e549b
Register both welcome and agreement steps in DocAuthLog
soniaconnolly Jul 17, 2023
06e5286
Lint
soniaconnolly Jul 17, 2023
a3b3289
Test agreement checkbox in getting started feature spec
soniaconnolly Jul 17, 2023
f5dc4ce
Remove unneeded locals when rendering show in WelcomeController
soniaconnolly Jul 17, 2023
05dd0ca
Add Agreement feature specs and make them pass
soniaconnolly Jul 17, 2023
bdf5e63
I18n lint
soniaconnolly Jul 18, 2023
6545ddb
Put parameters on own line, fix downcase of SP name
soniaconnolly Jul 18, 2023
b4bbe58
Merge remote-tracking branch 'origin/main' into sonia-lg-7355-new-get…
soniaconnolly Jul 18, 2023
9ef31de
Fix bad merge in analytics_events
soniaconnolly Jul 18, 2023
f42300f
Clean up Funnel::DocAuth::RegisterStep code layout
soniaconnolly Jul 18, 2023
72c9834
Replace no_sp_name with APP_NAME when there's no SP
soniaconnolly Jul 18, 2023
b44e98b
Fix capitalization of APP_NAME in Welcome show template
soniaconnolly Jul 18, 2023
f014e8b
Add show template spec and external_redirect analytics spec
soniaconnolly Jul 19, 2023
b20e2b8
Update spec to match analytics arg change
soniaconnolly Jul 19, 2023
5fc58f2
Change A/B test buckets to :welcome and :getting_started instead of :…
soniaconnolly Jul 19, 2023
2d23223
Use FakeABTestBucket to avoid any_instance stub
soniaconnolly Jul 19, 2023
0fbec4d
Merge remote-tracking branch 'origin/main' into sonia-lg-7355-new-get…
soniaconnolly Jul 19, 2023
d1a4723
Only redirect if bucket is :getting_started, stay on Welcome for all …
soniaconnolly Jul 19, 2023
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
13 changes: 13 additions & 0 deletions app/controllers/concerns/idv/getting_started_ab_test_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Idv
module GettingStartedAbTestConcern
def getting_started_a_b_test_bucket
AbTests::IDV_GETTING_STARTED.bucket(sp_session[:request_id] || session.id)
end

def maybe_redirect_for_getting_started_ab_test
return if getting_started_a_b_test_bucket != :getting_started

redirect_to idv_getting_started_url
end
end
end
84 changes: 84 additions & 0 deletions app/controllers/idv/getting_started_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module Idv
class GettingStartedController < ApplicationController
include IdvStepConcern
include StepUtilitiesConcern

before_action :confirm_agreement_needed

def show
analytics.idv_doc_auth_getting_started_visited(**analytics_arguments)

# Register both Welcome and Agreement steps in DocAuthLog
Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).
call('welcome', :view, true)
Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).
call('agreement', :view, true)

@sp_name = decorated_session.sp_name || APP_NAME
@title = t('doc_auth.headings.getting_started', sp_name: @sp_name)

render :show, locals: { flow_session: flow_session }
end

def update
flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow?
skip_to_capture if params[:skip_upload]

result = Idv::ConsentForm.new.submit(consent_form_params)

analytics.idv_doc_auth_getting_started_submitted(
**analytics_arguments.merge(result.to_h),
)

if result.success?
idv_session.idv_consent_given = true

create_document_capture_session
cancel_previous_in_person_enrollments

redirect_to idv_hybrid_handoff_url
else
redirect_to idv_getting_started_url
end
end

private

def analytics_arguments
{
step: 'getting_started',
analytics_id: 'Doc Auth',
irs_reproofing: irs_reproofing?,
}
end

def create_document_capture_session
document_capture_session = DocumentCaptureSession.create(
user_id: current_user.id,
issuer: sp_session[:issuer],
)
flow_session[:document_capture_session_uuid] = document_capture_session.uuid
end

def cancel_previous_in_person_enrollments
return unless IdentityConfig.store.in_person_proofing_enabled
UspsInPersonProofing::EnrollmentHelper.
cancel_stale_establishing_enrollments_for_user(current_user)
end

def skip_to_capture
flow_session[:skip_upload_step] = true
idv_session.flow_path = 'standard'
end

def consent_form_params
params.require(:doc_auth).permit(:ial2_consent_given)
end

def confirm_agreement_needed
return unless idv_session.idv_consent_given

redirect_to idv_hybrid_handoff_url
end
end
end
10 changes: 5 additions & 5 deletions app/controllers/idv/welcome_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ class WelcomeController < ApplicationController
include IdvStepConcern
include StepIndicatorConcern
include StepUtilitiesConcern
include GettingStartedAbTestConcern

before_action :confirm_welcome_needed
before_action :maybe_redirect_for_getting_started_ab_test

def show
analytics.idv_doc_auth_welcome_visited(**analytics_arguments)

Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call(
'welcome', :view,
true
)
Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).
call('welcome', :view, true)

render :show, locals: { flow_session: flow_session }
render :show
end

def update
Expand Down
9 changes: 8 additions & 1 deletion app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,17 @@ def idv_doc_auth_exception_visited(step_name:, remaining_attempts:, **extra)
)
end

def idv_doc_auth_getting_started_submitted(**extra)
track_event('IdV: doc auth getting_started submitted', **extra)
end

def idv_doc_auth_getting_started_visited(**extra)
track_event('IdV: doc auth getting_started visited', **extra)
end

# The "hybrid handoff" step: Desktop user has submitted their choice to
# either continue via desktop ("document_capture" destination) or switch
# to mobile phone ("send_link" destination) to perform document upload.
# Mobile users still log this event but with skip_upload_step = true
# @identity.idp.previous_event_name IdV: doc auth upload submitted
def idv_doc_auth_hybrid_handoff_submitted(**extra)
track_event('IdV: doc auth hybrid handoff submitted', **extra)
Expand Down
1 change: 1 addition & 0 deletions app/services/marketing_site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class MarketingSite
verify-your-identity/verify-your-identity-in-person
verify-your-identity/phone-number
verify-your-identity/verify-your-address-by-mail
verify-your-identity/how-to-verify-your-identity
].to_set.freeze

def self.locale_segment
Expand Down
100 changes: 100 additions & 0 deletions app/views/idv/getting_started/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<% title @title %>

<%= render 'shared/maintenance_window_alert' do %>
<%= render JavascriptRequiredComponent.new(
header: t('idv.getting_started.no_js_header'),
intro: t('idv.getting_started.no_js_intro', sp_name: @sp_name),
) do %>

<% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %>
<%= render AlertComponent.new(
type: :info,
message: t('doc_auth.info.irs_reproofing_explanation'),
class: ['margin-bottom-2', 'usa-alert--info-important'],
)
%>
<% end %>

<%= render AlertComponent.new(
type: :error,
class: [
'js-consent-form-alert',
'margin-bottom-4',
flow_session[:error_message].blank? && 'display-none',
].select(&:present?),
message: flow_session[:error_message].presence || t('errors.doc_auth.consent_form'),
) %>

<%= render PageHeadingComponent.new.with_content(@title) %>
<p>
<%= t(
'doc_auth.info.getting_started_html',
sp_name: @sp_name,
link_html: new_tab_link_to(
t('doc_auth.info.getting_started_learn_more'),
help_center_redirect_path(
category: 'verify-your-identity',
article: 'how-to-verify-your-identity',
flow: :idv,
step: :getting_started,
location: 'intro_paragraph',
),
),
) %>
</p>

<h2><%= t('doc_auth.getting_started.instructions.getting_started') %></h2>

<%= render ProcessListComponent.new(heading_level: :h3, class: 'margin-y-3') do |c| %>
<%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet1')) do %>
<p><%= t('doc_auth.getting_started.instructions.text1') %></p>
<% end %>
<%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet2')) do %>
<p><%= t('doc_auth.getting_started.instructions.text2') %></p>
<% end %>
<%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet3')) do %>
<p><%= t('doc_auth.getting_started.instructions.text3') %></p>
<% end %>
<%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet4', app_name: APP_NAME)) do %>
<p><%= t('doc_auth.getting_started.instructions.text4') %></p>
<% end %>
<% end %>

<%= simple_form_for(
:doc_auth,
url: url_for,
method: 'put',
html: { autocomplete: 'off', class: 'margin-top-2 margin-bottom-5 js-consent-continue-form' },
) do |f| %>
<%= render ClickObserverComponent.new(event_name: 'IdV: consent checkbox toggled') do %>
<%= render ValidatedFieldComponent.new(
form: f,
name: :ial2_consent_given,
as: :boolean,
label: t('doc_auth.getting_started.instructions.consent', app_name: APP_NAME),
required: true,
) %>
<% end %>
<p class="margin-top-2">
<%= new_tab_link_to(
t('doc_auth.getting_started.instructions.learn_more'),
policy_redirect_url(flow: :idv, step: :getting_started, location: :consent),
) %>
</p>
<div class="margin-top-4">
<%= render(
SpinnerButtonComponent.new(
type: :submit,
big: true,
wide: true,
spin_on_click: false,
).with_content(t('doc_auth.buttons.continue')),
) %>
</div>
<% end %>

<%= render 'shared/cancel', link: idv_cancel_path(step: 'getting_started') %>
<% end %>
<% end %>

<%= javascript_packs_tag_once('document-capture-welcome') %>
4 changes: 2 additions & 2 deletions app/views/idv/welcome/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<%= render 'shared/maintenance_window_alert' do %>
<%= render JavascriptRequiredComponent.new(
header: t('idv.welcome.no_js_header'),
intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')),
intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || APP_NAME),
) do %>

<% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %>
Expand All @@ -26,7 +26,7 @@

<%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.welcome')) %>
<p>
<%= t('doc_auth.info.welcome', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')) %>
<%= t('doc_auth.info.welcome', sp_name: decorated_session.sp_name || APP_NAME) %>
</p>

<h2><%= t('doc_auth.instructions.welcome') %></h2>
Expand Down
1 change: 1 addition & 0 deletions config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ idv_acuant_sdk_version_default: '11.8.2'
idv_acuant_sdk_version_alternate: '11.8.1'
idv_acuant_sdk_upgrade_a_b_testing_enabled: false
idv_acuant_sdk_upgrade_a_b_testing_percent: 50
idv_getting_started_a_b_testing: '{"welcome":100,"getting_started":0}'
idv_send_link_attempt_window_in_minutes: 10
idv_send_link_max_attempts: 5
idv_tmx_test_csp_disabled_emails: '[]'
Expand Down
5 changes: 5 additions & 0 deletions config/initializers/ab_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ module AbTests
0,
},
)

IDV_GETTING_STARTED = AbTestBucket.new(
experiment_name: 'Idv: Getting Started Experience',
buckets: IdentityConfig.store.idv_getting_started_a_b_testing,
)
end
22 changes: 21 additions & 1 deletion config/locales/doc_auth/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,23 @@ en:
choose_file_html: Drag file here or <lg-underline>choose from folder</lg-underline>
doc_success: We verified your information
selected_file: Selected file
getting_started:
instructions:
bullet1: Add photos of your ID
bullet2: Enter your Social Security number
bullet3: Match to your phone number
bullet4: Re-enter your %{app_name} password
consent: By checking this box, you are letting %{app_name} ask for, use, keep,
and share your personal information. We will use it to verify your
identity.
getting_started: 'You’ll need to:'
learn_more: Learn more about our privacy and security measures
text1: Use your driver’s license or state ID card. Other forms of ID are not
accepted.
text2: You will not need your physical SSN card.
text3: Your phone number matches you to your personal information. After you
match, we’ll send you a code.
text4: Your password saves and encrypts your personal information.
headings:
address: Update your mailing address
back: Back
Expand All @@ -113,6 +130,7 @@ en:
document_capture_back: Back of your ID
document_capture_front: Front of your ID
front: Front
getting_started: Let’s verify your identity for %{sp_name}
hybrid_handoff: How would you like to add your ID?
interstitial: We are processing your images
lets_go: How verifying your identity works
Expand Down Expand Up @@ -146,6 +164,9 @@ en:
document_capture_intro_acknowledgment: We’ll collect information about you by
reading your state‑issued ID. We use this information to verify your
identity.
getting_started_html: '%{sp_name} needs to make sure you are you — not someone
pretending to be you. %{link_html}'
getting_started_learn_more: Learn more about what you need to verify your identity
hybrid_handoff: We’ll collect information about you by reading your state‑issued ID.
image_loaded: Image loaded
image_loading: Image loading
Expand All @@ -161,7 +182,6 @@ en:
your state‑issued ID.
link_sent_complete_no_polling: When you are done, click Continue here to finish verifying your identity.
link_sent_complete_polling: The next step will load automatically.
no_sp_name: The agency that you are trying to access
privacy: '%{app_name} is a secure, government website that adheres to the
highest standards in data protection. We use your data to verify your
identity.'
Expand Down
22 changes: 21 additions & 1 deletion config/locales/doc_auth/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,23 @@ es:
carpeta</lg-underline>
doc_success: Verificamos sus datos
selected_file: Archivo seleccionado
getting_started:
instructions:
bullet1: Incluir fotos de su identificación
bullet2: Introducir su número de Seguro Social
bullet3: Vincular su número de teléfono
bullet4: Volver a introducir su contraseña de %{app_name}
consent: Al marcar esta casilla, usted permite que %{app_name} solicite,
utilice, conserve y comparta su información personal. Los utilizamos
para verificar su identidad.
getting_started: 'Deberá:'
learn_more: Obtenga más información sobre nuestras medidas de privacidad y
seguridad
text1: Su documento de identidad no puede estar caducado.
text2: No necesitará la tarjeta con usted.
text3: Su número de teléfono se asocia a su información personal. Después de que
lo haya asociado, le enviaremos un código.
text4: Su contraseña guarda y encripta su información personal.
headings:
address: Actualice su dirección postal
back: Parte Trasera
Expand All @@ -138,6 +155,7 @@ es:
document_capture_back: Parte trasera de su documento de identidad
document_capture_front: Parte delantera de su documento de identidad
front: Parte Delantera
getting_started: Vamos a verificar su identidad para %{sp_name}
hybrid_handoff: '¿Cómo desea añadir su documento de identidad?'
interstitial: Estamos procesando sus imágenes
lets_go: Cómo funciona la verificación de su identidad
Expand Down Expand Up @@ -174,6 +192,9 @@ es:
document_capture_intro_acknowledgment: Recopilaremos información sobre usted
leyendo su documento de identidad expedido por el Estado. Usamos esta
información para verificar su identidad.
getting_started_html: '%{sp_name} necesita asegurarse de que es usted realmente
y no alguien que se hace pasar por usted. %{link_html}'
getting_started_learn_more: Obtenga más información sobre lo que necesita para verificar su identidad
hybrid_handoff: Recopilaremos información sobre usted leyendo su documento de
identidad expedido por el estado.
image_loaded: Imagen cargada
Expand All @@ -193,7 +214,6 @@ es:
completar la verificación de tu identidad.
link_sent_complete_polling: El siguiente paso se cargará automáticamente una vez
que verifiques tu identidad a través de tu teléfono.
no_sp_name: La agencia a la que está intentando acceder
privacy: '%{app_name} es un sitio web gubernamental seguro que cumple con las
normas más estrictas de protección de datos. Utilizamos sus datos para
verificar su identidad.'
Expand Down
Loading