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
49 changes: 49 additions & 0 deletions app/controllers/idv/by_mail/sp_follow_up_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module Idv
module ByMail
class SpFollowUpController < ApplicationController
include Idv::AvailabilityConcern

before_action :confirm_two_factor_authenticated
before_action :confirm_needs_sp_follow_up

def new
analytics.track_event(:idv_by_mail_sp_follow_up_visited, **analytics_params)
@presenter = Idv::ByMail::SpFollowUpPresenter.new(current_user:)
end

def show
analytics.track_event(:idv_by_mail_sp_follow_up_submitted, **analytics_params)

sp_return_url_resolver = SpReturnUrlResolver.new(
service_provider: current_user.active_profile.initiating_service_provider,
)
redirect_url = sp_return_url_resolver.post_idv_follow_up_url ||
sp_return_url_resolver.return_to_sp_url
redirect_to(redirect_url, allow_other_host: true)
end

def cancel
analytics.track_event(:idv_by_mail_sp_follow_up_cancelled, **analytics_params)
redirect_to account_url
end

private

def analytics_params
initiating_service_provider = current_user.active_profile.initiating_service_provider
{
initiating_service_provider: initiating_service_provider.issuer,
}
end

def confirm_needs_sp_follow_up
return if current_user.identity_verified? &&
current_user.active_profile.initiating_service_provider.present? &&
!current_sp.present?
redirect_to account_url
end
end
end
end
2 changes: 2 additions & 0 deletions app/controllers/idv/personal_key_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def next_step
idv_please_call_url
elsif session[:sp]
sign_up_completed_url
elsif idv_session.address_verification_mechanism == 'gpo'
idv_sp_follow_up_path
else
after_sign_in_path_for(current_user)
end
Expand Down
40 changes: 40 additions & 0 deletions app/presenters/idv/by_mail/sp_follow_up_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

module Idv
module ByMail
class SpFollowUpPresenter
include ActionView::Helpers::TranslationHelper

attr_reader :current_user

def initialize(current_user:)
@current_user = current_user
end

def heading
t(
'idv.by_mail.sp_follow_up.heading',
service_provider: initiating_service_provider_name,
)
end

def body
t(
'idv.by_mail.sp_follow_up.body',
service_provider: initiating_service_provider_name,
app_name: APP_NAME,
)
end

private

def initiating_service_provider_name
initiating_service_provider.friendly_name
end

def initiating_service_provider
@initiating_service_provider ||= current_user.active_profile.initiating_service_provider
end
end
end
end
47 changes: 47 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -820,15 +820,32 @@ def gpo_confirmation_upload(
# User visited sign-in URL from the "You've been successfully verified email" CTA button
# @param issuer [String] the ServiceProvider.issuer
# @param campaign_id [String] the email campaign ID
# @param [Hash,nil] proofing_components User's current proofing components
# @option proofing_components [String,nil] 'document_check' Vendor that verified the user's ID
# @option proofing_components [String,nil] 'document_type' Type of ID used to verify
# @option proofing_components [String,nil] 'source_check' Source used to verify user's PII
# @option proofing_components [String,nil] 'resolution_check' Vendor for identity resolution check
# @option proofing_components [String,nil] 'address_check' Method used to verify user's address
# @option proofing_components [Boolean,nil] 'threatmetrix' Whether ThreatMetrix check was done
# @option proofing_components [String,nil] 'threatmetrix_review_status' TMX decision on the user
# @param [String,nil] active_profile_idv_level ID verification level of user's active profile.
# @param [String,nil] pending_profile_idv_level ID verification level of user's pending profile.
def idv_account_verified_cta_visited(
issuer:,
campaign_id:,
proofing_components: nil,
active_profile_idv_level: nil,
pending_profile_idv_level: nil,
Comment on lines 836 to 838
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are these being passed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These need to be documented since they are added by AnalyticsEventsEnhancer. Otherwise the feature tests get cranky about undocumented params.

**extra
)
track_event(
:idv_account_verified_cta_visited,
issuer:,
campaign_id:,
proofing_components:,
active_profile_idv_level:,
pending_profile_idv_level:,

**extra,
)
end
Expand Down Expand Up @@ -1032,6 +1049,36 @@ def idv_barcode_warning_retake_photos_clicked(liveness_checking_required:, **ext
)
end

# @param [String] initiating_service_provider The service provider the user needs to connect to
# The user chose not to connect their account from the SP follow-up page
def idv_by_mail_sp_follow_up_cancelled(initiating_service_provider:, **extra)
track_event(
:idv_by_mail_sp_follow_up_cancelled,
initiating_service_provider:,
**extra,
)
end

# @param [String] initiating_service_provider The service provider the user needs to connect to
# The user chose to connect their account from the SP follow-up page
def idv_by_mail_sp_follow_up_submitted(initiating_service_provider:, **extra)
track_event(
:idv_by_mail_sp_follow_up_submitted,
initiating_service_provider:,
**extra,
)
end

# @param [String] initiating_service_provider The service provider the user needs to connect to
# The user visited the SP follow-up page
def idv_by_mail_sp_follow_up_visited(initiating_service_provider:, **extra)
track_event(
:idv_by_mail_sp_follow_up_visited,
initiating_service_provider:,
**extra,
)
end

# @param [Hash] error
def idv_camera_info_error(error:, **_extra)
track_event(:idv_camera_info_error, error: error)
Expand Down
24 changes: 24 additions & 0 deletions app/views/idv/by_mail/sp_follow_up/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<% self.title = @presenter.heading %>

<div class="text-center">
<%= image_tag(asset_url('user-access.svg'), width: '280', height: '91', alt: '', aria: { hidden: true }) %>
<h1 class="margin-bottom-4"><%= @presenter.heading %></h1>
</div>

<p><%= @presenter.body %></p>

<div class='margin-top-5 margin-bottom-2'>
<%= render ButtonComponent.new(
url: idv_sp_follow_up_connect_path,
big: true,
wide: true,
).with_content(t('idv.by_mail.sp_follow_up.connect_account')) %>
</div>
<div>
<%= render ButtonComponent.new(
url: idv_sp_follow_up_cancel_path,
big: true,
wide: true,
outline: true,
).with_content(t('idv.by_mail.sp_follow_up.go_to_account')) %>
</div>
4 changes: 4 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,10 @@ idv.buttons.change_ssn_label: Update Social Security number
idv.buttons.change_state_id_label: Update state ID
idv.buttons.continue_plain: Continue
idv.buttons.mail.send: Request a letter
idv.by_mail.sp_follow_up.body: Sign back in to %{service_provider} to connect your verified %{app_name} account and access services.
idv.by_mail.sp_follow_up.connect_account: Connect your account
idv.by_mail.sp_follow_up.go_to_account: Go to account
idv.by_mail.sp_follow_up.heading: Connect to %{service_provider}
idv.cancel.actions.account_page: Go to account page
idv.cancel.actions.exit: Exit %{app_name}
idv.cancel.actions.keep_going: No, keep going
Expand Down
4 changes: 4 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,10 @@ idv.buttons.change_ssn_label: Actualizar número de Seguro Social
idv.buttons.change_state_id_label: Actualizar identificación estatal
idv.buttons.continue_plain: Continuar
idv.buttons.mail.send: Solicitar una carta
idv.by_mail.sp_follow_up.body: Vuelva a iniciar sesión en %{service_provider} para conectar su cuenta verificada de %{app_name} y acceder a los servicios.
idv.by_mail.sp_follow_up.connect_account: Conecte su cuenta
idv.by_mail.sp_follow_up.go_to_account: Ir a la cuenta
idv.by_mail.sp_follow_up.heading: Conéctese a %{service_provider}
idv.cancel.actions.account_page: Ir a la página de la cuenta
idv.cancel.actions.exit: Salir de %{app_name}
idv.cancel.actions.keep_going: No, continuar
Expand Down
4 changes: 4 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,10 @@ idv.buttons.change_ssn_label: Mettre à jour votre numéro de sécurité sociale
idv.buttons.change_state_id_label: Mettre à jour votre pièce d’identité
idv.buttons.continue_plain: Suite
idv.buttons.mail.send: Demander une lettre
idv.by_mail.sp_follow_up.body: Connectez-vous à nouveau à %{service_provider} pour y associer votre compte %{app_name} vérifié et accéder aux services de cet organisme.
idv.by_mail.sp_follow_up.connect_account: Associer votre compte
idv.by_mail.sp_follow_up.go_to_account: Aller sur le compte
idv.by_mail.sp_follow_up.heading: Vous connecter à %{service_provider}
idv.cancel.actions.account_page: Aller à la page de votre compte
idv.cancel.actions.exit: Quitter %{app_name}
idv.cancel.actions.keep_going: Non, continuer
Expand Down
4 changes: 4 additions & 0 deletions config/locales/zh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,10 @@ idv.buttons.change_ssn_label: 更新社会保障号码
idv.buttons.change_state_id_label: 更新州颁发的身份证件
idv.buttons.continue_plain: 继续
idv.buttons.mail.send: 要求发一封信
idv.by_mail.sp_follow_up.body: 重新登录 %{service_provider}以连接你验证过的%{app_name}账户并获得服务。
idv.by_mail.sp_follow_up.connect_account: 连接你的账户
idv.by_mail.sp_follow_up.go_to_account: 前往账户
idv.by_mail.sp_follow_up.heading: 连接 %{service_provider}
idv.cancel.actions.account_page: 到账户页面
idv.cancel.actions.exit: 退出 %{app_name}
idv.cancel.actions.keep_going: 不是,继续
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,9 @@
end

get '/by_mail/letter_enqueued' => 'by_mail/letter_enqueued#show', as: :letter_enqueued
get '/by_mail/sp_follow_up' => 'by_mail/sp_follow_up#new', as: :sp_follow_up
get '/by_mail/sp_follow_up/connect' => 'by_mail/sp_follow_up#show', as: :sp_follow_up_connect
get '/by_mail/sp_follow_up/cancel' => 'by_mail/sp_follow_up#cancel', as: :sp_follow_up_cancel

# We re-mapped `/verify/by_mail` to `/verify/by_mail/enter_code`. However, we sent emails to
# users with a link to `/verify/by_mail?did_not_receive_letter=1`. We need to continue
Expand Down
83 changes: 83 additions & 0 deletions spec/controllers/idv/by_mail/sp_follow_up_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require 'rails_helper'

RSpec.describe Idv::ByMail::SpFollowUpController do
let(:post_idv_follow_up_url) { 'https://example.com/follow_up' }
let(:initiating_service_provider) { create(:service_provider, post_idv_follow_up_url:) }
let(:user) { create(:user, :fully_registered) }
let!(:profile) { create(:profile, :active, user:, initiating_service_provider:) }

before do
stub_sign_in(user) if user.present?
stub_analytics
end

describe '#new' do
context 'the user has not finished verification' do
let(:profile) do
create(:profile, :verify_by_mail_pending, user:, initiating_service_provider:)
end

it 'redirects to the account page' do
get :new

expect(response).to redirect_to(account_url)
end
end

context 'the user has an SP in the session' do
before do
allow(controller).to receive(:current_sp).and_return(initiating_service_provider)
end

it 'redirects to the account page' do
get :new

expect(response).to redirect_to(account_url)
end
end

context 'the user does not have an initiating service provider' do
let(:profile) { create(:profile, :active, user:, initiating_service_provider: nil) }

it 'redirects to the account page' do
get :new

expect(response).to redirect_to(account_url)
end
end

it 'logs analytics and renders the template' do
get :new

expect(response).to render_template(:new)
expect(@analytics).to have_logged_event(
:idv_by_mail_sp_follow_up_visited,
initiating_service_provider: initiating_service_provider.issuer,
)
end
end

describe '#show' do
it 'logs analytics and redirects to the service provider' do
get :show

expect(response).to redirect_to(post_idv_follow_up_url)
expect(@analytics).to have_logged_event(
:idv_by_mail_sp_follow_up_submitted,
initiating_service_provider: initiating_service_provider.issuer,
)
end
end

describe '#cancel' do
it 'logs analytics and redirects to the account URL' do
get :cancel

expect(response).to redirect_to(account_url)
expect(@analytics).to have_logged_event(
:idv_by_mail_sp_follow_up_cancelled,
initiating_service_provider: initiating_service_provider.issuer,
)
end
end
end
41 changes: 35 additions & 6 deletions spec/controllers/idv/personal_key_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -483,14 +483,43 @@ def assert_personal_key_generated_for_profiles(*profile_pii_pairs)
context 'user selected gpo verification' do
let(:address_verification_mechanism) { 'gpo' }

it 'redirects to correct url' do
patch :update
expect(response).to redirect_to idv_letter_enqueued_url
context 'when the user requested a letter this session' do
it 'redirects to correct url' do
patch :update
expect(response).to redirect_to idv_letter_enqueued_url
end

it 'does not log any events' do
expect(@analytics).not_to have_logged_event
patch :update
end
end

it 'does not log any events' do
expect(@analytics).not_to have_logged_event
patch :update
context 'when the user entered a GPO code' do
before do
pending_profile = user.pending_profile
pending_profile.remove_gpo_deactivation_reason
pending_profile.activate
end

it 'redirects to correct url' do
patch :update
expect(response).to redirect_to idv_sp_follow_up_url
end

it 'logs analytics' do
patch :update

expect(@analytics).to have_logged_event(
'IdV: personal key submitted',
hash_including(
address_verification_method: 'gpo',
fraud_review_pending: false,
fraud_rejection: false,
in_person_verification_pending: false,
),
)
end
end
end

Expand Down
Loading