diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 14ece152c6a..dd8fe4a973c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -227,9 +227,9 @@ def after_sign_in_path_for(_user) return user_please_call_url if current_user.suspended? return user_password_compromised_url if session[:redirect_to_password_compromised].present? return authentication_methods_setup_url if user_needs_sp_auth_method_setup? - return login_add_piv_cac_prompt_url if session[:needs_to_setup_piv_cac_after_sign_in].present? return fix_broken_personal_key_url if current_user.broken_personal_key? return user_session.delete(:stored_location) if user_session.key?(:stored_location) + return login_add_piv_cac_prompt_url if session[:needs_to_setup_piv_cac_after_sign_in].present? return reactivate_account_url if user_needs_to_reactivate_account? return login_piv_cac_recommended_path if user_recommended_for_piv_cac? return second_mfa_reminder_url if user_needs_second_mfa_reminder? diff --git a/app/controllers/idv/in_person/usps_locations_controller.rb b/app/controllers/idv/in_person/usps_locations_controller.rb index 45cac7ac484..e6783b92210 100644 --- a/app/controllers/idv/in_person/usps_locations_controller.rb +++ b/app/controllers/idv/in_person/usps_locations_controller.rb @@ -46,7 +46,9 @@ def update enrollment.update!( selected_location_details: update_params.as_json, issuer: current_sp&.issuer, + doc_auth_result: document_capture_session&.last_doc_auth_result, ) + add_proofing_component render json: { success: true }, status: :ok @@ -54,6 +56,24 @@ def update private + def idv_session + if user_session && current_user + @idv_session ||= Idv::Session.new( + user_session: user_session, + current_user: current_user, + service_provider: current_sp, + ) + end + end + + def document_capture_session + if idv_session&.document_capture_session_uuid # standard flow + DocumentCaptureSession.find_by(uuid: idv_session.document_capture_session_uuid) + else # hybrid flow + super + end + end + def proofer @proofer ||= EnrollmentHelper.usps_proofer end diff --git a/app/controllers/sign_up/completions_controller.rb b/app/controllers/sign_up/completions_controller.rb index f665f0d85fc..1107fa56309 100644 --- a/app/controllers/sign_up/completions_controller.rb +++ b/app/controllers/sign_up/completions_controller.rb @@ -89,6 +89,11 @@ def analytics_attributes(page_occurence) needs_completion_screen_reason: needs_completion_screen_reason, } + if (last_enrollment = current_user.in_person_enrollments.last) + attributes[:in_person_proofing_status] = last_enrollment.status + attributes[:doc_auth_result] = last_enrollment.doc_auth_result + end + if page_occurence.present? && DisposableEmailDomain.disposable?(email_domain) attributes[:disposable_email_domain] = email_domain end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index 159e784baf2..d8a1df59251 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -72,7 +72,7 @@ def increment_session_bad_password_count end def process_locked_out_session - warden.logout(:user) + sign_out(:user) warden.lock! flash[:error] = t( @@ -100,7 +100,7 @@ def valid_captcha_result? def process_failed_captcha flash[:error] = t('errors.messages.invalid_recaptcha_token') - warden.logout(:user) + sign_out(:user) warden.lock! redirect_to root_url end @@ -176,6 +176,7 @@ def track_authentication_attempt(email) bad_password_count: session[:bad_password_count].to_i, sp_request_url_present: sp_session[:request_url].present?, remember_device: remember_device_cookie.present?, + new_device: success ? new_device? : nil, ) end diff --git a/app/forms/idv/api_image_upload_form.rb b/app/forms/idv/api_image_upload_form.rb index 6eca89aa4a3..da4dffc4ca9 100644 --- a/app/forms/idv/api_image_upload_form.rb +++ b/app/forms/idv/api_image_upload_form.rb @@ -38,6 +38,10 @@ def submit if form_response.success? client_response = post_images_to_client + document_capture_session.update!( + last_doc_auth_result: client_response.extra[:doc_auth_result], + ) + if client_response.success? doc_pii_response = validate_pii_from_doc(client_response) end diff --git a/app/forms/openid_connect_token_form.rb b/app/forms/openid_connect_token_form.rb index 404887ba55e..3ae404bc13b 100644 --- a/app/forms/openid_connect_token_form.rb +++ b/app/forms/openid_connect_token_form.rb @@ -5,7 +5,7 @@ class OpenidConnectTokenForm include ActionView::Helpers::TranslationHelper include Rails.application.routes.url_helpers - ISSUED_AT_LEEWAY_SECONDS = 10.seconds.to_i.freeze + ISSUED_AT_LEEWAY_SECONDS = 10 ATTRS = %i[ client_assertion diff --git a/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.spec.tsx b/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.spec.tsx index 8baea2980f6..b6c69a08518 100644 --- a/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.spec.tsx +++ b/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.spec.tsx @@ -49,7 +49,7 @@ describe('DocumentCaptureTroubleshootingOptions', () => { 'idv.troubleshooting.options.supported_documentslinks.new_tab', ); expect(links[1].getAttribute('href')).to.equal( - 'https://example.com/redirect/?category=verify-your-identity&article=accepted-state-issued-identification&location=document_capture_troubleshooting_options', + 'https://example.com/redirect/?category=verify-your-identity&article=accepted-identification-documents&location=document_capture_troubleshooting_options', ); expect(links[1].target).to.equal('_blank'); }); diff --git a/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx b/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx index b5bbba9f5aa..9e7530d009a 100644 --- a/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx +++ b/app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx @@ -57,7 +57,7 @@ function DocumentCaptureTroubleshootingOptions({ showDocumentTips && { url: getHelpCenterURL({ category: 'verify-your-identity', - article: 'accepted-state-issued-identification', + article: 'accepted-identification-documents', location, }), text: t('idv.troubleshooting.options.supported_documents'), diff --git a/app/javascript/packages/document-capture/components/document-capture.tsx b/app/javascript/packages/document-capture/components/document-capture.tsx index a7e3d062886..afbacbc27d6 100644 --- a/app/javascript/packages/document-capture/components/document-capture.tsx +++ b/app/javascript/packages/document-capture/components/document-capture.tsx @@ -39,14 +39,59 @@ function DocumentCapture({ onStepChange = () => {} }: DocumentCaptureProps) { const { trackSubmitEvent, trackVisitEvent } = useContext(AnalyticsContext); const { inPersonFullAddressEntryEnabled, inPersonURL, skipDocAuth, skipDocAuthFromHandoff } = useContext(InPersonContext); - const appName = getConfigValue('appName'); - useDidUpdateEffect(onStepChange, [stepName]); useEffect(() => { if (stepName) { trackVisitEvent(stepName); } }, [stepName]); + const appName = getConfigValue('appName'); + const inPersonLocationPostOfficeSearchForm = inPersonFullAddressEntryEnabled + ? InPersonLocationFullAddressEntryPostOfficeSearchStep + : InPersonLocationPostOfficeSearchStep; + + // Define different states to be used in human readable array declaration + const documentFormStep: FormStep = { + name: 'documents', + form: DocumentsStep, + title: t('doc_auth.headings.document_capture'), + }; + const reviewFormStep: FormStep = { + name: 'review', + form: + submissionError instanceof UploadFormEntriesError + ? withProps({ + remainingSubmitAttempts: submissionError.remainingSubmitAttempts, + isResultCodeInvalid: submissionError.isResultCodeInvalid, + isFailedResult: submissionError.isFailedResult, + isFailedDocType: submissionError.isFailedDocType, + isFailedSelfie: submissionError.isFailedSelfie, + isFailedSelfieLivenessOrQuality: + submissionError.selfieNotLive || submissionError.selfieNotGoodQuality, + captureHints: submissionError.hints, + pii: submissionError.pii, + failedImageFingerprints: submissionError.failed_image_fingerprints, + })(ReviewIssuesStep) + : ReviewIssuesStep, + title: t('doc_auth.errors.rate_limited_heading'), + }; + + // In Person Steps + const prepareFormStep: FormStep = { + name: 'prepare', + form: InPersonPrepareStep, + title: t('in_person_proofing.headings.prepare'), + }; + const locationFormStep: FormStep = { + name: 'location', + form: inPersonLocationPostOfficeSearchForm, + title: t('in_person_proofing.headings.po_search.location'), + }; + const hybridFormStep: FormStep = { + name: 'switch_back', + form: InPersonSwitchBackStep, + title: t('in_person_proofing.headings.switch_back'), + }; /** * Clears error state and sets form values for submission. @@ -80,62 +125,16 @@ function DocumentCapture({ onStepChange = () => {} }: DocumentCaptureProps) { initialValues = formValues; } - const inPersonLocationPostOfficeSearchForm = inPersonFullAddressEntryEnabled - ? InPersonLocationFullAddressEntryPostOfficeSearchStep - : InPersonLocationPostOfficeSearchStep; - const inPersonSteps: FormStep[] = inPersonURL === undefined ? [] - : ([ - { - name: 'prepare', - form: InPersonPrepareStep, - title: t('in_person_proofing.headings.prepare'), - }, - { - name: 'location', - form: inPersonLocationPostOfficeSearchForm, - title: t('in_person_proofing.headings.po_search.location'), - }, - flowPath === 'hybrid' && { - name: 'switch_back', - form: InPersonSwitchBackStep, - title: t('in_person_proofing.headings.switch_back'), - }, - ].filter(Boolean) as FormStep[]); + : ([prepareFormStep, locationFormStep, flowPath === 'hybrid' && hybridFormStep].filter( + Boolean, + ) as FormStep[]); const defaultSteps: FormStep[] = submissionError - ? ( - [ - { - name: 'review', - form: - submissionError instanceof UploadFormEntriesError - ? withProps({ - remainingSubmitAttempts: submissionError.remainingSubmitAttempts, - isResultCodeInvalid: submissionError.isResultCodeInvalid, - isFailedResult: submissionError.isFailedResult, - isFailedDocType: submissionError.isFailedDocType, - isFailedSelfie: submissionError.isFailedSelfie, - isFailedSelfieLivenessOrQuality: - submissionError.selfieNotLive || submissionError.selfieNotGoodQuality, - captureHints: submissionError.hints, - pii: submissionError.pii, - failedImageFingerprints: submissionError.failed_image_fingerprints, - })(ReviewIssuesStep) - : ReviewIssuesStep, - title: t('doc_auth.errors.rate_limited_heading'), - }, - ] as FormStep[] - ).concat(inPersonSteps) - : ([ - { - name: 'documents', - form: DocumentsStep, - title: t('doc_auth.headings.document_capture'), - }, - ].filter(Boolean) as FormStep[]); + ? ([reviewFormStep] as FormStep[]).concat(inPersonSteps) + : ([documentFormStep] as FormStep[]); // If the user got here by opting-in to in-person proofing, when skipDocAuth === true, // then set steps to inPersonSteps diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index 6ef3868ef16..bff4dfe7fd3 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -121,9 +121,11 @@ def check_enrollment(enrollment) enrollment.update(status_check_attempted_at: status_check_attempted_at) end - def passed_with_unsupported_secondary_id_type?(response) - return response['secondaryIdType'].present? && - SUPPORTED_SECONDARY_ID_TYPES.exclude?(response['secondaryIdType']) + def passed_with_unsupported_secondary_id_type?(enrollment, response) + return false if enrollment.enhanced_ipp? + + response['secondaryIdType'].present? && + SUPPORTED_SECONDARY_ID_TYPES.exclude?(response['secondaryIdType']) end def analytics(user: AnonymousUser.new) @@ -483,7 +485,7 @@ def process_enrollment_response(enrollment, response) when IPP_STATUS_PASSED if fraud_result_pending?(enrollment) handle_passed_with_fraud_review_pending(enrollment, response) - elsif passed_with_unsupported_secondary_id_type?(response) + elsif passed_with_unsupported_secondary_id_type?(enrollment, response) handle_unsupported_secondary_id(enrollment, response) elsif passed_with_primary_id_check?(enrollment, response) handle_successful_status_update(enrollment, response) diff --git a/app/models/document_capture_session.rb b/app/models/document_capture_session.rb index 0963509df7d..3b117e56ded 100644 --- a/app/models/document_capture_session.rb +++ b/app/models/document_capture_session.rb @@ -23,7 +23,7 @@ def store_result_from_response(doc_auth_response) session_result.selfie_status = doc_auth_response.selfie_status EncryptedRedisStructStorage.store( session_result, - expires_in: IdentityConfig.store.doc_capture_request_valid_for_minutes.minutes.seconds.to_i, + expires_in: IdentityConfig.store.doc_capture_request_valid_for_minutes.minutes.in_seconds, ) self.ocr_confirmation_pending = doc_auth_response.attention_with_barcode? save! @@ -45,7 +45,7 @@ def store_failed_auth_data(front_image_fingerprint:, back_image_fingerprint:, EncryptedRedisStructStorage.store( session_result, - expires_in: IdentityConfig.store.doc_capture_request_valid_for_minutes.minutes.seconds.to_i, + expires_in: IdentityConfig.store.doc_capture_request_valid_for_minutes.minutes.in_seconds, ) save! end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 8bea717ba07..4fc309a00a2 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -404,6 +404,8 @@ def edit_password_visit # @param [String] bad_password_count represents number of prior login failures # @param [Boolean] sp_request_url_present if was an SP request URL in the session # @param [Boolean] remember_device if the remember device cookie was present + # @param [Boolean, nil] new_device Whether the user is authenticating from a new device. Nil if + # there is the attempt was unsuccessful, since it cannot be known whether it's a new device. # Tracks authentication attempts at the email/password screen def email_and_password_auth( success:, @@ -413,6 +415,7 @@ def email_and_password_auth( bad_password_count:, sp_request_url_present:, remember_device:, + new_device:, **extra ) track_event( @@ -424,6 +427,7 @@ def email_and_password_auth( bad_password_count:, sp_request_url_present:, remember_device:, + new_device:, **extra, ) end @@ -5814,6 +5818,8 @@ def user_registration_cancellation(request_came_from:, **extra) # @param [Array] sp_session_requested_attributes Attributes requested by the service provider # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow # @param [String, nil] disposable_email_domain Disposable email domain used for registration + # @param [String, nil] in_person_proofing_status In person proofing status + # @param [String, nil] doc_auth_result The doc auth result def user_registration_complete( ial2:, service_provider_name:, @@ -5823,6 +5829,8 @@ def user_registration_complete( sp_session_requested_attributes:, ialmax: nil, disposable_email_domain: nil, + in_person_proofing_status: nil, + doc_auth_result: nil, **extra ) track_event( @@ -5835,6 +5843,8 @@ def user_registration_complete( needs_completion_screen_reason:, sp_session_requested_attributes:, disposable_email_domain:, + in_person_proofing_status:, + doc_auth_result:, **extra, ) end diff --git a/app/services/marketing_site.rb b/app/services/marketing_site.rb index 08ad301235c..4b67f6f62ab 100644 --- a/app/services/marketing_site.rb +++ b/app/services/marketing_site.rb @@ -11,7 +11,6 @@ class UnknownArticleException < StandardError; end manage-your-account/personal-key trouble-signing-in/face-or-touch-unlock verify-your-identity/accepted-identification-documents - verify-your-identity/accepted-state-issued-identification verify-your-identity/how-to-add-images-of-your-state-issued-id verify-your-identity/verify-your-identity-in-person verify-your-identity/phone-number diff --git a/app/services/rate_limiter.rb b/app/services/rate_limiter.rb index f25751f9246..7ef94fbbafc 100644 --- a/app/services/rate_limiter.rb +++ b/app/services/rate_limiter.rb @@ -79,7 +79,7 @@ def increment! multi.incr(key) multi.expireat( key, - now + RateLimiter.attempt_window_in_minutes(rate_limit_type).minutes.seconds.to_i, + now + RateLimiter.attempt_window_in_minutes(rate_limit_type).minutes.in_seconds, ) end end @@ -132,8 +132,7 @@ def increment_to_limited! client.set( key, value, - exat: now.to_i + - RateLimiter.attempt_window_in_minutes(rate_limit_type).minutes.seconds.to_i, + exat: now.to_i + RateLimiter.attempt_window_in_minutes(rate_limit_type).minutes.in_seconds, ) end diff --git a/app/services/service_provider_request_proxy.rb b/app/services/service_provider_request_proxy.rb index 91cea97db16..1175175cd95 100644 --- a/app/services/service_provider_request_proxy.rb +++ b/app/services/service_provider_request_proxy.rb @@ -70,7 +70,7 @@ def self.write(obj, uuid) REDIS_POOL.with do |client| client.setex( key(uuid), - IdentityConfig.store.service_provider_request_ttl_hours.hours.to_i, + IdentityConfig.store.service_provider_request_ttl_hours.hours.in_seconds, obj.to_json, ) end diff --git a/app/services/usps_in_person_proofing/mock/fixtures.rb b/app/services/usps_in_person_proofing/mock/fixtures.rb index c5eaffaa1b7..11a2aac5f62 100644 --- a/app/services/usps_in_person_proofing/mock/fixtures.rb +++ b/app/services/usps_in_person_proofing/mock/fixtures.rb @@ -77,6 +77,12 @@ def self.request_passed_proofing_supported_secondary_id_type_results_response ) end + def self.request_passed_proofing_secondary_id_type_results_response_ial_2 + load_response_fixture( + 'request_passed_proofing_secondary_id_type_results_response_ial_2.json', + ) + end + def self.request_expired_proofing_results_response load_response_fixture('request_expired_proofing_results_response.json') end diff --git a/app/services/usps_in_person_proofing/mock/responses/request_passed_proofing_secondary_id_type_results_response_ial_2.json b/app/services/usps_in_person_proofing/mock/responses/request_passed_proofing_secondary_id_type_results_response_ial_2.json new file mode 100644 index 00000000000..b87e45ab991 --- /dev/null +++ b/app/services/usps_in_person_proofing/mock/responses/request_passed_proofing_secondary_id_type_results_response_ial_2.json @@ -0,0 +1,14 @@ +{ + "status": "In-person passed", + "proofingPostOffice": "WILKES BARRE", + "proofingCity": "WILKES BARRE", + "proofingState": "PA", + "enrollmentCode": "2090002197504352", + "primaryIdType": "State driver's license", + "transactionStartDateTime": "12/17/2020 033855", + "transactionEndDateTime": "12/17/2020 034055", + "secondaryIdType": "State driver's license", + "fraudSuspected": false, + "proofingConfirmationNumber": "350040248346701", + "ippAssuranceLevel": "2.0" +} diff --git a/app/views/idv/in_person/state_id.html.erb b/app/views/idv/in_person/state_id.html.erb index 0e738146466..8595c0e77b8 100644 --- a/app/views/idv/in_person/state_id.html.erb +++ b/app/views/idv/in_person/state_id.html.erb @@ -28,7 +28,7 @@ <%= link_to( MarketingSite.help_center_article_url( category: 'verify-your-identity', - article: 'accepted-state-issued-identification', + article: 'accepted-identification-documents', ), class: 'display-inline', ) do %> diff --git a/config/environments/development.rb b/config/environments/development.rb index 9d2303fc94f..2c7433a6bcb 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -40,7 +40,7 @@ config.cache_store = :memory_store config.public_file_server.headers = { - Rack::CACHE_CONTROL => "public, max-age=#{2.days.to_i}", + Rack::CACHE_CONTROL => "public, max-age=#{2.days.in_seconds}", } else config.action_controller.perform_caching = false diff --git a/config/initializers/job_configurations.rb b/config/initializers/job_configurations.rb index cba2f104c9a..3b5a81fc33b 100644 --- a/config/initializers/job_configurations.rb +++ b/config/initializers/job_configurations.rb @@ -233,7 +233,7 @@ weekly_protocols_report: { class: 'Reports::ProtocolsReport', cron: cron_every_monday, - args: -> { [Time.zone.yesterday] }, + args: -> { [Time.zone.yesterday.end_of_day] }, }, }.compact end diff --git a/db/primary_migrate/20240708183211_add_doc_auth_result_to_in_person_enrollments.rb b/db/primary_migrate/20240708183211_add_doc_auth_result_to_in_person_enrollments.rb new file mode 100644 index 00000000000..7cc64052e54 --- /dev/null +++ b/db/primary_migrate/20240708183211_add_doc_auth_result_to_in_person_enrollments.rb @@ -0,0 +1,6 @@ +class AddDocAuthResultToInPersonEnrollments < ActiveRecord::Migration[7.1] + def change + add_column :in_person_enrollments, :doc_auth_result, :string + add_column :document_capture_sessions, :last_doc_auth_result, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c99936d6691..06cfd26c3f8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_06_04_173515) do +ActiveRecord::Schema[7.1].define(version: 2024_07_08_183211) do # These are extensions that must be enabled in order to support this database enable_extension "citext" enable_extension "pg_stat_statements" @@ -191,6 +191,7 @@ t.string "issuer" t.datetime "cancelled_at", precision: nil t.boolean "ocr_confirmation_pending", default: false + t.string "last_doc_auth_result" t.index ["result_id"], name: "index_document_capture_sessions_on_result_id" t.index ["user_id"], name: "index_document_capture_sessions_on_user_id" t.index ["uuid"], name: "index_document_capture_sessions_on_uuid" @@ -318,6 +319,7 @@ t.datetime "notification_sent_at", comment: "The time a notification was sent" t.datetime "last_batch_claimed_at" t.string "sponsor_id" + t.string "doc_auth_result" t.index ["profile_id"], name: "index_in_person_enrollments_on_profile_id" t.index ["ready_for_status_check"], name: "index_in_person_enrollments_on_ready_for_status_check", where: "(ready_for_status_check = true)" t.index ["status_check_attempted_at"], name: "index_in_person_enrollments_on_status_check_attempted_at", where: "(status = 1)" diff --git a/spec/controllers/country_support_controller_spec.rb b/spec/controllers/country_support_controller_spec.rb index 9b25219fd27..add5264b707 100644 --- a/spec/controllers/country_support_controller_spec.rb +++ b/spec/controllers/country_support_controller_spec.rb @@ -18,7 +18,7 @@ it 'sets HTTP headers to cache for 15 minutes' do get :index - expect(response['Cache-Control']).to eq("max-age=#{15.minutes.to_i}, public") + expect(response['Cache-Control']).to eq("max-age=#{15.minutes.in_seconds}, public") end context 'renders when passing in different locale' do diff --git a/spec/controllers/idv/image_uploads_controller_spec.rb b/spec/controllers/idv/image_uploads_controller_spec.rb index 16f665bd8d4..288cf1026c6 100644 --- a/spec/controllers/idv/image_uploads_controller_spec.rb +++ b/spec/controllers/idv/image_uploads_controller_spec.rb @@ -8,13 +8,17 @@ let(:back_image) { DocAuthImageFixtures.document_back_image_multipart } let(:selfie_img) { nil } let(:state_id_number) { 'S59397998' } + let(:user) { create(:user) } + + before do + stub_sign_in(user) if user + end describe '#create' do subject(:action) do post :create, params: params end - let(:user) { create(:user) } let!(:document_capture_session) { user.document_capture_sessions.create!(user: user) } let(:flow_path) { 'standard' } let(:params) do diff --git a/spec/controllers/idv/in_person/usps_locations_controller_spec.rb b/spec/controllers/idv/in_person/usps_locations_controller_spec.rb index 402ae40efa4..130b8bfe6f5 100644 --- a/spec/controllers/idv/in_person/usps_locations_controller_spec.rb +++ b/spec/controllers/idv/in_person/usps_locations_controller_spec.rb @@ -326,6 +326,23 @@ end end + context 'with failed doc_auth_result' do + before do + allow(controller).to receive(:document_capture_session).and_return( + OpenStruct.new({ last_doc_auth_result: 'Failed' }), + ) + end + + it 'updates the doc_auth_result in the enrollment' do + response + + enrollment = user.reload.establishing_in_person_enrollment + + expect(enrollment.selected_location_details).to_not be_nil + expect(enrollment.doc_auth_result).to eq('Failed') + end + end + context 'with feature disabled' do let(:in_person_proofing_enabled) { false } diff --git a/spec/controllers/redirect/help_center_controller_spec.rb b/spec/controllers/redirect/help_center_controller_spec.rb index 86cb32cde18..beae74ff5cc 100644 --- a/spec/controllers/redirect/help_center_controller_spec.rb +++ b/spec/controllers/redirect/help_center_controller_spec.rb @@ -27,7 +27,7 @@ context 'with valid help center article' do let(:category) { 'verify-your-identity' } - let(:article) { 'accepted-state-issued-identification' } + let(:article) { 'accepted-identification-documents' } let(:params) { super().merge(category:, article:) } it 'redirects to the help center article and logs' do diff --git a/spec/controllers/sign_up/cancellations_controller_spec.rb b/spec/controllers/sign_up/cancellations_controller_spec.rb index 96af62cb09b..62c74d61fe5 100644 --- a/spec/controllers/sign_up/cancellations_controller_spec.rb +++ b/spec/controllers/sign_up/cancellations_controller_spec.rb @@ -74,7 +74,7 @@ it 'redirects if confirmation_token is expired' do confirmation_token = '1' invalid_confirmation_sent_at = - Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.to_i + 1) + Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.in_seconds + 1) create( :user, email_addresses: [ diff --git a/spec/controllers/sign_up/completions_controller_spec.rb b/spec/controllers/sign_up/completions_controller_spec.rb index 41a4ea46018..985c64c241b 100644 --- a/spec/controllers/sign_up/completions_controller_spec.rb +++ b/spec/controllers/sign_up/completions_controller_spec.rb @@ -236,6 +236,8 @@ sp_session_requested_attributes: nil, in_account_creation_flow: true, disposable_email_domain: nil, + in_person_proofing_status: nil, + doc_auth_result: nil, ) end @@ -296,6 +298,8 @@ sp_session_requested_attributes: nil, in_account_creation_flow: true, disposable_email_domain: 'temporary.com', + doc_auth_result: nil, + in_person_proofing_status: nil, ) end end @@ -312,6 +316,7 @@ ) stub_sign_in(user) sp = create(:service_provider, issuer: 'https://awesome') + create(:in_person_enrollment, status: 'passed', doc_auth_result: 'Passed', user: user) subject.session[:sp] = { issuer: sp.issuer, acr_values: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, @@ -332,6 +337,8 @@ sp_session_requested_attributes: ['email'], in_account_creation_flow: true, disposable_email_domain: 'temporary.com', + in_person_proofing_status: 'passed', + doc_auth_result: 'Passed', ) end diff --git a/spec/controllers/sign_up/email_confirmations_controller_spec.rb b/spec/controllers/sign_up/email_confirmations_controller_spec.rb index 0adb05d8600..86aa2337e09 100644 --- a/spec/controllers/sign_up/email_confirmations_controller_spec.rb +++ b/spec/controllers/sign_up/email_confirmations_controller_spec.rb @@ -73,7 +73,7 @@ it 'tracks expired token' do invalid_confirmation_sent_at = - Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.to_i + 1) + Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.in_seconds + 1) email_address = create( :email_address, :unconfirmed, diff --git a/spec/controllers/sign_up/passwords_controller_spec.rb b/spec/controllers/sign_up/passwords_controller_spec.rb index 80597c6f9a4..11865486b7f 100644 --- a/spec/controllers/sign_up/passwords_controller_spec.rb +++ b/spec/controllers/sign_up/passwords_controller_spec.rb @@ -130,7 +130,7 @@ context 'with an with an invalid confirmation_token' do let(:token) { 'new token' } let(:invalid_confirmation_sent_at) do - Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.to_i + 1) + Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.in_seconds + 1) end let!(:user) do create( @@ -161,7 +161,7 @@ it 'rejects when confirmation_token is invalid' do invalid_confirmation_sent_at = - Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.to_i + 1) + Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.in_seconds + 1) create( :user, :unconfirmed, diff --git a/spec/controllers/users/sessions_controller_spec.rb b/spec/controllers/users/sessions_controller_spec.rb index c22af06d3bd..ad235ebe656 100644 --- a/spec/controllers/users/sessions_controller_spec.rb +++ b/spec/controllers/users/sessions_controller_spec.rb @@ -57,6 +57,7 @@ bad_password_count: 0, sp_request_url_present: false, remember_device: false, + new_device: true, ) end @@ -113,6 +114,24 @@ response end + + it 'tracks as not being from a new device' do + stub_analytics + + response + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', + success: true, + user_id: user.uuid, + user_locked_out: false, + valid_captcha_result: true, + bad_password_count: 0, + sp_request_url_present: false, + remember_device: false, + new_device: false, + ) + end end end @@ -150,7 +169,12 @@ user = create(:user, :fully_registered) stub_analytics - analytics_hash = { + expect(SCrypt::Engine).to receive(:hash_secret).once.and_call_original + + post :create, params: { user: { email: user.email.upcase, password: 'invalid_password' } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: false, user_id: user.uuid, user_locked_out: false, @@ -158,19 +182,19 @@ bad_password_count: 1, sp_request_url_present: false, remember_device: false, - } - expect(SCrypt::Engine).to receive(:hash_secret).once.and_call_original - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - post :create, params: { user: { email: user.email.upcase, password: 'invalid_password' } } + new_device: nil, + ) expect(subject.session[:sign_in_flow]).to eq(:sign_in) end it 'tracks the authentication attempt for nonexistent user' do stub_analytics - analytics_hash = { + expect(SCrypt::Engine).to receive(:hash_secret).once.and_call_original + + post :create, params: { user: { email: 'foo@example.com', password: 'password' } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: false, user_id: 'anonymous-uuid', user_locked_out: false, @@ -178,13 +202,8 @@ bad_password_count: 1, sp_request_url_present: false, remember_device: false, - } - expect(SCrypt::Engine).to receive(:hash_secret).once.and_call_original - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - post :create, params: { user: { email: 'foo@example.com', password: 'password' } } + new_device: nil, + ) end it 'tracks unsuccessful authentication for locked out user' do @@ -195,7 +214,11 @@ ) stub_analytics - analytics_hash = { + + post :create, params: { user: { email: user.email.upcase, password: user.password } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: false, user_id: user.uuid, user_locked_out: true, @@ -203,12 +226,8 @@ bad_password_count: 0, sp_request_url_present: false, remember_device: false, - } - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - post :create, params: { user: { email: user.email.upcase, password: user.password } } + new_device: nil, + ) end it 'tracks unsuccessful authentication for failed reCAPTCHA' do @@ -229,6 +248,7 @@ valid_captcha_result: false, bad_password_count: 0, remember_device: false, + new_device: nil, sp_request_url_present: false, ) end @@ -241,7 +261,10 @@ stub_analytics - analytics_hash = { + post :create, params: { user: { email: user.email.upcase, password: 'invalid' } } + post :create, params: { user: { email: user.email.upcase, password: 'invalid' } } + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: false, user_id: user.uuid, user_locked_out: false, @@ -249,18 +272,18 @@ bad_password_count: 2, sp_request_url_present: false, remember_device: false, - } - - post :create, params: { user: { email: user.email.upcase, password: 'invalid' } } - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - post :create, params: { user: { email: user.email.upcase, password: 'invalid' } } + new_device: nil, + ) end it 'tracks the presence of SP request_url in session' do subject.session[:sp] = { request_url: mock_valid_site } stub_analytics - analytics_hash = { + + post :create, params: { user: { email: 'foo@example.com', password: 'password' } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: false, user_id: 'anonymous-uuid', user_locked_out: false, @@ -268,12 +291,8 @@ bad_password_count: 1, sp_request_url_present: true, remember_device: false, - } - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - post :create, params: { user: { email: 'foo@example.com', password: 'password' } } + new_device: nil, + ) end context 'IAL1 user' do @@ -431,7 +450,11 @@ ) stub_analytics - analytics_hash = { + + post :create, params: { user: { email: user.email, password: user.password } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: true, user_id: user.uuid, user_locked_out: false, @@ -439,19 +462,12 @@ bad_password_count: 0, sp_request_url_present: false, remember_device: false, - } - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - profile_encryption_error = { + new_device: true, + ) + expect(@analytics).to have_logged_event( + 'Profile Encryption: Invalid', error: 'Unable to parse encrypted payload', - } - expect(@analytics).to receive(:track_event). - with('Profile Encryption: Invalid', profile_encryption_error) - - post :create, params: { user: { email: user.email, password: user.password } } - + ) expect(controller.user_session[:encrypted_profiles]).to be_nil expect(profile.reload).to_not be_active end @@ -558,7 +574,11 @@ } stub_analytics - analytics_hash = { + + post :create, params: { user: { email: user.email, password: user.password } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: true, user_id: user.uuid, user_locked_out: false, @@ -566,12 +586,8 @@ bad_password_count: 0, sp_request_url_present: false, remember_device: true, - } - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - post :create, params: { user: { email: user.email, password: user.password } } + new_device: true, + ) end end @@ -584,7 +600,11 @@ } stub_analytics - analytics_hash = { + + post :create, params: { user: { email: user.email, password: user.password } } + + expect(@analytics).to have_logged_event( + 'Email and Password Authentication', success: true, user_id: user.uuid, user_locked_out: false, @@ -592,12 +612,8 @@ bad_password_count: 0, sp_request_url_present: false, remember_device: true, - } - - expect(@analytics).to receive(:track_event). - with('Email and Password Authentication', analytics_hash) - - post :create, params: { user: { email: user.email, password: user.password } } + new_device: true, + ) end end diff --git a/spec/features/sign_in/setup_piv_cac_after_sign_in_spec.rb b/spec/features/sign_in/setup_piv_cac_after_sign_in_spec.rb index d41afebdc5c..146b5441230 100644 --- a/spec/features/sign_in/setup_piv_cac_after_sign_in_spec.rb +++ b/spec/features/sign_in/setup_piv_cac_after_sign_in_spec.rb @@ -57,8 +57,54 @@ to(include(expected_form_action)) end + scenario 'user opts to add piv/cac card and has to reauthenticate on remembered device' do + # Authenticate user to ensure remembered device cookie is established + user = create(:user, :fully_registered, :with_phone) + travel_to (IdentityConfig.store.reauthn_window + 1).seconds.ago do + sign_in_user(user) + check(t('forms.messages.remember_device')) + fill_in_code_with_last_phone_otp + click_submit_default + click_on t('links.sign_out') + end + + # Try signing in with PIV/CAC + sign_in_with_piv_cac_user_not_found + click_on t('instructions.mfa.piv_cac.back_to_sign_in') + + # Sign in with username and password + fill_in_credentials_and_submit(user.email, user.password) + + # Reauthenticate + expect(page).to have_content(t('two_factor_authentication.login_intro_reauthentication')) + expect(page).to have_current_path(login_two_factor_options_path) + click_on t('forms.buttons.continue') + fill_in_code_with_last_phone_otp + click_submit_default + + # Add PIV/CAC after sign-in + expect(current_path).to eq login_add_piv_cac_prompt_path + stub_piv_cac_service + fill_in 'name', with: 'Card 1' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect + + expect(page).to have_content(t('notices.piv_cac_configured')) + expect(current_path).to eq sign_up_completed_path + end + def perform_steps_to_get_to_add_piv_cac_during_sign_up(sp: :oidc) user = create(:user, :fully_registered, :with_phone) + sign_in_with_piv_cac_user_not_found(sp:) + click_on t('instructions.mfa.piv_cac.back_to_sign_in') + fill_in_credentials_and_submit(user.email, user.password) + fill_in_code_with_last_phone_otp + click_submit_default + expect(current_path).to eq login_add_piv_cac_prompt_path + fill_in 'name', with: 'Card 1' + end + + def sign_in_with_piv_cac_user_not_found(sp: :oidc) if sp visit_idp_from_sp_with_ial1(sp) else @@ -71,12 +117,5 @@ def perform_steps_to_get_to_add_piv_cac_during_sign_up(sp: :oidc) follow_piv_cac_redirect expect(page).to have_current_path(login_piv_cac_error_path(error: 'user.not_found')) - click_on t('instructions.mfa.piv_cac.back_to_sign_in') - - fill_in_credentials_and_submit(user.email, user.password) - fill_in_code_with_last_phone_otp - click_submit_default - expect(current_path).to eq login_add_piv_cac_prompt_path - fill_in t('forms.piv_cac_setup.nickname'), with: 'Card 1' end end diff --git a/spec/forms/idv/api_image_upload_form_spec.rb b/spec/forms/idv/api_image_upload_form_spec.rb index a31ecd4b90f..18f260fbd31 100644 --- a/spec/forms/idv/api_image_upload_form_spec.rb +++ b/spec/forms/idv/api_image_upload_form_spec.rb @@ -452,7 +452,10 @@ DocAuth::Response.new( success: false, errors: errors, - extra: { remaining_submit_attempts: IdentityConfig.store.doc_auth_max_attempts - 1 }, + extra: { + remaining_submit_attempts: IdentityConfig.store.doc_auth_max_attempts - 1, + doc_auth_result: 'Failed', + }, ) end let(:doc_auth_client) { double(DocAuth::LexisNexis::LexisNexisClient) } @@ -470,7 +473,16 @@ expect(response.selfie_status).to eq(:not_processed) expect(response.attention_with_barcode?).to eq(false) expect(response.pii_from_doc).to eq(nil) + end + + it 'saves the doc_auth_result to document_capture_session' do + response = form.submit + session = DocumentCaptureSession.find_by(uuid: document_capture_session_uuid) + + expect(response).to be_a_kind_of DocAuth::Response + expect(response.success?).to eq(false) expect(response.doc_auth_success?).to eq(false) + expect(session.last_doc_auth_result).to eq('Failed') end it 'includes remaining_submit_attempts' do @@ -498,7 +510,7 @@ expect(fake_analytics).to have_logged_event( 'IdV: doc auth image upload vendor submitted', hash_including( - doc_auth_result: nil, + doc_auth_result: 'Failed', errors: { front: 'glare' }, success: false, doc_type_supported: boolean, diff --git a/spec/forms/openid_connect_token_form_spec.rb b/spec/forms/openid_connect_token_form_spec.rb index 94ec7640ec5..e9b8403418c 100644 --- a/spec/forms/openid_connect_token_form_spec.rb +++ b/spec/forms/openid_connect_token_form_spec.rb @@ -412,7 +412,7 @@ OutOfBandSessionAccessor.new( identity.rails_session_id, ).put_empty_user_session( - 5.minutes.to_i, + 5.minutes.in_seconds, ) end diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index e3786004737..07a12cbfcf1 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -1498,24 +1498,28 @@ end describe 'Enhanced In-Person Proofing' do + let!(:pending_enrollment) do + create( + :in_person_enrollment, + :pending, + :with_notification_phone_configuration, + issuer: 'http://localhost:3000', + selected_location_details: { name: 'BALTIMORE' }, + sponsor_id: usps_eipp_sponsor_id, + ) + end + + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) + end + context <<~STR.squish do When an Enhanced IPP enrollment passess proofing with unsupported ID,enrollment by-passes the Primary ID check and STR - let!(:pending_enrollment) do - create( - :in_person_enrollment, - :pending, - :with_notification_phone_configuration, - issuer: 'http://localhost:3000', - selected_location_details: { name: 'BALTIMORE' }, - sponsor_id: usps_eipp_sponsor_id, - ) - end before do - allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) stub_request_passed_proofing_unsupported_id_results end @@ -1561,6 +1565,21 @@ ) end end + + context 'By passes the Secondary ID check when enrollment is Enhanced IPP' do + before do + stub_request_passed_proofing_secondary_id_type_results_ial_2 + end + + it_behaves_like( + 'enrollment_with_a_status_update', + passed: true, + email_type: 'Success', + enrollment_status: InPersonEnrollment::STATUS_PASSED, + response_json: UspsInPersonProofing::Mock::Fixtures. + request_passed_proofing_secondary_id_type_results_response_ial_2, + ) + end end end diff --git a/spec/jobs/reports/protocols_report_spec.rb b/spec/jobs/reports/protocols_report_spec.rb index 2e117ca682b..5d524f6981b 100644 --- a/spec/jobs/reports/protocols_report_spec.rb +++ b/spec/jobs/reports/protocols_report_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' RSpec.describe Reports::ProtocolsReport do - let(:report_date) { Date.new(2024, 7, 5) } + let(:report_date) { Date.new(2024, 7, 5).in_time_zone('UTC') } let(:email) { 'team@example.com' } let(:report_configs) do @@ -40,4 +40,16 @@ subject.perform(report_date) end end + + describe 'with empty logs' do + before do + stub_cloudwatch_logs([]) + end + + it 'sends an email with at least 1 attachment' do + subject.perform(report_date) + sent_mail = ActionMailer::Base.deliveries.last + expect(sent_mail.parts.attachments.count).to be >= 1 + end + end end diff --git a/spec/models/document_capture_session_spec.rb b/spec/models/document_capture_session_spec.rb index 5e67837cfa5..b1056460a49 100644 --- a/spec/models/document_capture_session_spec.rb +++ b/spec/models/document_capture_session_spec.rb @@ -21,6 +21,9 @@ zipcode: '12345', issuing_country_code: 'USA', ), + extra: { + doc_auth_result: 'Passed', + }, ) end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a84e0a83bad..049f8691016 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1000,7 +1000,7 @@ OutOfBandSessionAccessor.new(mock_session_id).put_pii( profile_id: 123, pii: { first_name: 'Mario' }, - expiration: 5.minutes.to_i, + expiration: 5.minutes.in_seconds, ) expect(OutOfBandSessionAccessor.new(mock_session_id).exists?).to eq true diff --git a/spec/presenters/openid_connect_user_info_presenter_spec.rb b/spec/presenters/openid_connect_user_info_presenter_spec.rb index 0f662816518..c268c9f3dd3 100644 --- a/spec/presenters/openid_connect_user_info_presenter_spec.rb +++ b/spec/presenters/openid_connect_user_info_presenter_spec.rb @@ -49,7 +49,7 @@ OutOfBandSessionAccessor.new(rails_session_id).put_pii( profile_id: profile.id, pii: pii, - expiration: 5.minutes.to_i, + expiration: 5.minutes.in_seconds, ) end end @@ -284,7 +284,7 @@ context 'when the piv/cac was used as a second factor' do before do - OutOfBandSessionAccessor.new(rails_session_id).put_x509(x509, 5.minutes.to_i) + OutOfBandSessionAccessor.new(rails_session_id).put_x509(x509, 5.minutes.in_seconds) end it 'includes the x509 claims' do diff --git a/spec/services/marketing_site_spec.rb b/spec/services/marketing_site_spec.rb index a49dd628769..c2d6bbdd8d7 100644 --- a/spec/services/marketing_site_spec.rb +++ b/spec/services/marketing_site_spec.rb @@ -170,20 +170,20 @@ context 'with valid article' do let(:category) { 'verify-your-identity' } - let(:article) { 'accepted-state-issued-identification' } + let(:article) { 'accepted-identification-documents' } it_behaves_like 'a marketing site URL' it 'returns article URL' do expect(url).to eq( - 'https://www.login.gov/help/verify-your-identity/accepted-state-issued-identification/', + 'https://www.login.gov/help/verify-your-identity/accepted-identification-documents/', ) end end context 'with anchor' do let(:category) { 'verify-your-identity' } - let(:article) { 'accepted-state-issued-identification' } + let(:article) { 'accepted-identification-documents' } let(:article_anchor) { 'test-anchor-url' } let(:url) do MarketingSite.help_center_article_url(category:, article:, article_anchor:) @@ -193,7 +193,7 @@ it 'returns article URL' do expect(url).to eq( - 'https://www.login.gov/help/verify-your-identity/accepted-state-issued-identification/#test-anchor-url', + 'https://www.login.gov/help/verify-your-identity/accepted-identification-documents/#test-anchor-url', ) end end @@ -213,7 +213,7 @@ context 'with valid article' do let(:category) { 'verify-your-identity' } - let(:article) { 'accepted-state-issued-identification' } + let(:article) { 'accepted-identification-documents' } it { expect(result).to eq(true) } diff --git a/spec/services/out_of_band_session_accessor_spec.rb b/spec/services/out_of_band_session_accessor_spec.rb index 3eaebff1913..68f414ab2be 100644 --- a/spec/services/out_of_band_session_accessor_spec.rb +++ b/spec/services/out_of_band_session_accessor_spec.rb @@ -17,10 +17,10 @@ store.put_pii( profile_id: profile_id, pii: { first_name: 'Fakey' }, - expiration: 5.minutes.to_i, + expiration: 5.minutes.in_seconds, ) - expect(store.ttl).to be_within(1).of(5.minutes.to_i) + expect(store.ttl).to be_within(1).of(5.minutes.in_seconds) end end @@ -29,7 +29,7 @@ store.put_pii( profile_id: profile_id, pii: { dob: '1970-01-01' }, - expiration: 5.minutes.to_i, + expiration: 5.minutes.in_seconds, ) pii = store.load_pii(profile_id) @@ -40,7 +40,7 @@ describe '#load_x509' do it 'loads X509 attributes from the session' do - store.put_x509({ subject: 'O=US, OU=DoD, CN=John.Doe.1234' }, 5.minutes.to_i) + store.put_x509({ subject: 'O=US, OU=DoD, CN=John.Doe.1234' }, 5.minutes.in_seconds) x509 = store.load_x509 expect(x509).to be_kind_of(X509::Attributes) @@ -53,7 +53,7 @@ store.put_pii( profile_id: profile_id, pii: { first_name: 'Fakey' }, - expiration: 5.minutes.to_i, + expiration: 5.minutes.in_seconds, ) store.destroy diff --git a/spec/services/send_sign_up_email_confirmation_spec.rb b/spec/services/send_sign_up_email_confirmation_spec.rb index 77190028a36..e7e23378aec 100644 --- a/spec/services/send_sign_up_email_confirmation_spec.rb +++ b/spec/services/send_sign_up_email_confirmation_spec.rb @@ -43,7 +43,7 @@ context 'when the user already has a confirmation token' do let(:email_address) do invalid_confirmation_sent_at = - Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.to_i + 1) + Time.zone.now - (IdentityConfig.store.add_email_link_valid_for_hours.hours.in_seconds + 1) create( :email_address, diff --git a/spec/support/usps_ipp_helper.rb b/spec/support/usps_ipp_helper.rb index a73504ba76d..67b9ab8fff9 100644 --- a/spec/support/usps_ipp_helper.rb +++ b/spec/support/usps_ipp_helper.rb @@ -239,6 +239,15 @@ def stub_request_passed_proofing_supported_secondary_id_type_results ) end + def stub_request_passed_proofing_secondary_id_type_results_ial_2 + stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( + status: 200, + body: UspsInPersonProofing::Mock:: + Fixtures.request_passed_proofing_secondary_id_type_results_response_ial_2, + headers: { 'content-type' => 'application/json' }, + ) + end + def stub_request_passed_proofing_unsupported_status_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( status: 200,