<%= render ValidatedFieldComponent.new(
- name: :state_id_jurisdiction,
- collection: us_states_territories,
+ name: :state_id_number,
form: f,
- hint: t('in_person_proofing.form.state_id.state_id_jurisdiction_hint'),
- label: t('in_person_proofing.form.state_id.state_id_jurisdiction'),
+ hint: t('in_person_proofing.form.state_id.state_id_number_hint'),
+ input_html: { value: pii[:state_id_number] },
+ label: t('in_person_proofing.form.state_id.state_id_number'),
label_html: { class: 'usa-label' },
- prompt: t('in_person_proofing.form.state_id.state_id_jurisdiction_prompt'),
+ maxlength: 255,
required: true,
- selected: pii[:state_id_jurisdiction],
) %>
+
+ <% if IdentityConfig.store.in_person_capture_secondary_id_enabled %>
+ <%= render ValidatedFieldComponent.new(
+ name: :state_id_address1,
+ form: f,
+ input_html: { value: pii[:state_id_address1] },
+ label: t('in_person_proofing.form.state_id.address1'),
+ label_html: { class: 'usa-label' },
+ maxlength: 255,
+ required: true,
+ ) %>
-
diff --git a/app/views/session_timeout/_warning.html.erb b/app/views/session_timeout/_warning.html.erb
index 652ad083fa9..c4871223b5d 100644
--- a/app/views/session_timeout/_warning.html.erb
+++ b/app/views/session_timeout/_warning.html.erb
@@ -8,16 +8,54 @@
- <%= modal_presenter.message %>
+ <%= t(
+ # i18n-tasks-use t('notices.timeout_warning.signed_in.message_html')
+ # i18n-tasks-use t('notices.timeout_warning.partially_signed_in.message_html')
+ 'message_html',
+ scope: modal_presenter.translation_scope,
+ time_left_in_session: render(
+ CountdownComponent.new(
+ expiration: Time.zone.now,
+ start_immediately: false,
+ ),
+ ),
+ ) %>
- <%= modal_presenter.sr_message %>
+ <%= t(
+ # i18n-tasks-use t('notices.timeout_warning.signed_in.live_region_message_html')
+ # i18n-tasks-use t('notices.timeout_warning.partially_signed_in.live_region_message_html')
+ 'live_region_message_html',
+ scope: modal_presenter.translation_scope,
+ time_left_in_session: render(
+ CountdownComponent.new(
+ expiration: Time.zone.now,
+ update_interval: 30.seconds,
+ start_immediately: false,
+ ),
+ ),
+ ) %>
- <%= button_tag modal_presenter.continue,
- id: 'session-keepalive-btn',
- class: 'usa-button usa-button--big usa-button--full-width margin-bottom-2' %>
- <%= link_to modal_presenter.sign_out,
- destroy_user_session_path,
- class: 'usa-button usa-button--big usa-button--full-width usa-button--outline' %>
+ <%= render ButtonComponent.new(
+ type: :button,
+ id: 'session-keepalive-btn',
+ big: true,
+ full_width: true,
+ class: 'margin-bottom-2',
+ ).with_content(
+ # i18n-tasks-use t('notices.timeout_warning.signed_in.continue')
+ # i18n-tasks-use t('notices.timeout_warning.partially_signed_in.continue')
+ t('continue', scope: modal_presenter.translation_scope),
+ ) %>
+ <%= render ButtonComponent.new(
+ action: ->(**tag_options, &block) { link_to(destroy_user_session_path, **tag_options, &block) },
+ big: true,
+ full_width: true,
+ outline: true,
+ ).with_content(
+ # i18n-tasks-use t('notices.timeout_warning.signed_in.sign_out')
+ # i18n-tasks-use t('notices.timeout_warning.partially_signed_in.sign_out')
+ t('sign_out', scope: modal_presenter.translation_scope),
+ ) %>
<% end %>
diff --git a/config/application.yml.default b/config/application.yml.default
index 65a69014dd5..c421f959f4a 100644
--- a/config/application.yml.default
+++ b/config/application.yml.default
@@ -116,7 +116,6 @@ good_job_max_threads: 5
good_job_queues: 'default:5;low:1;*'
good_job_queue_select_limit: 5_000
gpo_designated_receiver_pii: '{}'
-gpo_personal_key_after_otp: false
hide_phone_mfa_signup: false
identity_pki_disabled: false
identity_pki_local_dev: false
diff --git a/config/initializers/job_configurations.rb b/config/initializers/job_configurations.rb
index 3685875a79e..2702485bb7a 100644
--- a/config/initializers/job_configurations.rb
+++ b/config/initializers/job_configurations.rb
@@ -1,4 +1,3 @@
-cron_1m = '* * * * *'
cron_5m = '0/5 * * * *'
cron_1h = '0 * * * *'
cron_24h = '0 0 * * *'
@@ -105,12 +104,6 @@
class: 'HeartbeatJob',
cron: cron_5m,
},
- # Queue psql stats job to GoodJob
- psql_stats_job: {
- class: 'PsqlStatsJob',
- cron: cron_1m,
- args: -> { [Time.zone.now] },
- },
# Queue usps proofing job to GoodJob
get_usps_proofing_results_job: {
class: 'GetUspsProofingResultsJob',
@@ -146,6 +139,12 @@
cron: cron_24h,
args: -> { [Time.zone.today] },
},
+ # Send Duplicate SSN report to S3
+ duplicate_ssn: {
+ class: 'Reports::DuplicateSsnReport',
+ cron: cron_24h,
+ args: -> { [Time.zone.today] },
+ },
}
end
# rubocop:enable Metrics/BlockLength
diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb
index ca87a0a353e..f8599f44a30 100644
--- a/config/initializers/redis.rb
+++ b/config/initializers/redis.rb
@@ -3,8 +3,5 @@
end
REDIS_THROTTLE_POOL = ConnectionPool.new(size: IdentityConfig.store.redis_throttle_pool_size) do
- Redis::Namespace.new(
- 'throttle',
- redis: Redis.new(url: IdentityConfig.store.redis_throttle_url),
- )
+ Redis.new(url: IdentityConfig.store.redis_throttle_url)
end
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
index 06c02d9ec19..ca4d31ebe04 100644
--- a/config/initializers/simple_form.rb
+++ b/config/initializers/simple_form.rb
@@ -77,8 +77,8 @@
# Helper proc to define different types of radio button wrappers
radio_button_builder = proc do |name, bordered|
- item_label_class = 'usa-radio__label width-full text-no-wrap' +
- (bordered ? '' : ' margin-top-0')
+ item_label_class = 'usa-radio__label width-full' +
+ (bordered ? ' text-no-wrap' : ' margin-top-0')
legend_class = 'usa-label' + (bordered ? '' : ' margin-bottom-2')
input_class = 'usa-radio__input' + (bordered ? ' usa-radio__input--bordered' : '')
@@ -98,7 +98,9 @@
cr.use :input, class: input_class
end
end
- gr.wrapper(:grid_column_gap, tag: :div, class: 'grid-col-4 tablet:grid-col-6') {}
+ if bordered
+ gr.wrapper(:grid_column_gap, tag: :div, class: 'grid-col-4 tablet:grid-col-6') {}
+ end
end
b.use :error, wrap_with: { tag: 'div', class: 'usa-error-message' }
end
diff --git a/config/locales/idv/en.yml b/config/locales/idv/en.yml
index ef8b12b0005..bf02a3e1993 100644
--- a/config/locales/idv/en.yml
+++ b/config/locales/idv/en.yml
@@ -153,7 +153,6 @@ en:
resend: Send me another letter
timeframe_html: Letters are sent the next business day via USPS First Class Mail
and
typically take 3 to 7 business days to arrive.
- mail_sent: Your letter is on its way
otp_delivery_method_description: If you entered a landline above, please select “Phone call” below.
personal_key: This is your new personal key. Write it down and keep it in a safe
place. You will need it if you ever lose your password.
diff --git a/config/locales/idv/es.yml b/config/locales/idv/es.yml
index 9ae6520090d..62e927149fa 100644
--- a/config/locales/idv/es.yml
+++ b/config/locales/idv/es.yml
@@ -163,7 +163,6 @@ es:
timeframe_html: Las cartas se envían al día siguiente por First Class Mail de
USPS y
suelen tardar entre 3 y 7 días hábiles en
llegar.
- mail_sent: Su carta está en camino
otp_delivery_method_description: Si ha introducido un teléfono fijo más arriba,
seleccione “Llamada telefónica” más abajo.
personal_key: Esta es su nueva clave personal. Escríbala y guárdela en un lugar
diff --git a/config/locales/idv/fr.yml b/config/locales/idv/fr.yml
index f34e8031dae..a7406a5ff3c 100644
--- a/config/locales/idv/fr.yml
+++ b/config/locales/idv/fr.yml
@@ -172,7 +172,6 @@ fr:
timeframe_html: Les lettres sont envoyées les jours ouvrables par courriel de
première classe de USPS et
prennent généralement entre trois à
sept jours ouvrables pour être reçues.
- mail_sent: Votre lettre est en route
otp_delivery_method_description: Si vous avez saisi une ligne fixe ci-dessus,
veuillez sélectionner « Appel téléphonique » ci-dessous.
personal_key: Il s’agit de votre nouvelle clé personnelle. Notez-la et
diff --git a/config/locales/in_person_proofing/en.yml b/config/locales/in_person_proofing/en.yml
index 35724d29f4b..b332767ad65 100644
--- a/config/locales/in_person_proofing/en.yml
+++ b/config/locales/in_person_proofing/en.yml
@@ -95,6 +95,9 @@ en:
same_address_choice_yes: This address is on my state-issued ID
state_prompt: '- Select -'
state_id:
+ address1: Address
+ address2: Address line 2 (optional)
+ city: City
date_hint:
day: 'Example: 28'
month: 'Example: 4'
@@ -112,11 +115,15 @@ en:
missing_month_day_year: Enter a date of birth
range_min_age: You must be over 13 years of age to use %{app_name}
range_overflow: Enter a date that is in the past
+ same_address_as_id: Is your current residential address listed on your state-issued ID?
+ same_address_as_id_no: No, my current residential address is not listed on my state-issued ID
+ same_address_as_id_yes: Yes, my current residential address is listed on my state-issued ID
state_id_jurisdiction: State
state_id_jurisdiction_hint: Select the state shown on your ID
state_id_jurisdiction_prompt: '- Select -'
state_id_number: ID number
state_id_number_hint: May include letters and numbers
+ zipcode: ZIP Code
headings:
address: Enter your current address
barcode: You’re ready to verify your identity in person
@@ -126,7 +133,7 @@ en:
po_search:
location: Find a participating Post Office
prepare: Verify your identity in person
- state_id: Enter the information on your ID
+ state_id_milestone_2: Enter the information on your state-issued ID
switch_back: Switch back to your computer to prepare to verify your identity in person
update_address: Update your current address
update_state_id: Update the information on your ID
diff --git a/config/locales/in_person_proofing/es.yml b/config/locales/in_person_proofing/es.yml
index 03f7fa8d6d2..28278be9204 100644
--- a/config/locales/in_person_proofing/es.yml
+++ b/config/locales/in_person_proofing/es.yml
@@ -106,6 +106,9 @@ es:
same_address_choice_yes: Esta dirección aparece en mi cédula de identidad emitida por el estado
state_prompt: '- Seleccione -'
state_id:
+ address1: Dirección
+ address2: Línea de dirección 2 (opcional)
+ city: Ciudad
date_hint:
day: 'Ejemplo: 28'
month: 'Ejemplo: 4'
@@ -124,11 +127,18 @@ es:
missing_month_day_year: Introduce una fecha de nacimiento
range_min_age: Debe tener más de 13 años para usar %{app_name}
range_overflow: Ingrese una fecha que esté en el pasado
+ same_address_as_id: ¿Tu domicilio actual aparece en tu identificación emitida
+ por el estado?
+ same_address_as_id_no: No, mi domicilio actual no aparece en mi identificación
+ emitida por el estado.
+ same_address_as_id_yes: Sí, mi domicilio actual aparece en mi identificación
+ emitida por el estado
state_id_jurisdiction: Estado
state_id_jurisdiction_hint: Seleccione el estado que aparece en su cédula
state_id_jurisdiction_prompt: '- Seleccione -'
state_id_number: Número de cédula
state_id_number_hint: Puede incluir letras y números
+ zipcode: Código postal
headings:
address: Ingrese su dirección actual
barcode: Está listo para verificar su identidad en persona
@@ -138,7 +148,7 @@ es:
po_search:
location: Encuentre una oficina de correos participante
prepare: Verifique su identidad en persona
- state_id: Ingrese la información de su cédula
+ state_id_milestone_2: Ingresa la información de tu identificación emitida por el estado
switch_back: Vuelva a su computadora para prepararse para verificar su identidad
en persona
update_address: Actualizar su dirección actual
diff --git a/config/locales/in_person_proofing/fr.yml b/config/locales/in_person_proofing/fr.yml
index e2b5b154caa..d54eb1ceb35 100644
--- a/config/locales/in_person_proofing/fr.yml
+++ b/config/locales/in_person_proofing/fr.yml
@@ -108,6 +108,9 @@ fr:
same_address_choice_yes: Cette adresse figure sur mon document d’identité nationale
state_prompt: '- Sélectionnez -'
state_id:
+ address1: Adresse
+ address2: Adresse Ligne 2 (optional)
+ city: Ville
date_hint:
day: 'Exemple: 28'
month: 'Exemple: 4'
@@ -126,11 +129,18 @@ fr:
missing_month_day_year: Entrez une date de naissance
range_min_age: Vous devez avoir plus de 13 ans pour utiliser %{app_name}
range_overflow: Entrez une date qui est dans le passé
+ same_address_as_id: L’adresse de votre domicile actuel figure-t-elle sur votre
+ carte d’identité délivrée par l’État?
+ same_address_as_id_no: Non, l’adresse de mon domicile actuel ne figure pas sur
+ ma carte d’identité délivrée par l’État
+ same_address_as_id_yes: Oui, l’adresse de mon domicile actuel figure sur ma
+ carte d’identité délivrée par l’État
state_id_jurisdiction: État
state_id_jurisdiction_hint: Sélectionnez l’État figurant sur votre document d’identité
state_id_jurisdiction_prompt: '- Sélectionnez -'
state_id_number: Numéro d’identification
state_id_number_hint: Peut comprendre des lettres et des chiffres
+ zipcode: Code postal
headings:
address: Entrez votre adresse actuelle
barcode: Vous êtes prêt à vérifier votre identité en personne
@@ -140,7 +150,8 @@ fr:
po_search:
location: Trouver un bureau de poste participant
prepare: Vérifiez votre identité en personne
- state_id: Saisissez les informations figurant sur votre document d’identité
+ state_id_milestone_2: Saisissez les informations figurant sur votre carte
+ d’identité délivrée par l’État
switch_back: Retournez sur votre ordinateur pour vous préparer à vérifier votre
identité en personne
update_address: Mettre à jour votre adresse actuelle
diff --git a/config/locales/notices/en.yml b/config/locales/notices/en.yml
index eb8f8ee4e82..1d4e0b82ee8 100644
--- a/config/locales/notices/en.yml
+++ b/config/locales/notices/en.yml
@@ -47,18 +47,20 @@ en:
timeout_warning:
partially_signed_in:
continue: Continue sign in
+ live_region_message_html: You will be signed out in %{time_left_in_session}.
+ Select “keep me signed in” to stay logged in. Select “sign me out” to
+ sign out.
message_html: For your security, in %{time_left_in_session} we will cancel your
sign in.
sign_out: Cancel sign in
- sr_message_html: You will be signed out in %{time_left_in_session}. Select “keep
- me signed in” to stay logged in. Select “sign me out” to sign out.
signed_in:
continue: Keep me signed in
+ live_region_message_html: You will be signed out in %{time_left_in_session}.
+ Select “keep me signed in” to stay logged in. Select “sign me out” to
+ sign out.
message_html: For your security, we will sign you out in %{time_left_in_session}
unless you tell us otherwise.
sign_out: Sign me out
- sr_message_html: You will be signed out in %{time_left_in_session}. Select “keep
- me signed in” to stay logged in. Select “sign me out” to sign out.
totp_configured: An authentication app was added to your account.
totp_disabled: Your authentication app was deleted from your account.
use_diff_email:
diff --git a/config/locales/notices/es.yml b/config/locales/notices/es.yml
index 04550a8c2b3..8ace2e6f115 100644
--- a/config/locales/notices/es.yml
+++ b/config/locales/notices/es.yml
@@ -49,19 +49,19 @@ es:
timeout_warning:
partially_signed_in:
continue: Continuar el inicio de sesión
+ live_region_message_html: Tu sesión se cerrará en %{time_left_in_session}.
+ Selecciona “seguir conectado” para mantener tu sesión activa.
+ Seleccione “desconécteme” para cerrar la sesión.
message_html: Para su seguridad, en %{time_left_in_session} cancelaremos su acceso.
sign_out: Cancelar el inicio de sesión
- sr_message_html: Tu sesión se cerrará en %{time_left_in_session}. Selecciona
- “seguir conectado” para mantener tu sesión activa. Seleccione
- “desconécteme” para cerrar la sesión.
signed_in:
continue: Manténgame conectado
+ live_region_message_html: Tu sesión se cerrará en %{time_left_in_session}.
+ Selecciona “seguir conectado” para mantener tu sesión activa.
+ Seleccione “desconécteme” para cerrar la sesión.
message_html: Para su seguridad, terminaremos su sesión en
%{time_left_in_session} a menos que nos indique lo contrario.
sign_out: Desconécteme
- sr_message_html: Tu sesión se cerrará en %{time_left_in_session}. Selecciona
- “seguir conectado” para mantener tu sesión activa. Seleccione
- “desconécteme” para cerrar la sesión.
totp_configured: Una aplicación de autenticación fue agregada a tu cuenta.
totp_disabled: Tu aplicación de autenticación fue eliminada de tu cuenta.
use_diff_email:
diff --git a/config/locales/notices/fr.yml b/config/locales/notices/fr.yml
index 30fa3da0fea..42e0db9d12e 100644
--- a/config/locales/notices/fr.yml
+++ b/config/locales/notices/fr.yml
@@ -49,20 +49,20 @@ fr:
timeout_warning:
partially_signed_in:
continue: Continuer la connexion
+ live_region_message_html: Vous serez déconnecté dans %{time_left_in_session}.
+ Sélectionnez « garder ma connexion » pour rester connecté.
+ Sélectionnez « déconnectez-moi » pour vous déconnecter.
message_html: Pour votre sécurité, nous annulerons votre connexion dans
%{time_left_in_session}.
sign_out: Annuler la connexion
- sr_message_html: Vous serez déconnecté dans %{time_left_in_session}.
- Sélectionnez « garder ma connexion » pour rester connecté.
- Sélectionnez « déconnectez-moi » pour vous déconnecter.
signed_in:
continue: Gardez ma connexion active
+ live_region_message_html: Vous serez déconnecté dans %{time_left_in_session}.
+ Sélectionnez « garder ma connexion » pour rester connecté.
+ Sélectionnez « déconnectez-moi » pour vous déconnecter.
message_html: Pour votre sécurité, nous vous déconnecterons dans
%{time_left_in_session}, sauf en cas d’avis contraire de votre part.
sign_out: Déconnectez-moi
- sr_message_html: Vous serez déconnecté dans %{time_left_in_session}.
- Sélectionnez « garder ma connexion » pour rester connecté.
- Sélectionnez « déconnectez-moi » pour vous déconnecter.
totp_configured: Une application d’authentification a été ajoutée à votre compte.
totp_disabled: Votre application d’authentification a été supprimée de votre compte.
use_diff_email:
diff --git a/config/routes.rb b/config/routes.rb
index c79649eaadd..b4d4e9db409 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -251,7 +251,6 @@
get '/second_mfa_setup' => 'users/mfa_selection#index'
patch '/second_mfa_setup' => 'users/mfa_selection#update'
get '/phone_setup' => 'users/phone_setup#index'
- patch '/phone_setup' => 'users/phone_setup#create' # TODO: Remove after next deploy
post '/phone_setup' => 'users/phone_setup#create'
get '/users/two_factor_authentication' => 'users/two_factor_authentication#show',
as: :user_two_factor_authentication # route name is used by two_factor_authentication gem
diff --git a/db/primary_migrate/20230309201053_add_sp_issuer_field_to_account_reset_request.rb b/db/primary_migrate/20230309201053_add_sp_issuer_field_to_account_reset_request.rb
new file mode 100644
index 00000000000..44c34f3aed9
--- /dev/null
+++ b/db/primary_migrate/20230309201053_add_sp_issuer_field_to_account_reset_request.rb
@@ -0,0 +1,5 @@
+class AddSpIssuerFieldToAccountResetRequest < ActiveRecord::Migration[7.0]
+ def change
+ add_column :account_reset_requests, :requesting_issuer, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 7a161d48c19..2edc4ee8038 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.0].define(version: 2023_03_07_203559) do
+ActiveRecord::Schema[7.0].define(version: 2023_03_09_201053) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "pgcrypto"
@@ -26,6 +26,7 @@
t.string "granted_token"
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
+ t.string "requesting_issuer"
t.index ["cancelled_at", "granted_at", "requested_at"], name: "index_account_reset_requests_on_timestamps"
t.index ["granted_token"], name: "index_account_reset_requests_on_granted_token", unique: true
t.index ["request_token"], name: "index_account_reset_requests_on_request_token", unique: true
diff --git a/lib/identity_config.rb b/lib/identity_config.rb
index 1f70d93cd85..3b100b9cb70 100644
--- a/lib/identity_config.rb
+++ b/lib/identity_config.rb
@@ -193,7 +193,6 @@ def self.build_store(config_map)
config.add(:good_job_queues, type: :string)
config.add(:good_job_queue_select_limit, type: :integer)
config.add(:gpo_designated_receiver_pii, type: :json, options: { symbolize_names: true })
- config.add(:gpo_personal_key_after_otp, type: :boolean)
config.add(:hide_phone_mfa_signup, type: :boolean)
config.add(:hmac_fingerprinter_key, type: :string)
config.add(:hmac_fingerprinter_key_queue, type: :json)
diff --git a/package.json b/package.json
index 4333a229151..b20906934eb 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,7 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"source-map-loader": "^4.0.0",
- "webpack": "^5.74.0",
+ "webpack": "^5.76.1",
"webpack-assets-manifest": "^5.1.0",
"webpack-cli": "^4.10.0",
"zxcvbn": "4.4.2"
@@ -68,7 +68,7 @@
"dirty-chai": "^2.0.1",
"dom-accessibility-api": "^0.5.14",
"eslint": "^8.24.0",
- "eslint-plugin-import": "^2.26.0",
+ "eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-mocha": "^10.1.0",
"eslint-plugin-prettier": "^4.2.1",
diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb
index 8e0ca01ad78..1c22945b5c5 100644
--- a/spec/controllers/account_reset/delete_account_controller_spec.rb
+++ b/spec/controllers/account_reset/delete_account_controller_spec.rb
@@ -34,26 +34,6 @@
expect(response).to redirect_to account_reset_confirm_delete_account_url
end
- it 'logs a good token to the attempts api' do
- user = create(:user, :signed_up, :with_backup_code)
- create(:phone_configuration, user: user, phone: Faker::PhoneNumber.cell_phone)
- create_list(:webauthn_configuration, 2, user: user)
- create_account_reset_request_for(user)
- grant_request(user)
-
- session[:granted_token] = AccountResetRequest.first.granted_token
- stub_attempts_tracker
-
- expect(@irs_attempts_api_tracker).to receive(:account_reset_account_deleted).with(
- success: true,
- failure_reason: nil,
- )
-
- delete :delete
-
- expect(response).to redirect_to account_reset_confirm_delete_account_url
- end
-
it 'redirects to root if the token does not match one in the DB' do
session[:granted_token] = 'foo'
stub_analytics
@@ -74,18 +54,6 @@
expect(flash[:error]).to eq(invalid_token_message)
end
- it 'logs an error in irs attempts tracker' do
- session[:granted_token] = 'foo'
- stub_attempts_tracker
-
- expect(@irs_attempts_api_tracker).to receive(:account_reset_account_deleted).with(
- success: false,
- failure_reason: invalid_token_error,
- )
-
- delete :delete
- end
-
it 'displays a flash and redirects to root if the token is missing' do
stub_analytics
properties = {
diff --git a/spec/controllers/concerns/idv/step_indicator_concern_spec.rb b/spec/controllers/concerns/idv/step_indicator_concern_spec.rb
index cdfb9f763b9..622bd9c8d24 100644
--- a/spec/controllers/concerns/idv/step_indicator_concern_spec.rb
+++ b/spec/controllers/concerns/idv/step_indicator_concern_spec.rb
@@ -11,36 +11,82 @@
before { stub_sign_in(user) }
describe '#step_indicator_steps' do
+ def force_gpo
+ idv_session = instance_double(Idv::Session)
+ allow(idv_session).to receive(:method_missing).
+ with(:address_verification_mechanism).
+ and_return('gpo')
+ allow(controller).to receive(:idv_session).and_return(idv_session)
+ end
+
subject(:steps) { controller.step_indicator_steps }
- it 'returns doc auth steps' do
- expect(steps).to eq Idv::Flows::DocAuthFlow::STEP_INDICATOR_STEPS
- end
+ context 'without an in-person proofing component' do
+ let(:doc_auth_step_indicator_steps) do
+ [
+ { name: :getting_started },
+ { name: :verify_id },
+ { name: :verify_info },
+ { name: :verify_phone_or_address },
+ { name: :secure_account },
+ ]
+ end
- context 'with pending profile' do
- let(:profile) { create(:profile, deactivation_reason: :gpo_verification_pending) }
+ let(:doc_auth_step_indicator_steps_gpo) do
+ [
+ { name: :getting_started },
+ { name: :verify_id },
+ { name: :verify_info },
+ { name: :get_a_letter },
+ { name: :secure_account },
+ ]
+ end
- it 'returns doc auth gpo steps' do
- expect(steps).to eq Idv::Flows::DocAuthFlow::STEP_INDICATOR_STEPS_GPO
+ context 'without a pending profile' do
+ it 'returns doc auth steps' do
+ expect(steps).to eq doc_auth_step_indicator_steps
+ end
end
- end
- context 'with gpo address verification method' do
- before do
- idv_session = instance_double(Idv::Session)
- allow(idv_session).to receive(:method_missing).
- with(:address_verification_mechanism).
- and_return('gpo')
- allow(controller).to receive(:idv_session).and_return(idv_session)
+ context 'with a pending profile' do
+ let(:profile) { create(:profile, deactivation_reason: :gpo_verification_pending) }
+
+ it 'returns doc auth gpo steps' do
+ expect(steps).to eq doc_auth_step_indicator_steps_gpo
+ end
end
- it 'returns doc auth gpo steps' do
- expect(steps).to eq Idv::Flows::DocAuthFlow::STEP_INDICATOR_STEPS_GPO
+ context 'with gpo address verification method' do
+ before { force_gpo }
+
+ it 'returns doc auth gpo steps' do
+ expect(steps).to eq doc_auth_step_indicator_steps_gpo
+ end
end
end
context 'with in person proofing component' do
- context 'with proofing component via pending profile' do
+ let(:in_person_step_indicator_steps) do
+ [
+ { name: :find_a_post_office },
+ { name: :verify_info },
+ { name: :verify_phone_or_address },
+ { name: :secure_account },
+ { name: :go_to_the_post_office },
+ ]
+ end
+
+ let(:in_person_step_indicator_steps_gpo) do
+ [
+ { name: :find_a_post_office },
+ { name: :verify_info },
+ { name: :secure_account },
+ { name: :get_a_letter },
+ { name: :go_to_the_post_office },
+ ]
+ end
+
+ context 'via pending profile' do
let(:profile) do
create(
:profile,
@@ -50,30 +96,24 @@
end
it 'returns in person gpo steps' do
- expect(steps).to eq Idv::Flows::InPersonFlow::STEP_INDICATOR_STEPS_GPO
+ expect(steps).to eq in_person_step_indicator_steps_gpo
end
end
- context 'with proofing component via current idv session' do
+ context 'via current idv session' do
before do
ProofingComponent.create(user: user, document_check: Idp::Constants::Vendors::USPS)
end
it 'returns in person steps' do
- expect(steps).to eq Idv::Flows::InPersonFlow::STEP_INDICATOR_STEPS
+ expect(steps).to eq in_person_step_indicator_steps
end
context 'with gpo address verification method' do
- before do
- idv_session = instance_double(Idv::Session)
- allow(idv_session).to receive(:method_missing).
- with(:address_verification_mechanism).
- and_return('gpo')
- allow(controller).to receive(:idv_session).and_return(idv_session)
- end
+ before { force_gpo }
it 'returns in person gpo steps' do
- expect(steps).to eq Idv::Flows::InPersonFlow::STEP_INDICATOR_STEPS_GPO
+ expect(steps).to eq in_person_step_indicator_steps_gpo
end
end
end
diff --git a/spec/controllers/concerns/idv_step_concern_spec.rb b/spec/controllers/concerns/idv_step_concern_spec.rb
index e60cc8692e9..9a4384acae9 100644
--- a/spec/controllers/concerns/idv_step_concern_spec.rb
+++ b/spec/controllers/concerns/idv_step_concern_spec.rb
@@ -128,8 +128,7 @@ def show
context 'the user has completed the verify info step' do
it 'does not redirect and renders the view' do
- idv_session.profile_confirmation = true
- idv_session.resolution_successful = 'phone'
+ idv_session.resolution_successful = true
get :show
@@ -140,7 +139,6 @@ def show
context 'the user has not completed the verify info step' do
it 'redirects to the remote verify info step' do
- idv_session.profile_confirmation = nil
idv_session.resolution_successful = nil
get :show
@@ -151,7 +149,6 @@ def show
context 'the user has not completed the verify info step with an in-person enrollment' do
it 'redirects to the in-person verify info step' do
- idv_session.profile_confirmation = nil
idv_session.resolution_successful = nil
ProofingComponent.find_or_create_by(
diff --git a/spec/controllers/idv/gpo_verify_controller_spec.rb b/spec/controllers/idv/gpo_verify_controller_spec.rb
index 5dabc273dea..45c2c356f39 100644
--- a/spec/controllers/idv/gpo_verify_controller_spec.rb
+++ b/spec/controllers/idv/gpo_verify_controller_spec.rb
@@ -125,14 +125,6 @@
disavowal_event_count = user.events.where(event_type: :account_verified, ip: '0.0.0.0').
where.not(disavowal_token_fingerprint: nil).count
expect(disavowal_event_count).to eq 1
- expect(response).to redirect_to(sign_up_completed_url)
- end
-
- it 'redirects to the personal key page if new gpo flow is enabled' do
- allow(IdentityConfig.store).to receive(:gpo_personal_key_after_otp).and_return(true)
-
- action
-
expect(response).to redirect_to(idv_personal_key_url)
end
@@ -205,7 +197,7 @@
disavowal_event_count = user.events.where(event_type: :account_verified, ip: '0.0.0.0').
where.not(disavowal_token_fingerprint: nil).count
expect(disavowal_event_count).to eq 1
- expect(response).to redirect_to(sign_up_completed_url)
+ expect(response).to redirect_to(idv_personal_key_url)
end
end
end
diff --git a/spec/controllers/idv/personal_key_controller_spec.rb b/spec/controllers/idv/personal_key_controller_spec.rb
index a01e4a1e972..513533f31a0 100644
--- a/spec/controllers/idv/personal_key_controller_spec.rb
+++ b/spec/controllers/idv/personal_key_controller_spec.rb
@@ -131,14 +131,7 @@ def index
subject.idv_session.address_verification_mechanism = 'gpo'
end
- it 'sets flash.now[:success]' do
- get :show
- expect(flash[:success]).to eq t('idv.messages.mail_sent')
- end
-
it 'does not show a flash in new gpo flow' do
- allow(IdentityConfig.store).to receive(:gpo_personal_key_after_otp).and_return(true)
-
get :show
expect(flash[:success]).to eq nil
end
@@ -206,8 +199,6 @@ def index
context 'with gpo personal key after verification' do
it 'redirects to sign up completed_url for a sp' do
- allow(IdentityConfig.store).to receive(:gpo_personal_key_after_otp).
- and_return(true)
allow(subject).to receive(:pending_profile?).and_return(false)
subject.session[:sp] = { ial2: true }
diff --git a/spec/controllers/idv/phone_controller_spec.rb b/spec/controllers/idv/phone_controller_spec.rb
index 8c60e77ca28..7fb7a9b8525 100644
--- a/spec/controllers/idv/phone_controller_spec.rb
+++ b/spec/controllers/idv/phone_controller_spec.rb
@@ -78,7 +78,6 @@
context 'when the user has not finished the verify step' do
before do
subject.idv_session.applicant = nil
- subject.idv_session.profile_confirmation = nil
subject.idv_session.resolution_successful = nil
allow(controller).to receive(:confirm_idv_applicant_created).and_call_original
diff --git a/spec/controllers/idv/review_controller_spec.rb b/spec/controllers/idv/review_controller_spec.rb
index 80e1b1a203a..bf0c77b6ab7 100644
--- a/spec/controllers/idv/review_controller_spec.rb
+++ b/spec/controllers/idv/review_controller_spec.rb
@@ -18,8 +18,7 @@
current_user: user,
service_provider: nil,
)
- idv_session.profile_confirmation = true
- idv_session.resolution_successful = 'phone'
+ idv_session.resolution_successful = true
idv_session.vendor_phone_confirmation = true
idv_session.user_phone_confirmation = true
idv_session.applicant = applicant.with_indifferent_access
@@ -610,7 +609,6 @@ def show
end
it 'redirects to come back later page' do
- allow(IdentityConfig.store).to receive(:gpo_personal_key_after_otp).and_return(true)
put :create, params: { user: { password: ControllerHelper::VALID_PASSWORD } }
expect(response).to redirect_to idv_come_back_later_url
diff --git a/spec/controllers/idv/session_errors_controller_spec.rb b/spec/controllers/idv/session_errors_controller_spec.rb
index 60ba2af7959..0431345e16f 100644
--- a/spec/controllers/idv/session_errors_controller_spec.rb
+++ b/spec/controllers/idv/session_errors_controller_spec.rb
@@ -34,7 +34,7 @@
end
context 'the user is authenticated and has confirmed their profile' do
- let(:idv_session_profile_confirmation) { true }
+ let(:verify_info_step_complete) { true }
let(:user) { build(:user) }
it 'redirects to the phone url' do
@@ -102,12 +102,12 @@
describe Idv::SessionErrorsController do
let(:idv_session) { double }
- let(:idv_session_profile_confirmation) { false }
+ let(:verify_info_step_complete) { false }
let(:user) { nil }
before do
- allow(idv_session).to receive(:profile_confirmation).
- and_return(idv_session_profile_confirmation)
+ allow(idv_session).to receive(:verify_info_step_complete?).
+ and_return(verify_info_step_complete)
allow(controller).to receive(:idv_session).and_return(idv_session)
stub_sign_in(user) if user
stub_analytics
diff --git a/spec/controllers/idv/ssn_controller_spec.rb b/spec/controllers/idv/ssn_controller_spec.rb
index 1d2ec862b51..19a9a49da96 100644
--- a/spec/controllers/idv/ssn_controller_spec.rb
+++ b/spec/controllers/idv/ssn_controller_spec.rb
@@ -110,6 +110,14 @@
expect(flow_session['pii_from_doc'][:ssn]).to eq(ssn)
end
+ it 'redirects to address controller for Puerto Rico addresses' do
+ flow_session['pii_from_doc'][:state] = 'PR'
+
+ put :update, params: params
+
+ expect(response).to redirect_to(idv_address_url)
+ end
+
it 'sends analytics_submitted event with correct step count' do
get :show
put :update, params: params
diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb
index ef51bd651bd..32718d46f86 100644
--- a/spec/controllers/idv/verify_info_controller_spec.rb
+++ b/spec/controllers/idv/verify_info_controller_spec.rb
@@ -112,7 +112,7 @@
context 'when the user has already verified their info' do
it 'redirects to the review controller' do
- controller.idv_session.profile_confirmation = true
+ controller.idv_session.resolution_successful = true
get :show
diff --git a/spec/features/account_reset/delete_account_spec.rb b/spec/features/account_reset/delete_account_spec.rb
index 61d0d786310..cb0f3ef5e53 100644
--- a/spec/features/account_reset/delete_account_spec.rb
+++ b/spec/features/account_reset/delete_account_spec.rb
@@ -2,11 +2,23 @@
describe 'Account Reset Request: Delete Account', email: true do
include PushNotificationsHelper
+ include OidcAuthHelper
+ include IrsAttemptsApiTrackingHelper
let(:user) { create(:user, :signed_up) }
let(:user_email) { user.email_addresses.first.email }
let(:push_notification_url) { 'http://localhost/push_notifications' }
+ let(:service_provider) do
+ create(
+ :service_provider,
+ active: true,
+ redirect_uris: ['http://localhost:7654/auth/result'],
+ ial: 2,
+ irs_attempts_api_enabled: true,
+ )
+ end
+
context 'as an IAL1 user' do
it 'allows the user to delete their account after 24 hours' do
signin(user_email, user.password)
@@ -173,4 +185,92 @@
expect(page).to have_current_path(new_user_session_path)
end
end
+
+ context 'logs IRS attempts api events' do
+ before do
+ allow(IdentityConfig.store).to receive(:irs_attempt_api_enabled).and_return(true)
+ mock_irs_attempts_api_encryption_key
+ end
+
+ it 'allows the user to delete their account after 24 hours and log irs event' do
+ visit_idp_from_ial1_oidc_sp(
+ client_id: service_provider.issuer,
+ )
+
+ signin(user_email, user.password)
+ click_link t('two_factor_authentication.login_options_link_text')
+ click_link t('two_factor_authentication.account_reset.link')
+ expect(page).
+ to have_content strip_tags(
+ t('account_reset.recovery_options.try_method_again'),
+ )
+ click_link t('account_reset.request.yes_continue')
+ expect(page).
+ to have_content strip_tags(
+ t('account_reset.request.delete_account'),
+ )
+ click_button t('account_reset.request.yes_continue')
+
+ expect(page).
+ to have_content strip_tags(
+ t('account_reset.confirm_request.instructions_start'),
+ )
+ expect(page).
+ to have_content user_email
+ expect(page).
+ to have_content strip_tags(
+ t('account_reset.confirm_request.instructions_end'),
+ )
+ expect(page).to have_content t('account_reset.confirm_request.security_note')
+ expect(page).to have_content t('account_reset.confirm_request.close_window')
+
+ reset_email
+ set_new_browser_session
+ events = irs_attempts_api_tracked_events(timestamp: Time.zone.now)
+ expected_event_types = %w[mfa-login-phone-otp-sent login-email-and-password-auth
+ account-reset-request-submitted]
+ received_event_types = events.map(&:event_type)
+
+ expect(events.count).to eq received_event_types.count
+ expect(received_event_types).to match_array(expected_event_types)
+
+ travel_to(Time.zone.now + 2.days + 1.second) do
+ AccountReset::GrantRequestsAndSendEmails.new.perform(Time.zone.today)
+ open_last_email
+ click_email_link_matching(/delete_account\?token/)
+
+ expect(page).to have_content(t('account_reset.delete_account.title'))
+ expect(page).to have_current_path(account_reset_delete_account_path)
+
+ click_button t('account_reset.request.yes_continue')
+
+ expect(page).to have_content(
+ strip_tags(
+ t(
+ 'account_reset.confirm_delete_account.info_html',
+ email: user_email,
+ link: t('account_reset.confirm_delete_account.link_text'),
+ ),
+ ),
+ )
+ expect(page).to have_current_path(account_reset_confirm_delete_account_path)
+ expect(User.where(id: user.id)).to be_empty
+ deleted_user = DeletedUser.find_by(user_id: user.id)
+ expect(deleted_user.user_id).to eq(user.id)
+ expect(deleted_user.uuid).to eq(user.uuid)
+ expect(last_email.subject).to eq t('user_mailer.account_reset_complete.subject')
+
+ click_link t('account_reset.confirm_delete_account.link_text')
+
+ expect(page).to have_current_path(sign_up_email_path)
+
+ events = irs_attempts_api_tracked_events(timestamp: Time.zone.now)
+ expected_event_types = %w[account-reset-account-deleted]
+ received_event_types = events.map(&:event_type)
+
+ expect(events.count).to eq received_event_types.count
+ expect(received_event_types).to match_array(expected_event_types)
+ end
+ end
+ end
end
diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb
index 9496457689e..eadab798730 100644
--- a/spec/features/idv/analytics_spec.rb
+++ b/spec/features/idv/analytics_spec.rb
@@ -69,9 +69,6 @@
'IdV: USPS address letter enqueued' => { enqueued_at: Time.zone.now.utc, resend: false, proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' } },
'IdV: review complete' => { success: true, proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' }, fraud_review_pending: false, fraud_rejection: false, deactivation_reason: 'gpo_verification_pending' },
'IdV: final resolution' => { success: true, proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' }, fraud_review_pending: false, fraud_rejection: false, deactivation_reason: 'gpo_verification_pending' },
- 'IdV: personal key visited' => { address_verification_method: 'gpo', proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' } },
- 'IdV: personal key acknowledgment toggled' => { checked: true, proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' } },
- 'IdV: personal key submitted' => { address_verification_method: 'gpo', proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' }, fraud_review_pending: false, fraud_rejection: false, deactivation_reason: 'gpo_verification_pending' },
'IdV: come back later visited' => { proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' } },
}
end
@@ -185,7 +182,6 @@
enter_gpo_flow
gpo_step
complete_review_step(user)
- acknowledge_and_confirm_personal_key
end
it 'records all of the events' do
diff --git a/spec/features/idv/clearing_and_restarting_spec.rb b/spec/features/idv/clearing_and_restarting_spec.rb
index e0ea19bdbc0..6de48def5ba 100644
--- a/spec/features/idv/clearing_and_restarting_spec.rb
+++ b/spec/features/idv/clearing_and_restarting_spec.rb
@@ -9,7 +9,6 @@
before do
start_idv_from_sp
complete_idv_steps_with_gpo_before_confirmation_step(user)
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
end
context 'before signing out' do
diff --git a/spec/features/idv/doc_auth/address_step_spec.rb b/spec/features/idv/doc_auth/address_step_spec.rb
index fffcb328841..b55352e51b2 100644
--- a/spec/features/idv/doc_auth/address_step_spec.rb
+++ b/spec/features/idv/doc_auth/address_step_spec.rb
@@ -48,12 +48,16 @@
complete_doc_auth_steps_before_document_capture_step
complete_document_capture_step_with_yml('spec/fixtures/puerto_rico_resident.yml')
complete_ssn_step
- click_button t('idv.buttons.change_address_label')
end
it 'shows address guidance and hint text' do
+ expect(page).to have_current_path(idv_address_url)
expect(page.body).to include(t('doc_auth.info.address_guidance_puerto_rico_html'))
expect(page).to have_content(t('forms.example'))
+ fill_in 'idv_form_address1', with: '123 Calle Carlos'
+ fill_in 'idv_form_address2', with: 'URB Las Gladiolas'
+ click_button t('forms.buttons.submit.update')
+ expect(page).to have_current_path(idv_verify_info_path)
end
end
end
diff --git a/spec/features/idv/in_person_spec.rb b/spec/features/idv/in_person_spec.rb
index 40e8e4e86aa..4b5af8607eb 100644
--- a/spec/features/idv/in_person_spec.rb
+++ b/spec/features/idv/in_person_spec.rb
@@ -8,6 +8,8 @@
before do
allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true)
+ allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled).
+ and_return(false)
end
context 'ThreatMetrix review pending' do
@@ -45,7 +47,7 @@
expect(page).to have_content(t('headings.verify'))
expect(page).to have_text(InPersonHelper::GOOD_FIRST_NAME)
expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME)
- expect(page).to have_text(InPersonHelper::GOOD_DOB)
+ expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT)
expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER)
expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1)
expect(page).to have_text(InPersonHelper::GOOD_CITY)
@@ -132,8 +134,10 @@
complete_prepare_step(user)
# state ID page
- expect_in_person_step_indicator_current_step(t('step_indicator.flows.idv.verify_info'))
- expect(page).to have_content(t('in_person_proofing.headings.state_id'))
+ expect_in_person_step_indicator_current_step(
+ t('step_indicator.flows.idv.verify_info'),
+ )
+ expect(page).to have_content(t('in_person_proofing.headings.state_id_milestone_2'))
complete_state_id_step(user)
# address page
@@ -152,7 +156,7 @@
expect(page).to have_content(t('headings.verify'))
expect(page).to have_text(InPersonHelper::GOOD_FIRST_NAME)
expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME)
- expect(page).to have_text(InPersonHelper::GOOD_DOB)
+ expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT)
expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER)
expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1)
expect(page).to have_text(InPersonHelper::GOOD_CITY)
@@ -169,6 +173,7 @@
# click update address button
click_button t('idv.buttons.change_address_label')
expect(page).to have_content(t('in_person_proofing.headings.update_address'))
+ choose t('in_person_proofing.form.address.same_address_choice_yes')
click_button t('forms.buttons.submit.update')
expect(page).to have_content(t('headings.verify'))
@@ -375,8 +380,6 @@
click_on t('idv.buttons.mail.send')
expect_in_person_gpo_step_indicator_current_step(t('step_indicator.flows.idv.secure_account'))
complete_review_step
- expect_in_person_gpo_step_indicator_current_step(t('step_indicator.flows.idv.secure_account'))
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
expect_in_person_gpo_step_indicator_current_step(t('step_indicator.flows.idv.get_a_letter'))
expect(page).to have_content(t('idv.titles.come_back_later'))
@@ -403,7 +406,6 @@
click_on t('idv.troubleshooting.options.verify_by_mail')
click_on t('idv.buttons.mail.send')
complete_review_step
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
click_idv_continue
click_on t('account.index.verification.reactivate_button')
click_on t('idv.messages.clear_and_start_over')
@@ -483,4 +485,28 @@
expect(page).to have_current_path(idv_in_person_step_path(step: :ssn), wait: 10)
end
end
+
+ context 'validate_id_and_residential_addresses feature flag enabled', allow_browser_log: true do
+ let(:user) { user_with_2fa }
+
+ before do
+ allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled).
+ and_return(true)
+ end
+
+ it 'captures the address, address line 2, city, state and zip code' do
+ sign_in_and_2fa_user(user)
+ begin_in_person_proofing(user)
+ search_for_post_office
+
+ # location page
+ location = page.find_all('.location-collection-item')[1]
+ location.click_button(t('in_person_proofing.body.location.location_button'))
+
+ # prepare page
+ complete_prepare_step(user)
+
+ complete_state_id_step(user, same_address_as_id: false, include_address: true)
+ end
+ end
end
diff --git a/spec/features/idv/steps/confirmation_step_spec.rb b/spec/features/idv/steps/confirmation_step_spec.rb
index 0052d2d5733..b1da498fe6f 100644
--- a/spec/features/idv/steps/confirmation_step_spec.rb
+++ b/spec/features/idv/steps/confirmation_step_spec.rb
@@ -31,8 +31,7 @@
let(:address_verification_mechanism) { :gpo }
it 'shows status content for gpo verification progress' do
- expect(page).to have_content(t('idv.messages.mail_sent'))
- expect_step_indicator_current_step(t('step_indicator.flows.idv.secure_account'))
+ expect(page).to have_content(t('idv.titles.come_back_later'))
expect(page).to have_content(t('step_indicator.flows.idv.get_a_letter'))
expect(page).not_to have_content(t('step_indicator.flows.idv.verify_phone_or_address'))
end
diff --git a/spec/features/idv/steps/gpo_otp_verification_step_spec.rb b/spec/features/idv/steps/gpo_otp_verification_step_spec.rb
index 9d2f85f1576..13b96d0e147 100644
--- a/spec/features/idv/steps/gpo_otp_verification_step_spec.rb
+++ b/spec/features/idv/steps/gpo_otp_verification_step_spec.rb
@@ -74,8 +74,6 @@
context 'with gpo personal key after verification' do
it 'shows the user a personal key after verification' do
- allow(IdentityConfig.store).to receive(:gpo_personal_key_after_otp).
- and_return(true)
sign_in_live_with_2fa(user)
expect(current_path).to eq idv_gpo_verify_path
diff --git a/spec/features/idv/steps/gpo_step_spec.rb b/spec/features/idv/steps/gpo_step_spec.rb
index 78c54d4b6fd..1c3c254ae6c 100644
--- a/spec/features/idv/steps/gpo_step_spec.rb
+++ b/spec/features/idv/steps/gpo_step_spec.rb
@@ -50,7 +50,6 @@ def complete_idv_and_return_to_gpo_step
click_on t('idv.buttons.mail.send')
fill_in 'Password', with: user_password
click_continue
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
visit root_path
click_on t('idv.buttons.cancel')
first(:link, t('links.sign_out')).click
@@ -103,12 +102,6 @@ def expect_user_to_be_unverified(user)
click_on(t('idv.buttons.mail.send'))
fill_in 'Password', with: new_password
click_continue
- page.find(
- 'label',
- text: t('forms.personal_key.required_checkbox'),
- wait: 5,
- ).click
- click_continue
set_new_browser_session
visit_idp_from_ial2_oidc_sp
signin(user.email, new_password)
diff --git a/spec/features/idv/steps/in_person/verify_info_spec.rb b/spec/features/idv/steps/in_person/verify_info_spec.rb
index 6f408fb9760..7aacb6188f1 100644
--- a/spec/features/idv/steps/in_person/verify_info_spec.rb
+++ b/spec/features/idv/steps/in_person/verify_info_spec.rb
@@ -28,11 +28,7 @@
expect(page).to have_content(t('headings.verify'))
expect(page).to have_text(InPersonHelper::GOOD_FIRST_NAME)
expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME)
- i18n_dob = I18n.l(
- Date.parse(InPersonHelper::GOOD_DOB),
- format: I18n.t('time.formats.event_date'),
- )
- expect(page).to have_text(i18n_dob)
+ expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT)
expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER)
expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1)
expect(page).to have_text(InPersonHelper::GOOD_CITY)
diff --git a/spec/features/idv/steps/in_person/verify_step_spec.rb b/spec/features/idv/steps/in_person/verify_step_spec.rb
index e9100dec707..a2a5d0342a0 100644
--- a/spec/features/idv/steps/in_person/verify_step_spec.rb
+++ b/spec/features/idv/steps/in_person/verify_step_spec.rb
@@ -25,7 +25,7 @@
expect(page).to have_content(t('headings.verify'))
expect(page).to have_text(InPersonHelper::GOOD_FIRST_NAME)
expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME)
- expect(page).to have_text(InPersonHelper::GOOD_DOB)
+ expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT)
expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER)
expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1)
expect(page).to have_text(InPersonHelper::GOOD_CITY)
diff --git a/spec/features/idv/steps/review_step_spec.rb b/spec/features/idv/steps/review_step_spec.rb
index 75cd6674a9f..0a5f9b5eacb 100644
--- a/spec/features/idv/steps/review_step_spec.rb
+++ b/spec/features/idv/steps/review_step_spec.rb
@@ -82,7 +82,6 @@
end
it 'sends you to the come_back_later page after review step' do
- allow(IdentityConfig.store).to receive(:gpo_personal_key_after_otp).and_return(true)
fill_in 'Password', with: user_password
click_continue
diff --git a/spec/features/saml/ial2_sso_spec.rb b/spec/features/saml/ial2_sso_spec.rb
index 608bca8c411..d90e358698a 100644
--- a/spec/features/saml/ial2_sso_spec.rb
+++ b/spec/features/saml/ial2_sso_spec.rb
@@ -29,7 +29,6 @@ def perform_id_verification_with_gpo_without_confirming_code(user)
click_on t('idv.buttons.mail.send')
fill_in t('idv.form.password'), with: user.password
click_continue
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
click_link t('idv.cancel.actions.exit', app_name: APP_NAME)
end
@@ -44,7 +43,6 @@ def update_mailing_address
click_on t('idv.buttons.mail.resend')
fill_in t('idv.form.password'), with: user.password
click_continue
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
click_link t('idv.cancel.actions.exit', app_name: APP_NAME)
end
diff --git a/spec/features/users/verify_profile_spec.rb b/spec/features/users/verify_profile_spec.rb
index 263093cbd09..047eb20e7c3 100644
--- a/spec/features/users/verify_profile_spec.rb
+++ b/spec/features/users/verify_profile_spec.rb
@@ -28,8 +28,8 @@
sign_in_live_with_2fa(user)
fill_in t('forms.verify_profile.name'), with: otp
click_button t('forms.verify_profile.submit')
+ acknowledge_and_confirm_personal_key
- expect(page).to have_content(t('account.index.verification.success'))
expect(page).to have_current_path(account_path)
end
diff --git a/spec/jobs/fraud_rejection_daily_job_spec.rb b/spec/jobs/fraud_rejection_daily_job_spec.rb
index 9a1022acef3..cd683751bcc 100644
--- a/spec/jobs/fraud_rejection_daily_job_spec.rb
+++ b/spec/jobs/fraud_rejection_daily_job_spec.rb
@@ -18,6 +18,7 @@
expect { job.perform(Time.zone.today) }.to change { rejected_profiles.count }.by(1)
expect(job_analytics).to have_logged_event(
'Fraud: Automatic Fraud Rejection',
+ rejection_date: Time.zone.today,
verified_at: rejected_profiles.first.verified_at,
)
end
diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb
index bd17b08c838..1ffce6a2238 100644
--- a/spec/jobs/get_usps_proofing_results_job_spec.rb
+++ b/spec/jobs/get_usps_proofing_results_job_spec.rb
@@ -146,13 +146,13 @@
let(:job) { GetUspsProofingResultsJob.new }
let(:job_analytics) { FakeAnalytics.new }
let(:transaction_start_date_time) do
- ActiveSupport::TimeZone['Central Time (US & Canada)'].strptime(
+ ActiveSupport::TimeZone[-6].strptime(
'12/17/2020 033855',
'%m/%d/%Y %H%M%S',
).in_time_zone('UTC')
end
let(:transaction_end_date_time) do
- ActiveSupport::TimeZone['Central Time (US & Canada)'].strptime(
+ ActiveSupport::TimeZone[-6].strptime(
'12/17/2020 034055',
'%m/%d/%Y %H%M%S',
).in_time_zone('UTC')
@@ -414,7 +414,7 @@
context 'a custom delay greater than zero is set' do
let(:user) { pending_enrollment.user }
let(:proofed_at_string) do
- proofed_at = ActiveSupport::TimeZone['Central Time (US & Canada)'].now - 1.hour
+ proofed_at = ActiveSupport::TimeZone[-6].now
proofed_at.strftime('%m/%d/%Y %H%M%S')
end
@@ -424,11 +424,12 @@
end
it 'uses the custom delay when proofing passes' do
- stub_request_passed_proofing_results(transactionEndDateTime: proofed_at_string)
wait_until = nil
freeze_time do
- wait_until = Time.zone.now + 4.hours
+ stub_request_passed_proofing_results(transactionEndDateTime: proofed_at_string)
+ wait_until = Time.zone.now +
+ IdentityConfig.store.in_person_results_delay_in_hours.hours
expect do
job.perform(Time.zone.now)
end.to have_enqueued_mail(UserMailer, :in_person_verified).with(
@@ -448,11 +449,12 @@
end
it 'uses the custom delay when proofing fails' do
- stub_request_failed_proofing_results(transactionEndDateTime: proofed_at_string)
wait_until = nil
freeze_time do
- wait_until = Time.zone.now + 4.hours
+ stub_request_failed_proofing_results(transactionEndDateTime: proofed_at_string)
+ wait_until = Time.zone.now +
+ IdentityConfig.store.in_person_results_delay_in_hours.hours
expect do
job.perform(Time.zone.now)
end.to have_enqueued_mail(UserMailer, :in_person_failed).with(
diff --git a/spec/jobs/heartbeat_job_spec.rb b/spec/jobs/heartbeat_job_spec.rb
index 8838f4065cc..113531fa617 100644
--- a/spec/jobs/heartbeat_job_spec.rb
+++ b/spec/jobs/heartbeat_job_spec.rb
@@ -13,10 +13,6 @@
msg = JSON.parse(str, symbolize_names: true)
expect(msg).to eq(
name: 'queue_metric.good_job',
- num_finished: 0,
- num_unfinished: 0,
- num_running: 0,
- num_errors: 0,
)
end
diff --git a/spec/jobs/psql_stats_job_spec.rb b/spec/jobs/psql_stats_job_spec.rb
deleted file mode 100644
index e77848ba73d..00000000000
--- a/spec/jobs/psql_stats_job_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe PsqlStatsJob, type: :job do
- describe '#perform' do
- it 'returns true' do
- result = PsqlStatsJob.new.perform(Time.zone.now)
-
- expect(result).to eq true
- end
-
- it 'logs psql table bloat metrics' do
- expect(IdentityJobLogSubscriber.reports_logger).to receive(:info) do |str|
- msg = JSON.parse(str, symbolize_names: true)
- expect(msg[:name]).to eq('psql_bloat_statistics')
- expect(msg[:table_data][:users][:tblname]).to eq('users')
- end
-
- PsqlStatsJob.new.perform(Time.zone.now)
- end
- end
-end
diff --git a/spec/jobs/reports/duplicate_ssn_report_spec.rb b/spec/jobs/reports/duplicate_ssn_report_spec.rb
new file mode 100644
index 00000000000..afe816a4442
--- /dev/null
+++ b/spec/jobs/reports/duplicate_ssn_report_spec.rb
@@ -0,0 +1,102 @@
+require 'rails_helper'
+require 'csv'
+
+RSpec.describe Reports::DuplicateSsnReport do
+ let(:report_date) { Date.new(2022, 2, 2) }
+
+ describe '#perform' do
+ subject(:report) { described_class.new }
+
+ it 'runs the report and uploads to S3' do
+ expect(report).to receive(:save_report)
+
+ report.perform(report_date)
+ end
+ end
+
+ describe '#report_body' do
+ subject(:report_body) { described_class.new(report_date).report_body }
+
+ context 'with no data' do
+ it 'is an empty report' do
+ csv = CSV.parse(report_body, headers: true)
+
+ expect(csv).to be_empty
+ end
+ end
+
+ context 'with data' do
+ let(:ssn_fingerprint1) { 'aaa' }
+ let(:ssn_fingerprint2) { 'bbb' }
+
+ let!(:unique_profile) do
+ create(
+ :profile,
+ :active,
+ ssn_signature: ssn_fingerprint1,
+ activated_at: report_date,
+ )
+ end
+
+ let!(:fingerprint2_today_profile) do
+ create(
+ :profile,
+ :active,
+ ssn_signature: ssn_fingerprint2,
+ activated_at: report_date,
+ ).tap(&:reload)
+ end
+
+ let!(:fingerprint2_previous_profiles) do
+ [
+ create(
+ :profile,
+ active: false,
+ ssn_signature: ssn_fingerprint2,
+ activated_at: report_date - 10.days,
+ ),
+ create(
+ :profile,
+ active: false,
+ ssn_signature: ssn_fingerprint2,
+ activated_at: nil,
+ ),
+ ].map(&:reload)
+ end
+
+ it 'creates csv with corresponding data', aggregate_failures: true do
+ csv = CSV.parse(report_body, headers: true)
+ expect(csv.length).to eq(3)
+
+ expect(csv.find { |r| r['uuid'] == unique_profile.user.uuid }).
+ to be_nil, 'does not include unique users in the report'
+
+ today_user = fingerprint2_today_profile.user
+ today_row = csv.find { |r| r['uuid'] == today_user.uuid }
+
+ expect_row_matches_profile(row: today_row, profile: fingerprint2_today_profile)
+ expect(today_row['new_account']).to eq('true')
+
+ fingerprint2_previous_profiles.each do |profile|
+ row = csv.find { |r| r['uuid'] == profile.user.uuid }
+
+ expect_row_matches_profile(row:, profile:)
+ expect(row['new_account']).to eq('false')
+ end
+ end
+
+ def expect_row_matches_profile(row:, profile:)
+ expect(row).to be
+ expect(row['uuid']).to eq(profile.user.uuid)
+ expect(Time.zone.parse(row['account_created_at']).to_i).to eq(profile.user.created_at.to_i)
+ if profile.activated_at
+ expect(Time.zone.parse(row['identity_verified_at']).to_i).to eq(profile.activated_at.to_i)
+ end
+ expect(row['profile_active']).to eq(profile.active.to_s)
+ expect(row['ssn_fingerprint']).to eq(ssn_fingerprint2)
+ expect(row['count_ssn_fingerprint']).to eq('3')
+ expect(row['count_active_ssn_fingerprint']).to eq('1')
+ end
+ end
+ end
+end
diff --git a/spec/jobs/risc_delivery_job_spec.rb b/spec/jobs/risc_delivery_job_spec.rb
index 79d1a94ed31..530636e0217 100644
--- a/spec/jobs/risc_delivery_job_spec.rb
+++ b/spec/jobs/risc_delivery_job_spec.rb
@@ -2,9 +2,9 @@
RSpec.describe RiscDeliveryJob do
around do |ex|
- REDIS_THROTTLE_POOL.with { |namespaced| namespaced.redis.flushdb }
+ REDIS_THROTTLE_POOL.with { |client| client.flushdb }
ex.run
- REDIS_THROTTLE_POOL.with { |namespaced| namespaced.redis.flushdb }
+ REDIS_THROTTLE_POOL.with { |client| client.flushdb }
end
describe '#perform' do
diff --git a/spec/presenters/fully_signed_in_modal_presenter_spec.rb b/spec/presenters/fully_signed_in_modal_presenter_spec.rb
deleted file mode 100644
index 12f229edb56..00000000000
--- a/spec/presenters/fully_signed_in_modal_presenter_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'rails_helper'
-
-describe FullySignedInModalPresenter do
- include ActionView::Helpers::SanitizeHelper
-
- let(:expiration) { Time.zone.now + 1.minute + 1.second }
- let(:lookup_context) { ActionView::LookupContext.new(ActionController::Base.view_paths) }
- let(:view_context) { ActionView::Base.new(lookup_context, {}, nil) }
- subject(:presenter) do
- FullySignedInModalPresenter.new(view_context: view_context, expiration: expiration)
- end
-
- around do |ex|
- freeze_time { ex.run }
- end
-
- describe '#message' do
- it 'returns the fully signed in message' do
- expect(strip_tags(presenter.message)).to eq t(
- 'notices.timeout_warning.signed_in.message_html',
- time_left_in_session: '1 minute and 1 second',
- )
- end
- end
-
- describe '#sr_message' do
- it 'returns the fully signed in message for screen readers' do
- expect(strip_tags(presenter.sr_message)).to eq t(
- 'notices.timeout_warning.signed_in.sr_message_html',
- time_left_in_session: '1 minute and 1 second',
- )
- end
- end
-
- describe '#continue' do
- it 'uses the fully signed in localization' do
- expect(presenter.continue).to eq t('notices.timeout_warning.signed_in.continue')
- end
- end
-
- describe '#sign_out' do
- it 'uses the fully signed in localization' do
- expect(presenter.sign_out).to eq t('notices.timeout_warning.signed_in.sign_out')
- end
- end
-end
diff --git a/spec/presenters/partially_signed_in_modal_presenter_spec.rb b/spec/presenters/partially_signed_in_modal_presenter_spec.rb
deleted file mode 100644
index 8949e0fa53f..00000000000
--- a/spec/presenters/partially_signed_in_modal_presenter_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'rails_helper'
-
-describe PartiallySignedInModalPresenter do
- include ActionView::Helpers::SanitizeHelper
-
- let(:expiration) { Time.zone.now + 1.minute + 1.second }
- let(:lookup_context) { ActionView::LookupContext.new(ActionController::Base.view_paths) }
- let(:view_context) { ActionView::Base.new(lookup_context, {}, nil) }
- subject(:presenter) do
- PartiallySignedInModalPresenter.new(view_context: view_context, expiration: expiration)
- end
-
- around do |ex|
- freeze_time { ex.run }
- end
-
- describe '#message' do
- it 'returns the partially signed in message' do
- expect(strip_tags(presenter.message)).to eq t(
- 'notices.timeout_warning.partially_signed_in.message_html',
- time_left_in_session: '1 minute and 1 second',
- )
- end
- end
-
- describe '#sr_message' do
- it 'returns the partially signed in message for screen readers' do
- expect(strip_tags(presenter.sr_message)).to eq t(
- 'notices.timeout_warning.partially_signed_in.sr_message_html',
- time_left_in_session: '1 minute and 1 second',
- )
- end
- end
-
- describe '#continue' do
- it 'uses the partially signed in localization' do
- expect(presenter.continue).to eq t('notices.timeout_warning.partially_signed_in.continue')
- end
- end
-
- describe '#sign_out' do
- it 'uses the partially signed in localization' do
- expect(presenter.sign_out).to eq t('notices.timeout_warning.partially_signed_in.sign_out')
- end
- end
-end
diff --git a/spec/presenters/session_timeout_modal_presenter_spec.rb b/spec/presenters/session_timeout_modal_presenter_spec.rb
new file mode 100644
index 00000000000..0025600fc1a
--- /dev/null
+++ b/spec/presenters/session_timeout_modal_presenter_spec.rb
@@ -0,0 +1,27 @@
+require 'rails_helper'
+
+describe SessionTimeoutModalPresenter do
+ let(:user_fully_authenticated) { nil }
+
+ subject(:presenter) { described_class.new(user_fully_authenticated:) }
+
+ describe '#translation_scope' do
+ subject(:translation_scope) { presenter.translation_scope }
+
+ context 'without fully authenticated user' do
+ let(:user_fully_authenticated) { false }
+
+ it 'returns the partially signed in locale scope' do
+ expect(translation_scope).to eq([:notices, :timeout_warning, :partially_signed_in])
+ end
+ end
+
+ context 'with fully authenticated user' do
+ let(:user_fully_authenticated) { true }
+
+ it 'returns the fully signed in locale scope' do
+ expect(translation_scope).to eq([:notices, :timeout_warning, :signed_in])
+ end
+ end
+ end
+end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 3fe68c58dda..912de11754c 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -110,7 +110,7 @@ class Analytics
Telephony::Test::Message.clear_messages
Telephony::Test::Call.clear_calls
PushNotification::LocalEventQueue.clear!
- REDIS_THROTTLE_POOL.with { |namespaced| namespaced.redis.flushdb }
+ REDIS_THROTTLE_POOL.with { |client| client.flushdb }
end
config.before(:each) do
diff --git a/spec/requests/rack_attack_spec.rb b/spec/requests/rack_attack_spec.rb
index c186f48f0fe..a9aba39ce8e 100644
--- a/spec/requests/rack_attack_spec.rb
+++ b/spec/requests/rack_attack_spec.rb
@@ -394,7 +394,7 @@
context 'when the number of requests is under the limit' do
it 'does not throttle the request' do
(phone_setups_per_ip_limit - 1).times do
- patch '/phone_setup', headers: { REMOTE_ADDR: '1.2.3.4' }
+ post '/phone_setup', headers: { REMOTE_ADDR: '1.2.3.4' }
end
expect(response.status).to eq(302)
@@ -404,7 +404,7 @@
context 'when the number of requests is over the limit' do
it 'throttles the request' do
(phone_setups_per_ip_limit + 1).times do
- patch '/phone_setup', headers: { REMOTE_ADDR: '1.2.3.4' }
+ post '/phone_setup', headers: { REMOTE_ADDR: '1.2.3.4' }
end
expect(response.status).to eq(429)
diff --git a/spec/services/account_reset/create_request_spec.rb b/spec/services/account_reset/create_request_spec.rb
index b01872f278f..b8f1436c0b1 100644
--- a/spec/services/account_reset/create_request_spec.rb
+++ b/spec/services/account_reset/create_request_spec.rb
@@ -1,7 +1,8 @@
require 'rails_helper'
RSpec.describe AccountReset::CreateRequest do
- subject(:create_request) { described_class.new(user) }
+ subject(:requesting_issuer) { 'example-issuer' }
+ subject(:create_request) { described_class.new(user, requesting_issuer) }
describe '#call' do
context 'when the user does not have a phone' do
@@ -23,5 +24,16 @@
expect(response.to_h[:message_id]).to be_present
end
end
+
+ context 'when requesting_issuer is passed' do
+ let(:user) { build(:user) }
+
+ it 'it stores requesting_issuer' do
+ create_request.call
+ reset_request = AccountResetRequest.find_by(user_id: user.id)
+
+ expect(reset_request.requesting_issuer).to eq requesting_issuer
+ end
+ end
end
end
diff --git a/spec/services/account_reset/delete_account_spec.rb b/spec/services/account_reset/delete_account_spec.rb
index f169e620689..75ed8e04f79 100644
--- a/spec/services/account_reset/delete_account_spec.rb
+++ b/spec/services/account_reset/delete_account_spec.rb
@@ -2,7 +2,25 @@
describe AccountReset::DeleteAccount do
include AccountResetHelper
+
+ let(:expired_token_message) do
+ t('errors.account_reset.granted_token_expired', app_name: APP_NAME)
+ end
+ let(:expired_token_error) { { token: [expired_token_message] } }
let(:user) { create(:user) }
+ let(:request) { FakeRequest.new }
+ let(:analytics) { FakeAnalytics.new }
+ let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new }
+
+ let(:service_provider) do
+ create(
+ :service_provider,
+ active: true,
+ redirect_uris: ['http://localhost:7654/auth/result'],
+ ial: 2,
+ irs_attempts_api_enabled: true,
+ )
+ end
describe '#call' do
it 'can be called even if DeletedUser exists' do
@@ -10,7 +28,7 @@
grant_request(user)
token = AccountResetRequest.where(user_id: user.id).first.granted_token
DeletedUser.create_from_user(user)
- AccountReset::DeleteAccount.new(token).call
+ AccountReset::DeleteAccount.new(token, request, analytics).call
end
context 'when user.confirmed_at is nil' do
@@ -21,10 +39,47 @@
grant_request(user)
token = AccountResetRequest.where(user_id: user.id).first.granted_token
- expect { AccountReset::DeleteAccount.new(token).call }.to_not raise_error
+ expect do
+ AccountReset::DeleteAccount.new(token, request, analytics).call
+ end.to_not raise_error
expect(User.find_by(id: user.id)).to be_nil
end
end
+
+ context 'track irs event' do
+ before do
+ allow_any_instance_of(AccountReset::DeleteAccount).to receive(
+ :irs_attempts_api_tracker,
+ ).and_return(fake_attempts_tracker)
+ end
+
+ it 'logs attempts api event with success true if the token is good' do
+ expect(fake_attempts_tracker).to receive(:account_reset_account_deleted).with(
+ success: true,
+ failure_reason: nil,
+ )
+
+ create_account_reset_request_for(user, service_provider.issuer)
+ grant_request(user)
+ token = AccountResetRequest.where(user_id: user.id).first.granted_token
+ AccountReset::DeleteAccount.new(token, request, analytics).call
+ end
+
+ it 'logs attempts api event with failure reason if the token is expired' do
+ expect(fake_attempts_tracker).to receive(:account_reset_account_deleted).with(
+ success: false,
+ failure_reason: expired_token_error,
+ )
+
+ create_account_reset_request_for(user, service_provider.issuer)
+ grant_request(user)
+
+ travel_to(Time.zone.now + 2.days) do
+ token = AccountResetRequest.first.granted_token
+ AccountReset::DeleteAccount.new(token, request, analytics).call
+ end
+ end
+ end
end
end
diff --git a/spec/services/account_reset/validate_granted_token_spec.rb b/spec/services/account_reset/validate_granted_token_spec.rb
new file mode 100644
index 00000000000..93b60bd773a
--- /dev/null
+++ b/spec/services/account_reset/validate_granted_token_spec.rb
@@ -0,0 +1,49 @@
+require 'rails_helper'
+
+describe AccountReset::ValidateGrantedToken do
+ include AccountResetHelper
+
+ let(:expired_token_message) do
+ t('errors.account_reset.granted_token_expired', app_name: APP_NAME)
+ end
+ let(:expired_token_error) { { token: [expired_token_message] } }
+ let(:user) { create(:user) }
+ let(:request) { FakeRequest.new }
+ let(:analytics) { FakeAnalytics.new }
+ let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new }
+
+ let(:service_provider) do
+ create(
+ :service_provider,
+ active: true,
+ redirect_uris: ['http://localhost:7654/auth/result'],
+ ial: 2,
+ irs_attempts_api_enabled: true,
+ )
+ end
+
+ describe '#call' do
+ context 'track irs event' do
+ before do
+ allow_any_instance_of(AccountReset::ValidateGrantedToken).to receive(
+ :irs_attempts_api_tracker,
+ ).and_return(fake_attempts_tracker)
+ end
+
+ it 'logs attempts api event with failure reason if the token is expired' do
+ expect(fake_attempts_tracker).to receive(:account_reset_account_deleted).with(
+ success: false,
+ failure_reason: expired_token_error,
+ )
+
+ create_account_reset_request_for(user, service_provider.issuer)
+ grant_request(user)
+
+ travel_to(Time.zone.now + 2.days) do
+ token = AccountResetRequest.first.granted_token
+ AccountReset::ValidateGrantedToken.new(token, request, analytics).call
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/redis_rate_limiter_spec.rb b/spec/services/redis_rate_limiter_spec.rb
index 96a1c3034e8..dd3aa0d6a48 100644
--- a/spec/services/redis_rate_limiter_spec.rb
+++ b/spec/services/redis_rate_limiter_spec.rb
@@ -4,9 +4,9 @@
let(:now) { Time.zone.now }
around do |ex|
- REDIS_THROTTLE_POOL.with { |namespaced| namespaced.redis.flushdb }
+ REDIS_THROTTLE_POOL.with { |client| client.flushdb }
ex.run
- REDIS_THROTTLE_POOL.with { |namespaced| namespaced.redis.flushdb }
+ REDIS_THROTTLE_POOL.with { |client| client.flushdb }
end
let(:key) { 'some-unique-identifier' }
diff --git a/spec/support/account_reset_helper.rb b/spec/support/account_reset_helper.rb
index d82963627ce..54fb8e4364a 100644
--- a/spec/support/account_reset_helper.rb
+++ b/spec/support/account_reset_helper.rb
@@ -1,5 +1,5 @@
module AccountResetHelper
- def create_account_reset_request_for(user)
+ def create_account_reset_request_for(user, requesting_issuer = nil)
request = AccountResetRequest.create_or_find_by(user: user)
request_token = SecureRandom.uuid
request.update!(
@@ -8,6 +8,7 @@ def create_account_reset_request_for(user)
cancelled_at: nil,
granted_at: nil,
granted_token: nil,
+ requesting_issuer: requesting_issuer,
)
request_token
end
diff --git a/spec/support/controller_helper.rb b/spec/support/controller_helper.rb
index 61db17ce642..381f36df887 100644
--- a/spec/support/controller_helper.rb
+++ b/spec/support/controller_helper.rb
@@ -66,8 +66,7 @@ def stub_verify_steps_one_and_two(user)
dob: 50.years.ago.to_date.to_s,
ssn: '666-12-1234',
}.with_indifferent_access
- idv_session.profile_confirmation = true
- idv_session.resolution_successful = 'phone'
+ idv_session.resolution_successful = true
allow(subject).to receive(:confirm_idv_applicant_created).and_return(true)
allow(subject).to receive(:idv_session).and_return(idv_session)
allow(subject).to receive(:user_session).and_return(user_session)
@@ -81,7 +80,7 @@ def stub_user_with_applicant_data(user, applicant)
service_provider: nil
)
idv_session.applicant = applicant.with_indifferent_access
- idv_session.profile_confirmation = true
+ idv_session.resolution_successful = true
allow(subject).to receive(:confirm_idv_applicant_created).and_return(true)
allow(subject).to receive(:idv_session).and_return(idv_session)
allow(subject).to receive(:user_session).and_return(user_session)
diff --git a/spec/support/features/in_person_helper.rb b/spec/support/features/in_person_helper.rb
index a75e5c9eb86..3bfa4a51281 100644
--- a/spec/support/features/in_person_helper.rb
+++ b/spec/support/features/in_person_helper.rb
@@ -7,7 +7,12 @@ module InPersonHelper
GOOD_FIRST_NAME = Idp::Constants::MOCK_IDV_APPLICANT[:first_name]
GOOD_LAST_NAME = Idp::Constants::MOCK_IDV_APPLICANT[:last_name]
+ # the date in the format '1938-10-06'
GOOD_DOB = Idp::Constants::MOCK_IDV_APPLICANT[:dob]
+ # the date in the format 'October 6, 1938'
+ GOOD_DOB_FORMATTED_EVENT = I18n.l(
+ Date.parse(GOOD_DOB), format: I18n.t('time.formats.event_date')
+ )
GOOD_STATE_ID_JURISDICTION = Idp::Constants::MOCK_IDV_APPLICANT_FULL_STATE_ID_JURISDICTION
GOOD_STATE_ID_NUMBER = Idp::Constants::MOCK_IDV_APPLICANT[:state_id_number]
@@ -17,7 +22,7 @@ module InPersonHelper
GOOD_ZIPCODE = Idp::Constants::MOCK_IDV_APPLICANT[:zipcode]
GOOD_STATE = Idp::Constants::MOCK_IDV_APPLICANT_FULL_STATE
- def fill_out_state_id_form_ok
+ def fill_out_state_id_form_ok(include_address: false)
fill_in t('in_person_proofing.form.state_id.first_name'), with: GOOD_FIRST_NAME
fill_in t('in_person_proofing.form.state_id.last_name'), with: GOOD_LAST_NAME
year, month, day = GOOD_DOB.split('-')
@@ -27,6 +32,14 @@ def fill_out_state_id_form_ok
select GOOD_STATE_ID_JURISDICTION,
from: t('in_person_proofing.form.state_id.state_id_jurisdiction')
fill_in t('in_person_proofing.form.state_id.state_id_number'), with: GOOD_STATE_ID_NUMBER
+
+ if include_address
+ fill_in t('in_person_proofing.form.state_id.address1'), with: GOOD_ADDRESS1
+ fill_in t('in_person_proofing.form.state_id.address2'), with: GOOD_ADDRESS2
+ fill_in t('in_person_proofing.form.state_id.city'), with: GOOD_CITY
+ fill_in t('in_person_proofing.form.state_id.zipcode'), with: GOOD_ZIPCODE
+ choose t('in_person_proofing.form.state_id.same_address_as_id_no')
+ end
end
def fill_out_address_form_ok
@@ -67,11 +80,15 @@ def complete_prepare_step(_user = nil)
click_link t('forms.buttons.continue')
end
- def complete_state_id_step(_user = nil)
+ def complete_state_id_step(_user = nil, same_address_as_id: true, include_address: false)
# Wait for page to load before attempting to fill out form
expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10)
- fill_out_state_id_form_ok
+ include_address ? fill_out_state_id_form_ok(include_address: true) : fill_out_state_id_form_ok
click_idv_continue
+ unless include_address && same_address_as_id
+ expect(page).to have_current_path(idv_in_person_step_path(step: :address), wait: 10)
+ expect_in_person_step_indicator_current_step(t('step_indicator.flows.idv.verify_info'))
+ end
end
def complete_address_step(_user = nil)
diff --git a/spec/support/idv_examples/clearing_and_restarting.rb b/spec/support/idv_examples/clearing_and_restarting.rb
index 8da95bfe913..be194690714 100644
--- a/spec/support/idv_examples/clearing_and_restarting.rb
+++ b/spec/support/idv_examples/clearing_and_restarting.rb
@@ -27,7 +27,6 @@
end
fill_in 'Password', with: user.password
click_idv_continue
- acknowledge_and_confirm_personal_key unless IdentityConfig.store.gpo_personal_key_after_otp
gpo_confirmation = GpoConfirmation.order(created_at: :desc).first
diff --git a/yarn.lock b/yarn.lock
index c97bd69e82e..1ca4dee6923 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1419,7 +1419,7 @@
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
- integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
"@types/mime@*":
version "3.0.1"
@@ -1991,6 +1991,14 @@ aria-query@^5.0.0:
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.2.tgz#0b8a744295271861e1d933f8feca13f9b70cfdc1"
integrity sha512-eigU3vhqSO+Z8BKDnVLN/ompjhf3pYzecKXz8+whRy+9gZu8n1TCGfwzQUUPnqdHl9ax1Hr9031orZ+UOEYr7Q==
+array-buffer-byte-length@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead"
+ integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==
+ dependencies:
+ call-bind "^1.0.2"
+ is-array-buffer "^3.0.1"
+
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -2001,15 +2009,15 @@ array-flatten@^2.1.2:
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
-array-includes@^3.1.4, array-includes@^3.1.5:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
- integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
+array-includes@^3.1.5, array-includes@^3.1.6:
+ version "3.1.6"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f"
+ integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.4"
- es-abstract "^1.19.5"
- get-intrinsic "^1.1.1"
+ es-abstract "^1.20.4"
+ get-intrinsic "^1.1.3"
is-string "^1.0.7"
array-union@^2.1.0:
@@ -2017,23 +2025,24 @@ array-union@^2.1.0:
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
-array.prototype.flat@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
- integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
+array.prototype.flat@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2"
+ integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.0"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
-array.prototype.flatmap@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
- integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
+array.prototype.flatmap@^1.3.0, array.prototype.flatmap@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183"
+ integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
es-shim-unscopables "^1.0.0"
arrify@^1.0.1:
@@ -2515,7 +2524,7 @@ compression@^1.7.4:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+ integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
confusing-browser-globals@^1.0.10:
version "1.0.10"
@@ -2679,7 +2688,7 @@ data-urls@^3.0.2:
whatwg-mimetype "^3.0.0"
whatwg-url "^11.0.0"
-debug@2.6.9, debug@^2.6.9:
+debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -2760,9 +2769,9 @@ define-lazy-prop@^2.0.0:
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
define-properties@^1.1.3, define-properties@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
- integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5"
+ integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==
dependencies:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
@@ -2952,41 +2961,60 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5:
- version "1.20.3"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.3.tgz#90b143ff7aedc8b3d189bcfac7f1e3e3f81e9da1"
- integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==
+es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20.4:
+ version "1.21.2"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff"
+ integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==
dependencies:
+ array-buffer-byte-length "^1.0.0"
+ available-typed-arrays "^1.0.5"
call-bind "^1.0.2"
+ es-set-tostringtag "^2.0.1"
es-to-primitive "^1.2.1"
- function-bind "^1.1.1"
function.prototype.name "^1.1.5"
- get-intrinsic "^1.1.3"
+ get-intrinsic "^1.2.0"
get-symbol-description "^1.0.0"
+ globalthis "^1.0.3"
+ gopd "^1.0.1"
has "^1.0.3"
has-property-descriptors "^1.0.0"
+ has-proto "^1.0.1"
has-symbols "^1.0.3"
- internal-slot "^1.0.3"
- is-callable "^1.2.6"
+ internal-slot "^1.0.5"
+ is-array-buffer "^3.0.2"
+ is-callable "^1.2.7"
is-negative-zero "^2.0.2"
is-regex "^1.1.4"
is-shared-array-buffer "^1.0.2"
is-string "^1.0.7"
+ is-typed-array "^1.1.10"
is-weakref "^1.0.2"
- object-inspect "^1.12.2"
+ object-inspect "^1.12.3"
object-keys "^1.1.1"
object.assign "^4.1.4"
regexp.prototype.flags "^1.4.3"
safe-regex-test "^1.0.0"
- string.prototype.trimend "^1.0.5"
- string.prototype.trimstart "^1.0.5"
+ string.prototype.trim "^1.2.7"
+ string.prototype.trimend "^1.0.6"
+ string.prototype.trimstart "^1.0.6"
+ typed-array-length "^1.0.4"
unbox-primitive "^1.0.2"
+ which-typed-array "^1.1.9"
es-module-lexer@^0.9.0:
version "0.9.3"
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
+es-set-tostringtag@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8"
+ integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==
+ dependencies:
+ get-intrinsic "^1.1.3"
+ has "^1.0.3"
+ has-tostringtag "^1.0.0"
+
es-shim-unscopables@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241"
@@ -3054,38 +3082,41 @@ eslint-config-airbnb@^19.0.4:
object.assign "^4.1.2"
object.entries "^1.1.5"
-eslint-import-resolver-node@^0.3.6:
- version "0.3.6"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
- integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
+eslint-import-resolver-node@^0.3.7:
+ version "0.3.7"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7"
+ integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==
dependencies:
debug "^3.2.7"
- resolve "^1.20.0"
+ is-core-module "^2.11.0"
+ resolve "^1.22.1"
-eslint-module-utils@^2.7.3:
+eslint-module-utils@^2.7.4:
version "2.7.4"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974"
integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==
dependencies:
debug "^3.2.7"
-eslint-plugin-import@^2.26.0:
- version "2.26.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b"
- integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==
+eslint-plugin-import@^2.27.5:
+ version "2.27.5"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65"
+ integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==
dependencies:
- array-includes "^3.1.4"
- array.prototype.flat "^1.2.5"
- debug "^2.6.9"
+ array-includes "^3.1.6"
+ array.prototype.flat "^1.3.1"
+ array.prototype.flatmap "^1.3.1"
+ debug "^3.2.7"
doctrine "^2.1.0"
- eslint-import-resolver-node "^0.3.6"
- eslint-module-utils "^2.7.3"
+ eslint-import-resolver-node "^0.3.7"
+ eslint-module-utils "^2.7.4"
has "^1.0.3"
- is-core-module "^2.8.1"
+ is-core-module "^2.11.0"
is-glob "^4.0.3"
minimatch "^3.1.2"
- object.values "^1.1.5"
- resolve "^1.22.0"
+ object.values "^1.1.6"
+ resolve "^1.22.1"
+ semver "^6.3.0"
tsconfig-paths "^3.14.1"
eslint-plugin-jsx-a11y@^6.6.1:
@@ -3580,10 +3611,10 @@ get-func-name@^2.0.0:
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
-get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
- integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
+ integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==
dependencies:
function-bind "^1.1.1"
has "^1.0.3"
@@ -3673,6 +3704,13 @@ globals@^13.15.0:
dependencies:
type-fest "^0.20.2"
+globalthis@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf"
+ integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
+ dependencies:
+ define-properties "^1.1.3"
+
globby@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
@@ -3749,6 +3787,11 @@ has-property-descriptors@^1.0.0:
dependencies:
get-intrinsic "^1.1.1"
+has-proto@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
+ integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
+
has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
@@ -4002,12 +4045,12 @@ inquirer@^8.2.0:
through "^2.3.6"
wrap-ansi "^7.0.0"
-internal-slot@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
- integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==
+internal-slot@^1.0.3, internal-slot@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986"
+ integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==
dependencies:
- get-intrinsic "^1.1.0"
+ get-intrinsic "^1.2.0"
has "^1.0.3"
side-channel "^1.0.4"
@@ -4039,6 +4082,15 @@ is-arguments@^1.0.4:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
+is-array-buffer@^3.0.1, is-array-buffer@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe"
+ integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.2.0"
+ is-typed-array "^1.1.10"
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@@ -4066,15 +4118,15 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
-is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.6:
+is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
-is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.8.1, is-core-module@^2.9.0:
- version "2.10.0"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed"
- integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==
+is-core-module@^2.11.0, is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.9.0:
+ version "2.11.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
+ integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
dependencies:
has "^1.0.3"
@@ -4093,7 +4145,7 @@ is-docker@^2.0.0, is-docker@^2.1.1:
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
- integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
@@ -4130,9 +4182,9 @@ is-node-process@^1.0.1:
integrity sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==
is-number-object@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0"
- integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
+ integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
dependencies:
has-tostringtag "^1.0.0"
@@ -4207,7 +4259,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-is-typed-array@^1.1.10, is-typed-array@^1.1.3:
+is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9:
version "1.1.10"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f"
integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==
@@ -4351,10 +4403,10 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
-json5@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
- integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+json5@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
+ integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
dependencies:
minimist "^1.2.0"
@@ -4784,7 +4836,7 @@ mq-polyfill@^1.1.8:
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+ integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
ms@2.1.2:
version "2.1.2"
@@ -4941,10 +4993,10 @@ object-assign@4.1.1, object-assign@^4.1.0, object-assign@^4.1.1:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-object-inspect@^1.12.2, object-inspect@^1.9.0:
- version "1.12.2"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
- integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
+object-inspect@^1.12.3, object-inspect@^1.9.0:
+ version "1.12.3"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
+ integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
object-keys@^1.1.1:
version "1.1.1"
@@ -4987,14 +5039,14 @@ object.hasown@^1.1.1:
define-properties "^1.1.4"
es-abstract "^1.19.5"
-object.values@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
- integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
+object.values@^1.1.5, object.values@^1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d"
+ integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.1"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
obuf@^1.0.0, obuf@^1.1.2:
version "1.1.2"
@@ -5626,7 +5678,7 @@ resolve-id-refs@0.1.0:
resolved "https://registry.yarnpkg.com/resolve-id-refs/-/resolve-id-refs-0.1.0.tgz#3126624b887489da8fc0ae889632f8413ac6c3ec"
integrity sha1-MSZiS4h0idqPwK6IljL4QTrGw+w=
-resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0:
+resolve@^1.10.0, resolve@^1.14.2, resolve@^1.22.1, resolve@^1.9.0:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -6107,23 +6159,32 @@ string.prototype.matchall@^4.0.7:
regexp.prototype.flags "^1.4.1"
side-channel "^1.0.4"
-string.prototype.trimend@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
- integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
+string.prototype.trim@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533"
+ integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.4"
- es-abstract "^1.19.5"
+ es-abstract "^1.20.4"
-string.prototype.trimstart@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
- integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
+string.prototype.trimend@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533"
+ integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.4"
- es-abstract "^1.19.5"
+ es-abstract "^1.20.4"
+
+string.prototype.trimstart@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4"
+ integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
string_decoder@^1.1.1:
version "1.3.0"
@@ -6149,7 +6210,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
- integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
+ integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
strip-final-newline@^2.0.0:
version "2.0.0"
@@ -6426,12 +6487,12 @@ trim-newlines@^3.0.0:
integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
tsconfig-paths@^3.14.1:
- version "3.14.1"
- resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
- integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
+ version "3.14.2"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088"
+ integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==
dependencies:
"@types/json5" "^0.0.29"
- json5 "^1.0.1"
+ json5 "^1.0.2"
minimist "^1.2.6"
strip-bom "^3.0.0"
@@ -6509,6 +6570,15 @@ type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
+typed-array-length@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb"
+ integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==
+ dependencies:
+ call-bind "^1.0.2"
+ for-each "^0.3.3"
+ is-typed-array "^1.1.9"
+
typescript@^4.8.4:
version "4.8.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6"
@@ -6785,10 +6855,10 @@ webpack-sources@^3.2.3:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
-webpack@^5.74.0:
- version "5.74.0"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980"
- integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==
+webpack@^5.76.1:
+ version "5.76.1"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c"
+ integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==
dependencies:
"@types/eslint-scope" "^3.7.3"
"@types/estree" "^0.0.51"
@@ -6873,7 +6943,7 @@ which-boxed-primitive@^1.0.2:
is-string "^1.0.5"
is-symbol "^1.0.3"
-which-typed-array@^1.1.2:
+which-typed-array@^1.1.2, which-typed-array@^1.1.9:
version "1.1.9"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6"
integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==