-
Notifications
You must be signed in to change notification settings - Fork 116
/
session.rb
397 lines (333 loc) · 11.4 KB
/
session.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# frozen_string_literal: true
module Idv
# @attr address_edited [Boolean, nil]
# @attr address_verification_mechanism [String, nil]
# @attr applicant [Struct, nil]
# @attr document_capture_session_uuid [String, nil]
# @attr flow_path [String, nil]
# @attr go_back_path [String, nil]
# @attr gpo_code_verified [Boolean, nil]
# @attr had_barcode_attention_error [Boolean, nil]
# @attr had_barcode_read_failure [Boolean, nil]
# @attr idv_consent_given [Boolean, nil]
# @attr idv_consent_given_at [String, nil]
# @attr idv_phone_step_document_capture_session_uuid [String, nil]
# @attr mail_only_warning_shown [Boolean, nil]
# @attr opted_in_to_in_person_proofing [Boolean, nil]
# @attr personal_key [String, nil]
# @attr personal_key_acknowledged [Boolean, nil]
# @attr phone_for_mobile_flow [String, nil]
# @attr previous_phone_step_params [Array]
# @attr previous_ssn [String, nil]
# @attr profile_id [String, nil]
# @attr proofing_started_at [String, nil]
# @attr redo_document_capture [Boolean, nil]
# @attr residential_resolution_vendor [String, nil]
# @attr resolution_successful [Boolean, nil]
# @attr resolution_vendor [String,nil]
# @attr selfie_check_performed [Boolean, nil]
# @attr selfie_check_required [Boolean, nil]
# @attr skip_doc_auth_from_handoff [Boolean, nil]
# @attr skip_doc_auth_from_how_to_verify [Boolean, nil]
# @attr skip_hybrid_handoff [Boolean, nil]
# @attr source_check_vendor [String, nil]
# @attr ssn [String, nil]
# @attr threatmetrix_review_status [String, nil]
# @attr threatmetrix_session_id [String, nil]
# @attr user_phone_confirmation [Boolean, nil]
# @attr vendor_phone_confirmation [Boolean, nil]
# @attr verify_info_step_document_capture_session_uuid [String, nil]
# @attr welcome_visited [Boolean, nil]
# @attr_reader current_user [User]
# @attr_reader gpo_otp [String, nil]
# @attr_reader service_provider [ServiceProvider]
class Session
VALID_SESSION_ATTRIBUTES = %i[
address_edited
address_verification_mechanism
applicant
document_capture_session_uuid
flow_path
go_back_path
gpo_code_verified
had_barcode_attention_error
had_barcode_read_failure
idv_consent_given
idv_consent_given_at
idv_phone_step_document_capture_session_uuid
mail_only_warning_shown
opted_in_to_in_person_proofing
personal_key
personal_key_acknowledged
phone_for_mobile_flow
previous_phone_step_params
previous_ssn
profile_id
proofing_started_at
redo_document_capture
source_check_vendor
residential_resolution_vendor
resolution_successful
resolution_vendor
selfie_check_performed
selfie_check_required
skip_doc_auth_from_handoff
skip_doc_auth_from_how_to_verify
skip_hybrid_handoff
socure_docv_wait_polling_started_at
ssn
threatmetrix_review_status
threatmetrix_session_id
user_phone_confirmation
vendor_phone_confirmation
verify_info_step_document_capture_session_uuid
welcome_visited
].freeze
attr_reader :current_user, :gpo_otp, :service_provider
def initialize(user_session:, current_user:, service_provider:)
@user_session = user_session
@current_user = current_user
@service_provider = service_provider
set_idv_session
end
def method_missing(method_sym, *arguments, &block)
attr_name_sym = method_sym.to_s.delete_suffix('=').to_sym
if VALID_SESSION_ATTRIBUTES.include?(attr_name_sym)
return session[attr_name_sym] if arguments.empty?
session[attr_name_sym] = arguments.first
else
super
end
end
def respond_to_missing?(method_sym, include_private)
attr_name_sym = method_sym.to_s.delete_suffix('=').to_sym
VALID_SESSION_ATTRIBUTES.include?(attr_name_sym) || super
end
# @return [Profile]
def create_profile_from_applicant_with_password(
user_password, is_enhanced_ipp:, proofing_components:
)
if user_has_unscheduled_in_person_enrollment?
UspsInPersonProofing::EnrollmentHelper.schedule_in_person_enrollment(
user: current_user,
pii: Pii::Attributes.new_from_hash(applicant),
is_enhanced_ipp: is_enhanced_ipp,
opt_in: opt_in_param,
)
end
profile_maker = build_profile_maker(user_password)
profile = profile_maker.save_profile(
fraud_pending_reason: threatmetrix_fraud_pending_reason,
gpo_verification_needed: !phone_confirmed? || verify_by_mail?,
in_person_verification_needed: current_user.has_in_person_enrollment?,
selfie_check_performed: session[:selfie_check_performed],
proofing_components:,
)
profile.activate unless profile.reason_not_to_activate
self.profile_id = profile.id
self.personal_key = profile.personal_key
Pii::Cacher.new(current_user, user_session).save_decrypted_pii(
profile_maker.pii_attributes,
profile.id,
)
associate_in_person_enrollment_with_profile if profile.in_person_verification_pending?
if profile.gpo_verification_pending?
create_gpo_entry(profile_maker.pii_attributes, profile)
end
profile
end
def opt_in_param
opted_in_to_in_person_proofing unless !IdentityConfig.store.in_person_proofing_opt_in_enabled
end
def acknowledge_personal_key!
session.delete(:personal_key)
session[:personal_key_acknowledged] = true
end
def invalidate_personal_key!
session.delete(:personal_key)
session.delete(:personal_key_acknowledged)
end
def verify_by_mail?
address_verification_mechanism == 'gpo'
end
def vendor_params
applicant.merge('uuid' => current_user.uuid)
end
def profile_id=(value)
session[:profile_id] = value
@profile = nil
end
def profile
@profile ||= Profile.find_by(id: profile_id)
end
def clear
user_session.delete(:idv)
@profile = nil
@gpo_otp = nil
end
def associate_in_person_enrollment_with_profile
current_user.establishing_in_person_enrollment.update(profile: profile)
end
def create_gpo_entry(pii, profile)
begin
confirmation_maker = GpoConfirmationMaker.new(
pii: pii, service_provider: service_provider,
profile: profile
)
confirmation_maker.perform
@gpo_otp = confirmation_maker.otp
rescue
# We don't have what we need to actually generate a GPO letter.
profile.deactivate(:encryption_error)
raise
end
end
def phone_otp_sent?
vendor_phone_confirmation && address_verification_mechanism == 'phone'
end
def user_phone_confirmation_session
session_value = session[:user_phone_confirmation_session]
return if session_value.blank?
Idv::PhoneConfirmationSession.from_h(session_value)
end
def user_phone_confirmation_session=(new_user_phone_confirmation_session)
session[:user_phone_confirmation_session] = new_user_phone_confirmation_session.to_h
end
def failed_phone_step_numbers
session[:failed_phone_step_params] ||= []
end
def pii_from_doc=(new_pii_from_doc)
if new_pii_from_doc.blank?
session[:pii_from_doc] = nil
else
session[:pii_from_doc] = new_pii_from_doc.to_h
end
end
def pii_from_doc
return nil if session[:pii_from_doc].blank?
state_id_data = Pii::StateId.members.index_with { |key| session[:pii_from_doc][key] }
Pii::StateId.new(**state_id_data)
end
def updated_user_address=(updated_user_address)
if updated_user_address.blank?
session[:updated_user_address] = nil
else
session[:updated_user_address] = updated_user_address.to_h
end
end
def updated_user_address
return nil if session[:updated_user_address].blank?
Pii::Address.new(**session[:updated_user_address])
end
def add_failed_phone_step_number(phone)
parsed_phone = Phonelib.parse(phone)
phone_e164 = parsed_phone.e164
failed_phone_step_numbers << phone_e164 if !failed_phone_step_numbers.include?(phone_e164)
end
def proofing_workflow_time_in_seconds
Time.zone.now - Time.zone.parse(proofing_started_at) if proofing_started_at.present?
end
def pii_from_user_in_flow_session
user_session.dig('idv/in_person', :pii_from_user)
end
def has_pii_from_user_in_flow_session?
!!pii_from_user_in_flow_session
end
def invalidate_in_person_pii_from_user!
if has_pii_from_user_in_flow_session?
user_session['idv/in_person'][:pii_from_user] = nil
end
end
def remote_document_capture_complete?
pii_from_doc.present?
end
def ipp_document_capture_complete?
has_pii_from_user_in_flow_session? &&
user_session['idv/in_person'][:pii_from_user].has_key?(:address1)
end
def ipp_state_id_complete?
has_pii_from_user_in_flow_session? &&
user_session['idv/in_person'][:pii_from_user].has_key?(:identity_doc_address1)
end
def ssn_step_complete?
ssn.present?
end
def verify_info_step_complete?
resolution_successful
end
def phone_or_address_step_complete?
verify_by_mail? || phone_confirmed?
end
def address_mechanism_chosen?
vendor_phone_confirmation == true || verify_by_mail?
end
def phone_confirmed?
vendor_phone_confirmation == true && user_phone_confirmation == true
end
def address_confirmed?
gpo_code_verified == true
end
def address_confirmed!
session[:gpo_code_verified] = true
end
def mark_verify_info_step_complete!
session[:resolution_successful] = true
end
def invalidate_verify_info_step!
session[:resolution_successful] = nil
end
def mark_phone_step_started!
session[:address_verification_mechanism] = 'phone'
session[:vendor_phone_confirmation] = true
session[:user_phone_confirmation] = false
end
def mark_phone_step_complete!
session[:user_phone_confirmation] = true
end
def invalidate_phone_step!
session[:address_verification_mechanism] = nil
session[:vendor_phone_confirmation] = nil
session[:user_phone_confirmation] = nil
end
def skip_hybrid_handoff?
!!session[:skip_hybrid_handoff]
end
def desktop_selfie_test_mode_enabled?
IdentityConfig.store.doc_auth_selfie_desktop_test_mode
end
def idv_consent_given?
!!session[:idv_consent_given_at]
end
private
attr_reader :user_session
def set_idv_session
user_session[:idv] = new_idv_session unless user_session.key?(:idv)
end
def new_idv_session
{}
end
def session
user_session.fetch(:idv, {})
end
def build_profile_maker(user_password)
Idv::ProfileMaker.new(
applicant: applicant,
user: current_user,
user_password: user_password,
initiating_service_provider: service_provider,
)
end
def threatmetrix_fraud_pending_reason
return if !FeatureManagement.proofing_device_profiling_decisioning_enabled?
case threatmetrix_review_status
when 'reject'
'threatmetrix_reject'
when 'review'
'threatmetrix_review'
end
end
def user_has_unscheduled_in_person_enrollment?
current_user.has_establishing_in_person_enrollment?
end
end
end