diff --git a/Gemfile b/Gemfile
index 5f234e1ece7..ecbb06f22d7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -13,7 +13,6 @@ gem 'aws-sdk-ses', '~> 1.6'
gem 'aws-sdk-sns'
gem 'barby', '~> 0.6.8'
gem 'base32-crockford'
-gem 'blueprinter', '~> 0.25.3'
gem 'bootsnap', '~> 1.9.0', require: false
gem 'browser'
gem 'connection_pool'
diff --git a/Gemfile.lock b/Gemfile.lock
index 5552af47b72..f29bdfa603c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -188,7 +188,6 @@ GEM
bindata (2.4.10)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
- blueprinter (0.25.3)
bootsnap (1.9.3)
msgpack (~> 1.0)
brakeman (5.2.1)
@@ -309,7 +308,7 @@ GEM
railties (>= 6.0.0)
thor (>= 0.14.1)
webrick (>= 1.3)
- google-protobuf (3.21.7)
+ google-protobuf (3.21.9)
guard (2.16.2)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
@@ -440,7 +439,7 @@ GEM
parser (3.1.2.1)
ast (~> 2.4.1)
pg (1.3.5)
- pg_query (2.1.3)
+ pg_query (2.2.0)
google-protobuf (>= 3.19.2)
phonelib (0.6.54)
pkcs11 (0.3.4)
@@ -735,7 +734,6 @@ DEPENDENCIES
base32-crockford
better_errors (>= 2.5.1)
binding_of_caller
- blueprinter (~> 0.25.3)
bootsnap (~> 1.9.0)
brakeman
browser
diff --git a/app/blueprints/agreements/agency_blueprint.rb b/app/blueprints/agreements/agency_blueprint.rb
deleted file mode 100644
index 914769b0ee5..00000000000
--- a/app/blueprints/agreements/agency_blueprint.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Agreements
- class AgencyBlueprint < Blueprinter::Base
- identifier :abbreviation
-
- field :name
- end
-end
diff --git a/app/blueprints/agreements/iaa_blueprint.rb b/app/blueprints/agreements/iaa_blueprint.rb
deleted file mode 100644
index b5359a07917..00000000000
--- a/app/blueprints/agreements/iaa_blueprint.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Agreements
- class IaaBlueprint < Blueprinter::Base
- identifier :iaa_number
-
- field :partner_account
- field :gtc_number
- field :gtc_mod_number
- field :gtc_start_date, datetime_format: '%Y-%m-%d'
- field :gtc_end_date, datetime_format: '%Y-%m-%d'
- field :gtc_estimated_amount
- field :gtc_status
- field :order_number
- field :order_mod_number
- field :order_start_date, datetime_format: '%Y-%m-%d'
- field :order_end_date, datetime_format: '%Y-%m-%d'
- field :order_estimated_amount
- field :order_status
- field :ial2_users
- field :authentications
- end
-end
diff --git a/app/blueprints/agreements/partner_account_blueprint.rb b/app/blueprints/agreements/partner_account_blueprint.rb
deleted file mode 100644
index ce1a1ff81d2..00000000000
--- a/app/blueprints/agreements/partner_account_blueprint.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module Agreements
- class PartnerAccountBlueprint < Blueprinter::Base
- identifier :requesting_agency
-
- field :name
- field :became_partner, datetime_format: '%Y-%m-%d'
- field :status do |account, _options|
- account.partner_status
- end
- end
-end
diff --git a/app/controllers/idv/image_uploads_controller.rb b/app/controllers/idv/image_uploads_controller.rb
index 30d0af89889..a72f9fa6aa6 100644
--- a/app/controllers/idv/image_uploads_controller.rb
+++ b/app/controllers/idv/image_uploads_controller.rb
@@ -24,7 +24,13 @@ def image_upload_form
analytics: analytics,
uuid_prefix: current_sp&.app_id,
irs_attempts_api_tracker: irs_attempts_api_tracker,
+ store_encrypted_images: store_encrypted_images?,
)
end
+
+ def store_encrypted_images?
+ IdentityConfig.store.encrypted_document_storage_enabled &&
+ irs_attempt_api_enabled_for_session?
+ end
end
end
diff --git a/app/decorators/user_decorator.rb b/app/decorators/user_decorator.rb
index 265d018068c..51e70b19e0c 100644
--- a/app/decorators/user_decorator.rb
+++ b/app/decorators/user_decorator.rb
@@ -7,7 +7,6 @@ class UserDecorator
MAX_RECENT_EVENTS = 5
MAX_RECENT_DEVICES = 5
- DEFAULT_LOCKOUT_PERIOD = 10.minutes
def initialize(user)
@user = user
@@ -137,12 +136,7 @@ def delete_account_bullet_key
private
def lockout_period
- return DEFAULT_LOCKOUT_PERIOD if lockout_period_config.blank?
- lockout_period_config.minutes
- end
-
- def lockout_period_config
- @lockout_period_config ||= IdentityConfig.store.lockout_period_in_minutes
+ IdentityConfig.store.lockout_period_in_minutes.minutes
end
def lockout_period_expired?
diff --git a/app/forms/add_user_email_form.rb b/app/forms/add_user_email_form.rb
index 6ff9243be84..3912d26071a 100644
--- a/app/forms/add_user_email_form.rb
+++ b/app/forms/add_user_email_form.rb
@@ -1,6 +1,7 @@
class AddUserEmailForm
include ActiveModel::Model
include FormAddEmailValidator
+ include ActionView::Helpers::TranslationHelper
attr_reader :email
diff --git a/app/forms/idv/api_image_upload_form.rb b/app/forms/idv/api_image_upload_form.rb
index a4e46080e2b..e697dca995f 100644
--- a/app/forms/idv/api_image_upload_form.rb
+++ b/app/forms/idv/api_image_upload_form.rb
@@ -11,13 +11,14 @@ class ApiImageUploadForm
validate :throttle_if_rate_limited
def initialize(params, service_provider:, analytics: nil,
- uuid_prefix: nil, irs_attempts_api_tracker: nil)
+ uuid_prefix: nil, irs_attempts_api_tracker: nil, store_encrypted_images: false)
@params = params
@service_provider = service_provider
@analytics = analytics
@readable = {}
@uuid_prefix = uuid_prefix
@irs_attempts_api_tracker = irs_attempts_api_tracker
+ @store_encrypted_images = store_encrypted_images
end
def submit
@@ -64,8 +65,8 @@ def validate_form
def post_images_to_client
response = doc_auth_client.post_images(
- front_image: front.read,
- back_image: back.read,
+ front_image: front_image_bytes,
+ back_image: back_image_bytes,
image_source: image_source,
user_uuid: user_uuid,
uuid_prefix: uuid_prefix,
@@ -79,6 +80,14 @@ def post_images_to_client
response
end
+ def front_image_bytes
+ @front_image_bytes ||= front.read
+ end
+
+ def back_image_bytes
+ @back_image_bytes ||= back.read
+ end
+
def validate_pii_from_doc(client_response)
response = Idv::DocPiiForm.new(
pii: client_response.pii_from_doc,
@@ -190,15 +199,6 @@ def as_readable(image_key)
end
end
- def track_event(event, attributes = {})
- if analytics.present?
- analytics.track_event(
- event,
- attributes,
- )
- end
- end
-
def update_analytics(client_response)
add_costs(client_response)
update_funnel(client_response)
@@ -210,6 +210,7 @@ def update_analytics(client_response)
).merge(native_camera_ab_test_data),
)
pii_from_doc = client_response.pii_from_doc || {}
+ store_encrypted_images_if_required
irs_attempts_api_tracker.idv_document_upload_submitted(
success: client_response.success?,
document_state: pii_from_doc[:state],
@@ -224,6 +225,23 @@ def update_analytics(client_response)
)
end
+ def store_encrypted_images_if_required
+ return unless store_encrypted_images?
+
+ encrypted_document_storage_writer.encrypt_and_write_document(
+ front_image: front_image_bytes,
+ back_image: back_image_bytes,
+ )
+ end
+
+ def store_encrypted_images?
+ @store_encrypted_images
+ end
+
+ def encrypted_document_storage_writer
+ @encrypted_document_storage_writer ||= EncryptedDocumentStorage::DocumentWriter.new
+ end
+
def native_camera_ab_test_data
return {} unless IdentityConfig.store.idv_native_camera_a_b_testing_enabled
diff --git a/app/forms/new_phone_form.rb b/app/forms/new_phone_form.rb
index 10f24122794..af5228822c3 100644
--- a/app/forms/new_phone_form.rb
+++ b/app/forms/new_phone_form.rb
@@ -13,6 +13,7 @@ class NewPhoneForm
validate :validate_not_voip
validate :validate_not_duplicate
validate :validate_not_premium_rate
+ validate :validate_allowed_carrier
attr_accessor :phone, :international_code, :otp_delivery_preference,
:otp_make_default_number
@@ -80,6 +81,14 @@ def validate_not_voip
end
end
+ def validate_allowed_carrier
+ return if phone.blank? || phone_info.blank?
+
+ if IdentityConfig.store.phone_carrier_registration_blocklist.include?(phone_info.carrier)
+ errors.add(:phone, I18n.t('errors.messages.phone_carrier'), type: :phone_carrier)
+ end
+ end
+
def validate_not_duplicate
current_user_phones = user.phone_configurations.map do |phone_configuration|
PhoneFormatter.format(phone_configuration.phone)
diff --git a/app/javascript/packages/build-sass/CHANGELOG.md b/app/javascript/packages/build-sass/CHANGELOG.md
new file mode 100644
index 00000000000..275d71fc1c5
--- /dev/null
+++ b/app/javascript/packages/build-sass/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 1.0.0
+
+- Initial release
diff --git a/app/javascript/packages/build-sass/LICENSE.md b/app/javascript/packages/build-sass/LICENSE.md
new file mode 100644
index 00000000000..a9eb4a921cb
--- /dev/null
+++ b/app/javascript/packages/build-sass/LICENSE.md
@@ -0,0 +1,21 @@
+# License
+
+As a work of the [United States government](https://www.usa.gov/), this project is in the public domain within the United States of America.
+
+Additionally, we waive copyright and related rights in the work worldwide through the CC0 1.0 Universal public domain dedication.
+
+## CC0 1.0 Universal Summary
+
+This is a human-readable summary of the [Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode).
+
+### No Copyright
+
+The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
+
+You can copy, modify, distribute, and perform the work, even for commercial purposes, all without asking permission.
+
+### Other Information
+
+In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights.
+
+Unless expressly stated otherwise, the person who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. When using or citing the work, you should not imply endorsement by the author or the affirmer.
diff --git a/app/javascript/packages/build-sass/README.md b/app/javascript/packages/build-sass/README.md
new file mode 100644
index 00000000000..53b6bf3ccf3
--- /dev/null
+++ b/app/javascript/packages/build-sass/README.md
@@ -0,0 +1,54 @@
+# `@18f/identity-build-sass`
+
+Stylesheet compilation utility with reasonable defaults and fast performance.
+
+Why use it?
+
+- ⚡️ **It's fast**, since it uses native Dart Sass binary through [`sass-embedded`](http://npmjs.com/package/sass-embedded), and the Rust-based [Lightning CSS](https://www.npmjs.com/package/lightningcss) for autoprefixing and minification.
+- 💻 **It includes a CLI**, so it's easy to integrate with command-based build pipelines like NPM scripts or Makefile.
+- 🚀 **It has relevant defaults**, as as to require as little additional configuration as possible.
+
+Default behavior includes:
+
+- Optimizations enabled based on the `NODE_ENV` environment variable.
+- Autoprefixer configuration based on the current project's [Browserslist](https://browsersl.ist/) configuration.
+- Automatically adds `node_modules` as a loaded path for Sass compilation.
+- Output filenames derived from the input filenames (`main.css.scss` becomes `main.css`).
+
+## Usage
+
+### CLI
+
+Invoke the included `build-sass` executable with the source files and any relevant command flags.
+
+```
+npx build-sass path/to/sass/*.css.scss --out-dir=build
+```
+
+Flags:
+
+- `--out-dir`: The output directory
+- `--watch`: Run in watch mode, recompiling files on change
+
+### API
+
+#### `buildFile`
+
+Compiles a given Sass file.
+
+```ts
+function buildFile(
+ file: string,
+ options: {
+ outDir: string,
+ optimize: boolean,
+ ...sassOptions: SassOptions<'sync'>,
+ },
+): Promise