Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 57 additions & 45 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"selector": "AssignmentExpression[left.property.name='href'][right.type=/(Template)?Literal/]",
"message": "Do not assign window.location.href to a string or string template to avoid losing i18n parameters"
}
]
],
"react-hooks/exhaustive-deps": "error"
},
"settings": {
"import/internal-regex": "^@18f/identity-"
Expand Down Expand Up @@ -50,69 +51,80 @@
}
},
{
// Turn off react linting rules for most packages/files
"files": [
"spec/**",
"app/javascript/packs/**",
"app/javascript/packages/address-search/**",
"app/javascript/packages/components/**",
"app/javascript/packages/compose-components/**",
"app/javascript/packages/form-steps/**",
"app/javascript/packages/react-hooks/**",
"app/javascript/packages/react-i18n/**",
"app/javascript/packages/spinner-button/**",
"app/javascript/packages/step-indicator/**",
"app/javascript/packages/validated-field/**",
"app/javascript/packages/verify-flow/**",
// In progress: enabling these rules for all files in packages/document-capture
"app/javascript/packages/document-capture/context/**",
"app/javascript/packages/document-capture/higher-order/**",
"app/javascript/packages/document-capture/hooks/**",
// Comment out a file to enable react lint rules for that file only
"app/javascript/packages/address-search/components/address-input.tsx",
"app/javascript/packages/address-search/components/full-address-search-input.tsx",
"app/javascript/packages/components/hooks/use-focus-trap.ts",
"app/javascript/packages/components/hooks/use-toggle-body-class-by-presence.ts",
"app/javascript/packages/document-capture/components/acuant-camera.tsx",
"app/javascript/packages/document-capture/components/acuant-capture-canvas.jsx",
"app/javascript/packages/document-capture/components/acuant-capture.tsx",
"app/javascript/packages/document-capture/components/acuant-selfie-camera.tsx",
"app/javascript/packages/document-capture/components/acuant-selfie-capture-canvas.jsx",
"app/javascript/packages/document-capture/components/barcode-attention-warning.tsx",
"app/javascript/packages/document-capture/components/callback-on-mount.jsx",
"app/javascript/packages/document-capture/components/document-capture-troubleshooting-options.tsx",
"app/javascript/packages/document-capture/components/document-capture-warning.tsx",
"app/javascript/packages/document-capture/components/document-capture.tsx",
"app/javascript/packages/document-capture/components/document-side-acuant-capture.jsx",
"app/javascript/packages/document-capture/components/documents-step.jsx",
"app/javascript/packages/document-capture/components/file-image.jsx",
"app/javascript/packages/document-capture/components/file-input.tsx",
"app/javascript/packages/document-capture/components/hybrid-doc-capture-warning.spec.tsx",
"app/javascript/packages/document-capture/components/hybrid-doc-capture-warning.tsx",
"app/javascript/packages/document-capture/components/in-person-call-to-action.spec.tsx",
"app/javascript/packages/document-capture/components/in-person-call-to-action.tsx",
"app/javascript/packages/document-capture/components/in-person-location-full-address-entry-post-office-search-step.spec.tsx",
"app/javascript/packages/document-capture/components/in-person-location-full-address-entry-post-office-search-step.tsx",
"app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.spec.tsx",
"app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx",
"app/javascript/packages/document-capture/components/in-person-outage-alert.spec.tsx",
"app/javascript/packages/document-capture/components/in-person-outage-alert.tsx",
"app/javascript/packages/document-capture/components/in-person-prepare-step.spec.tsx",
"app/javascript/packages/document-capture/components/in-person-prepare-step.tsx",
"app/javascript/packages/document-capture/components/in-person-switch-back-step.tsx",
"app/javascript/packages/document-capture/components/in-person-troubleshooting-options.tsx",
"app/javascript/packages/document-capture/components/review-issues-step.tsx",
"app/javascript/packages/document-capture/components/status-message.jsx",
"app/javascript/packages/document-capture/components/submission-complete.tsx",
"app/javascript/packages/document-capture/components/submission-interstitial.jsx",
"app/javascript/packages/document-capture/components/submission-status.jsx",
"app/javascript/packages/document-capture/context/acuant.tsx",
"app/javascript/packages/document-capture/hooks/use-cookie.js",
"app/javascript/packages/form-steps/form-steps.spec.tsx",
"app/javascript/packages/form-steps/form-steps.tsx",
"app/javascript/packages/form-steps/use-history-param.ts",
"app/javascript/packages/react-hooks/use-did-update-effect.ts",
"app/javascript/packages/react-hooks/use-immutable-callback.ts",
"app/javascript/packages/react-hooks/use-object-memo.ts"
],
"rules": {
"react-hooks/exhaustive-deps": "off"
}
},
{
"files": [
"app/javascript/packages/address-search/components/in-person-locations.spec.tsx",
"app/javascript/packages/components/spinner-dots.jsx",
"app/javascript/packages/document-capture/components/acuant-capture.tsx",
"app/javascript/packages/document-capture/components/acuant-selfie-capture-canvas.jsx",
"app/javascript/packages/document-capture/components/document-side-acuant-capture.jsx",
"app/javascript/packages/document-capture/components/file-image.jsx",
"app/javascript/packages/document-capture/components/file-input.tsx",
"app/javascript/packages/document-capture/components/in-person-location-full-address-entry-post-office-search-step.tsx",
"app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx",
"app/javascript/packages/document-capture/components/in-person-prepare-step.tsx",
"app/javascript/packages/document-capture/components/submission-interstitial.jsx",
"app/javascript/packages/document-capture/components/submission.jsx",
"app/javascript/packages/document-capture/components/suspense-error-boundary.jsx",
"app/javascript/packages/document-capture/components/tip-list.tsx",
"app/javascript/packages/document-capture/components/unknown-error.tsx",
"spec/javascript/packages/document-capture/context/failed-capture-attempts-spec.jsx",
"spec/javascript/packages/document-capture/hooks/use-async-spec.jsx"
],
"rules": {
"react/prop-types": "off"
}
},
{
"files": [
"app/javascript/packages/components/status-page.spec.tsx",
"app/javascript/packages/document-capture/components/warning.tsx"
],
"rules": {
"react/prop-types": "off",
"react/display-name": "off",
"react/jsx-key": "off",
"react-hooks/exhaustive-deps": "off",
"react/jsx-key": "off"
}
},
{
"files": ["app/javascript/packages/document-capture/higher-order/with-props.jsx"],
"rules": {
"react/display-name": "off"
}
},
{
"files": [
"app/javascript/packages/form-steps/form-steps.spec.tsx",
"spec/javascript/spec_helper.js"
],
"rules": {
"react-hooks/rules-of-hooks": "off"
}
}
Expand Down
32 changes: 26 additions & 6 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ stages:
- after_test
- review
- scan
- deploy_production

workflow:
rules:
Expand Down Expand Up @@ -357,12 +358,7 @@ trigger_devops:
- if: $CI_COMMIT_BRANCH == "main"
trigger: lg/identity-devops

review-app:
stage: review
allow_failure: true
needs:
- job: build-review-image
resource_group: $CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov
.deploy:
image:
name: dtzar/helm-kubectl:latest
script:
Expand Down Expand Up @@ -495,6 +491,15 @@ review-app:
- echo https://$CI_ENVIRONMENT_SLUG-review-app.pivcac.identitysandbox.gov
- echo "Address of Dashboard review app:"
- echo https://$CI_ENVIRONMENT_SLUG-review-app-dashboard.review-app.identitysandbox.gov


review-app:
stage: review
allow_failure: true
needs:
- job: build-review-image
resource_group: $CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov
extends: .deploy
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov
Expand Down Expand Up @@ -525,6 +530,21 @@ stop-review-app:
- if: $CI_PIPELINE_SOURCE != "merge_request_event"
when: never

deploy_production:
stage: deploy_production
allow_failure: false
needs:
- job: build-review-image
resource_group: $CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov
extends: .deploy
environment:
name: production
deployment_tier: production
url: https://$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov
rules:
- if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"


include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ lint_yaml: normalize_yaml ## Lints YAML files
(! git diff --name-only | grep "^config/.*\.yml$$") || (echo "Error: Run 'make normalize_yaml' to normalize YAML"; exit 1)

lint_yarn_workspaces: ## Lints Yarn workspace packages
scripts/validate-workspaces.js
scripts/validate-workspaces.mjs

lint_asset_bundle_size: ## Lints JavaScript and CSS compiled bundle size
@# This enforces an asset size budget to ensure that download sizes are reasonable and to protect
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ def sign_out(*args)
super
end

def resolved_authn_context_result
@resolved_authn_context_result ||= AuthnContextResolver.new(
service_provider: current_sp,
vtr: sp_session[:vtr],
acr_values: sp_session[:acr_values],
).resolve
end

def context
user_session[:context] || UserSessionContext::AUTHENTICATION_CONTEXT
end
Expand Down
24 changes: 18 additions & 6 deletions app/controllers/openid_connect/authorization_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class AuthorizationController < ApplicationController

before_action :block_biometric_requests_in_production, only: [:index]
before_action :build_authorize_form_from_params, only: [:index]
before_action :set_devise_failure_redirect_for_concurrent_session_logout
before_action :pre_validate_authorize_form, only: [:index]
before_action :sign_out_if_prompt_param_is_login_and_user_is_signed_in, only: [:index]
before_action :store_request, only: [:index]
Expand Down Expand Up @@ -73,6 +74,10 @@ def redirect_to_reauthenticate
redirect_to user_two_factor_authentication_url
end

def set_devise_failure_redirect_for_concurrent_session_logout
request.env['devise_session_limited_failure_redirect_url'] = request.url
end

def link_identity_to_service_provider
@authorize_form.link_identity_to_service_provider(current_user, session.id)
end
Expand All @@ -87,6 +92,7 @@ def handle_successful_handoff

redirect_user(
@authorize_form.success_redirect_uri,
@authorize_form.service_provider.issuer,
current_user.uuid,
)

Expand Down Expand Up @@ -144,7 +150,7 @@ def pre_validate_authorize_form
if redirect_uri.nil?
render :error
else
redirect_user(redirect_uri, current_user&.uuid)
redirect_user(redirect_uri, @authorize_form.service_provider.issuer, current_user&.uuid)
end
end

Expand Down Expand Up @@ -199,15 +205,21 @@ def track_events
analytics.sp_redirect_initiated(
ial: event_ial_context.ial,
billed_ial: event_ial_context.bill_for_ial_1_or_2,
sign_in_flow: session[:sign_in_flow],
)
track_billing_events
end

def redirect_user(redirect_uri, user_uuid)
redirect_method = IdentityConfig.store.openid_connect_redirect_uuid_override_map.fetch(
user_uuid,
IdentityConfig.store.openid_connect_redirect,
)
def redirect_user(redirect_uri, issuer, user_uuid)
user_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_uuid_override_map[user_uuid]

sp_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_issuer_override_map[issuer]

redirect_method =
user_redirect_method_override || sp_redirect_method_override ||
IdentityConfig.store.openid_connect_redirect

case redirect_method
when 'client_side'
Expand Down
19 changes: 12 additions & 7 deletions app/controllers/openid_connect/logout_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def delete
analytics.logout_initiated(**result.to_h.except(:redirect_uri))
irs_attempts_api_tracker.logout_initiated(success: result.success?)

redirect_user(redirect_uri, current_user&.uuid)
redirect_user(redirect_uri, @logout_form.service_provider&.issuer, current_user&.uuid)
sign_out
else
render :error
Expand All @@ -44,11 +44,16 @@ def set_devise_failure_redirect_for_concurrent_session_logout
request.env['devise_session_limited_failure_redirect_url'] = request.url
end

def redirect_user(redirect_uri, user_uuid)
redirect_method = IdentityConfig.store.openid_connect_redirect_uuid_override_map.fetch(
user_uuid,
IdentityConfig.store.openid_connect_redirect,
)
def redirect_user(redirect_uri, issuer, user_uuid)
user_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_uuid_override_map[user_uuid]

sp_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_issuer_override_map[issuer]

redirect_method =
user_redirect_method_override || sp_redirect_method_override ||
IdentityConfig.store.openid_connect_redirect

case redirect_method
when 'client_side'
Expand Down Expand Up @@ -115,7 +120,7 @@ def handle_successful_logout_request(result, redirect_uri)

sign_out

redirect_user(redirect_uri, current_user&.uuid)
redirect_user(redirect_uri, @logout_form.service_provider&.issuer, current_user&.uuid)
end
end

Expand Down
6 changes: 5 additions & 1 deletion app/controllers/saml_idp_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
require 'saml_idp'

class SamlIdpController < ApplicationController
# Ordering is significant, since failure URL must be assigned before any references to the user,
# as the concurrent session timeout occurs as a callback to Warden's `after_set_user` hook.
before_action :set_devise_failure_redirect_for_concurrent_session_logout, only: [:auth, :logout]

include SamlIdp::Controller
include SamlIdpAuthConcern
include SamlIdpLogoutConcern
Expand All @@ -17,7 +21,6 @@ class SamlIdpController < ApplicationController

skip_before_action :verify_authenticity_token
before_action :require_path_year
before_action :set_devise_failure_redirect_for_concurrent_session_logout, only: :logout
before_action :handle_banned_user
before_action :bump_auth_count, only: :auth
before_action :redirect_to_sign_in, only: :auth, unless: :user_signed_in?
Expand Down Expand Up @@ -175,6 +178,7 @@ def track_events
analytics.sp_redirect_initiated(
ial: ial_context.ial,
billed_ial: ial_context.bill_for_ial_1_or_2,
sign_in_flow: session[:sign_in_flow],
)
track_billing_events
end
Expand Down
1 change: 1 addition & 0 deletions app/controllers/sign_up/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def process_successful_creation

resend_confirmation = params[:user][:resend]
session[:email] = @register_user_email_form.email
session[:sign_in_flow] = :create_account

redirect_to sign_up_verify_email_url(resend: resend_confirmation)
end
Expand Down
1 change: 1 addition & 0 deletions app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def new
end

def create
session[:sign_in_flow] = :sign_in
return process_locked_out_session if session_bad_password_count_max_exceeded?
return process_locked_out_user if current_user && user_locked_out?(current_user)

Expand Down
7 changes: 6 additions & 1 deletion app/controllers/users/verify_password_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ class VerifyPasswordController < ApplicationController
before_action :confirm_password_reset_profile
before_action :confirm_personal_key

def new; end
def new
analytics.reactivate_account_verify_password_visited
end

def update
result = verify_password_form.submit

irs_attempts_api_tracker.logged_in_profile_change_reauthentication_submitted(
success: result.success?,
)

analytics.reactivate_account_verify_password_submitted(success: result.success?)

if result.success?
handle_success(result)
else
Expand Down
Loading