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
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ GEM
concurrent-ruby (~> 1.0)
unicode-display_width (2.6.0)
uniform_notifier (1.16.0)
uri (1.0.2)
uri (1.0.3)
useragent (0.16.11)
view_component (3.21.0)
activesupport (>= 5.2.0, < 8.1)
Expand Down
10 changes: 8 additions & 2 deletions app/controllers/concerns/two_factor_authenticatable_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,24 @@ def handle_verification_for_authentication_context(result:, auth_method:, extra_
if result.success?
handle_valid_verification_for_authentication_context(auth_method:)
user_session.delete(:mfa_attempts)
session.delete(:sign_in_recaptcha_assessment_id)
session.delete(:sign_in_recaptcha_assessment_id) if sign_in_recaptcha_annotation_enabled?
else
handle_invalid_verification_for_authentication_context
end
end

def annotate_recaptcha(reason)
RecaptchaAnnotator.annotate(assessment_id: session[:sign_in_recaptcha_assessment_id], reason:)
if sign_in_recaptcha_annotation_enabled?
RecaptchaAnnotator.annotate(assessment_id: session[:sign_in_recaptcha_assessment_id], reason:)
end
end

private

def sign_in_recaptcha_annotation_enabled?
IdentityConfig.store.sign_in_recaptcha_annotation_enabled
end

def handle_valid_verification_for_authentication_context(auth_method:)
mark_user_session_authenticated(auth_method:, authentication_type: :valid_2fa)
disavowal_event, disavowal_token = create_user_event_with_disavowal(:sign_in_after_2fa)
Expand Down
3 changes: 1 addition & 2 deletions app/controllers/idv/welcome_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class WelcomeController < ApplicationController
include StepIndicatorConcern

before_action :confirm_not_rate_limited
before_action :cancel_previous_in_person_enrollments, only: :show

def show
idv_session.proofing_started_at ||= Time.zone.now.iso8601
Expand All @@ -23,7 +24,6 @@ def update
analytics.idv_doc_auth_welcome_submitted(**analytics_arguments)

create_document_capture_session
cancel_previous_in_person_enrollments

idv_session.welcome_visited = true

Expand Down Expand Up @@ -61,7 +61,6 @@ def create_document_capture_session
end

def cancel_previous_in_person_enrollments
return unless IdentityConfig.store.in_person_proofing_enabled
UspsInPersonProofing::EnrollmentHelper.cancel_establishing_and_in_progress_enrollments(
current_user,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ interface AcuantCaptureProps {
* Determine whether the selfie help text shoule be shown.
*/
showSelfieHelp: () => void;
/**
* Whether user is on the failed submission review step
*/
isReviewStep?: boolean;
}

/**
Expand Down Expand Up @@ -313,6 +317,7 @@ function AcuantCapture(
errorMessage,
name,
showSelfieHelp,
isReviewStep,
}: AcuantCaptureProps,
ref: Ref<HTMLInputElement | null>,
) {
Expand All @@ -327,7 +332,7 @@ function AcuantCapture(
} = useContext(AcuantContext);
const { isMockClient } = useContext(UploadContext);
const { trackEvent } = useContext(AnalyticsContext);
const { isSelfieCaptureEnabled, immediatelyBeginCapture } = useContext(SelfieCaptureContext);
const { isSelfieCaptureEnabled } = useContext(SelfieCaptureContext);
const fullScreenRef = useRef<FullScreenRefHandle>(null);
const inputRef = useRef<HTMLInputElement>(null);
const isForceUploading = useRef(false);
Expand All @@ -350,7 +355,7 @@ function AcuantCapture(
const isBackOfId = name === 'back';
useLogCameraInfo({ isBackOfId, hasStartedCropping });
const [isCapturingEnvironment, setIsCapturingEnvironment] = useState(
selfieCapture && immediatelyBeginCapture,
selfieCapture && !isReviewStep,
);

const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ function DocumentSideAcuantCapture({
className={className}
allowUpload={isUploadAllowed}
showSelfieHelp={showSelfieHelp}
isReviewStep={isReviewStep}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,12 @@ interface SelfieCaptureProps {
* the capture component.
*/
showHelpInitially: boolean;
/**
* Specify whether we should try to capture using Acuant immediately
*/
immediatelyBeginCapture: boolean;
}

const SelfieCaptureContext = createContext<SelfieCaptureProps>({
isSelfieCaptureEnabled: false,
isSelfieDesktopTestMode: false,
showHelpInitially: true,
immediatelyBeginCapture: false,
});

SelfieCaptureContext.displayName = 'SelfieCaptureContext';
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/packages/phone-input/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "1.0.0",
"dependencies": {
"intl-tel-input": "^24.5.0",
"libphonenumber-js": "^1.12.4"
"libphonenumber-js": "^1.12.5"
},
"sideEffects": [
"./index.ts"
Expand Down
1 change: 0 additions & 1 deletion app/javascript/packs/document-capture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ render(
isSelfieCaptureEnabled: getSelfieCaptureEnabled(),
isSelfieDesktopTestMode: String(docAuthSelfieDesktopTestMode) === 'true',
showHelpInitially: true,
immediatelyBeginCapture: false,
}}
>
<FailedCaptureAttemptsContextProvider
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/data_warehouse/table_summary_stats_export_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class TableSummaryStatsExportJob < BaseJob

TABLE_EXCLUSION_LIST = %w[
agency_identities
usps_confirmations
].freeze

TIMESTAMP_OVERRIDE = {
'sp_return_logs' => 'returned_at',
'registration_logs' => 'registered_at',
'letter_requests_to_usps_ftp_logs' => 'ftp_at',
}.freeze

def perform(timestamp)
Expand Down
14 changes: 12 additions & 2 deletions app/services/encryption/contextless_kms_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,23 @@ class ContextlessKmsClient
}.freeze

def encrypt(plaintext, log_context: nil)
KmsLogger.log(:encrypt, key_id: IdentityConfig.store.aws_kms_key_id, log_context: log_context)
KmsLogger.log(
action: :encrypt,
timestamp: Time.zone.now,
key_id: IdentityConfig.store.aws_kms_key_id,
log_context: log_context,
)
return encrypt_kms(plaintext) if FeatureManagement.use_kms?
encrypt_local(plaintext)
end

def decrypt(ciphertext, log_context: nil)
KmsLogger.log(:decrypt, key_id: IdentityConfig.store.aws_kms_key_id, log_context: log_context)
KmsLogger.log(
action: :decrypt,
timestamp: Time.zone.now,
key_id: IdentityConfig.store.aws_kms_key_id,
log_context: log_context,
)
return decrypt_kms(ciphertext) if use_kms?(ciphertext)
decrypt_local(ciphertext)
end
Expand Down
14 changes: 12 additions & 2 deletions app/services/encryption/kms_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ def initialize(kms_key_id: IdentityConfig.store.aws_kms_key_id)
end

def encrypt(plaintext, encryption_context)
KmsLogger.log(:encrypt, context: encryption_context, key_id: kms_key_id)
KmsLogger.log(
action: :encrypt,
timestamp: Time.zone.now,
context: encryption_context,
key_id: kms_key_id,
)
return encrypt_kms(plaintext, encryption_context) if FeatureManagement.use_kms?
encrypt_local(plaintext, encryption_context)
end
Expand All @@ -41,7 +46,12 @@ def decrypt(ciphertext, encryption_context)
if self.class.looks_like_contextless?(ciphertext)
return decrypt_contextless_kms(ciphertext, encryption_context)
end
KmsLogger.log(:decrypt, context: encryption_context, key_id: kms_key_id)
KmsLogger.log(
action: :decrypt,
timestamp: Time.zone.now,
context: encryption_context,
key_id: kms_key_id,
)
return decrypt_kms(ciphertext, encryption_context) if use_kms?(ciphertext)
decrypt_local(ciphertext, encryption_context)
end
Expand Down
3 changes: 2 additions & 1 deletion app/services/encryption/kms_logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

module Encryption
class KmsLogger
def self.log(action, key_id:, context: nil, log_context: nil)
def self.log(action:, timestamp:, key_id:, context: nil, log_context: nil)
output = {
kms: {
timestamp: timestamp,
action: action,
encryption_context: context,
log_context: log_context,
Expand Down
7 changes: 4 additions & 3 deletions app/services/recaptcha_annotator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ def annotate(assessment_id:, reason: nil, annotation: nil)
return if assessment_id.blank?

if FeatureManagement.recaptcha_enterprise?
assessment = create_or_update_assessment!(assessment_id:, reason:, annotation:)
RecaptchaAnnotateJob.perform_later(assessment:)
submit_annotation(assessment_id:, reason:, annotation:)
# Future:
# assessment = create_or_update_assessment!(assessment_id:, reason:, annotation:)
# RecaptchaAnnotateJob.perform_later(assessment:)
end

{ assessment_id:, reason:, annotation: }
Expand All @@ -34,7 +36,6 @@ def submit_assessment(assessment)
annotation: assessment.annotation_before_type_cast,
reason: assessment.annotation_reason_before_type_cast,
)
assessment.destroy
end

private
Expand Down
5 changes: 4 additions & 1 deletion app/services/saml_request_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def authorized_service_provider
end

def authorized_authn_context
# if there is no service provider, an error has already been added
return unless service_provider.present?

if !valid_authn_context? ||
(identity_proofing_requested? && !service_provider.identity_proofing_allowed?) ||
(ial_max_requested? && !service_provider.ialmax_allowed?) ||
Expand All @@ -74,7 +77,7 @@ def parsable_vtr
end

def registered_cert_exists
# if there is no service provider, this error has already been added
# if there is no service provider, an error has already been added
return if service_provider.blank?
return if service_provider.certs.present?
return unless service_provider.encrypt_responses?
Expand Down
3 changes: 3 additions & 0 deletions config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ short_term_phone_otp_max_attempt_window_in_seconds: 10
short_term_phone_otp_max_attempts: 2
show_unsupported_passkey_platform_authentication_setup: false
show_user_attribute_deprecation_warnings: false
sign_in_recaptcha_annotation_enabled: false
sign_in_recaptcha_log_failures_only: false
sign_in_recaptcha_percent_tested: 0
sign_in_recaptcha_score_threshold: 0.0
Expand Down Expand Up @@ -507,6 +508,7 @@ development:
secret_key_base: development_secret_key_base
session_encryption_key: 27bad3c25711099429c1afdfd1890910f3b59f5a4faec1c85e945cb8b02b02f261ba501d99cfbb4fab394e0102de6fecf8ffe260f322f610db3e96b2a775c120
show_unsupported_passkey_platform_authentication_setup: true
sign_in_recaptcha_annotation_enabled: true
sign_in_recaptcha_percent_tested: 100
sign_in_recaptcha_score_threshold: 0.3
skip_encryption_allowed_list: '["urn:gov:gsa:SAML:2.0.profiles:sp:sso:localhost"]'
Expand Down Expand Up @@ -607,6 +609,7 @@ test:
secret_key_base: test_secret_key_base
session_encryption_key: 27bad3c25711099429c1afdfd1890910f3b59f5a4faec1c85e945cb8b02b02f261ba501d99cfbb4fab394e0102de6fecf8ffe260f322f610db3e96b2a775c120
short_term_phone_otp_max_attempts: 100
sign_in_recaptcha_annotation_enabled: true
skip_encryption_allowed_list: '[]'
socure_docv_document_request_endpoint: 'https://sandbox.socure.test/documnt-request'
socure_docv_webhook_secret_key: 'secret-key'
Expand Down

This file was deleted.

4 changes: 1 addition & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[8.0].define(version: 2025_02_28_141538) do
ActiveRecord::Schema[8.0].define(version: 2025_02_24_134110) do
# These are extensions that must be enabled in order to support this database
enable_extension "citext"
enable_extension "pg_catalog.plpgsql"
Expand Down Expand Up @@ -482,8 +482,6 @@
create_table "recaptcha_assessments", id: :string, force: :cascade do |t|
t.string "annotation", comment: "sensitive=false"
t.string "annotation_reason", comment: "sensitive=false"
t.datetime "created_at", null: false, comment: "sensitive=false"
t.datetime "updated_at", null: false, comment: "sensitive=false"
end

create_table "registration_logs", force: :cascade do |t|
Expand Down
4 changes: 2 additions & 2 deletions lib/data_pull.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,13 @@ def run(args:, config:)
]
end
elsif config.include_missing?
table << [user.uuid, '[HAS NO PROFILE]', nil, nil, nil, nil, nil, nil]
table << [user.uuid, '[HAS NO PROFILE]', nil, nil, nil, nil, nil, nil, nil]
end
end

if config.include_missing?
(uuids - users.map(&:uuid)).each do |missing_uuid|
table << [missing_uuid, '[UUID NOT FOUND]', nil, nil, nil, nil, nil, nil]
table << [missing_uuid, '[UUID NOT FOUND]', nil, nil, nil, nil, nil, nil, nil]
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/identity_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ def self.store
config.add(:sign_in_user_id_per_ip_attempt_window_in_minutes, type: :integer)
config.add(:sign_in_user_id_per_ip_attempt_window_max_minutes, type: :integer)
config.add(:sign_in_user_id_per_ip_max_attempts, type: :integer)
config.add(:sign_in_recaptcha_annotation_enabled, type: :boolean)
config.add(:sign_in_recaptcha_log_failures_only, type: :boolean)
config.add(:sign_in_recaptcha_percent_tested, type: :integer)
config.add(:sign_in_recaptcha_score_threshold, type: :float)
Expand Down
Loading