From 0aea6135ef65c0c011f78fc71432f5992a00ccbd Mon Sep 17 00:00:00 2001 From: Tom Dooner Date: Wed, 19 Feb 2025 16:52:05 -0800 Subject: [PATCH] FFS-1427: Implement custom 404/500 errors --- app/.rubocop.yml | 2 + app/app/controllers/pages_controller.rb | 19 ++++++ app/app/views/pages/error_404.html.erb | 13 ++++ app/app/views/pages/error_500.html.erb | 13 ++++ app/config/application.rb | 3 + app/config/i18n-tasks.yml | 1 + app/config/locales/en.yml | 10 +++ app/config/routes.rb | 3 + app/public/404.html | 67 ------------------- app/public/422.html | 67 ------------------- app/public/500.html | 66 ------------------ app/spec/controllers/pages_controller_spec.rb | 40 +++++++++++ app/zap.conf | 1 + zap_options.conf | 13 ++++ 14 files changed, 118 insertions(+), 200 deletions(-) create mode 100644 app/app/views/pages/error_404.html.erb create mode 100644 app/app/views/pages/error_500.html.erb delete mode 100644 app/public/404.html delete mode 100644 app/public/422.html delete mode 100644 app/public/500.html create mode 100644 app/spec/controllers/pages_controller_spec.rb diff --git a/app/.rubocop.yml b/app/.rubocop.yml index 0c9fe0568..e74571f9a 100644 --- a/app/.rubocop.yml +++ b/app/.rubocop.yml @@ -21,3 +21,5 @@ Layout/IndentationWidth: Layout/IndentationConsistency: Enabled: true EnforcedStyle: normal +Layout/EndAlignment: + EnforcedStyleAlignWith: keyword diff --git a/app/app/controllers/pages_controller.rb b/app/app/controllers/pages_controller.rb index 45f463e4c..d2b235676 100644 --- a/app/app/controllers/pages_controller.rb +++ b/app/app/controllers/pages_controller.rb @@ -1,4 +1,23 @@ class PagesController < ApplicationController def home end + + def error_404 + # When in development environment, you'll need to set + # config.consider_all_requests_local = false + # in config/development.rb for these pages to actually show up. + @cbv_flow = if session[:cbv_flow_id] + CbvFlow.find(session[:cbv_flow_id]) + end + + render status: :not_found, formats: %i[html] + end + + def error_500 + # When in development environment, you'll need to set + # config.consider_all_requests_local = false + # in config/development.rb for these pages to actually show up. + + render status: :internal_server_error, formats: %i[html] + end end diff --git a/app/app/views/pages/error_404.html.erb b/app/app/views/pages/error_404.html.erb new file mode 100644 index 000000000..cc21c9cce --- /dev/null +++ b/app/app/views/pages/error_404.html.erb @@ -0,0 +1,13 @@ +<% header = t(".header") %> +<% content_for :title, header %> +

<%= header %>

+ +
+

<%= t(".error_code_html") %>

+ + <% if @cbv_flow && @cbv_flow.cbv_flow_invitation %> + <%= link_to t(".return_to_entry"), @cbv_flow.cbv_flow_invitation.to_url %> + <% else %> + <%= link_to t(".return_to_welcome"), root_url %> + <% end %> +
diff --git a/app/app/views/pages/error_500.html.erb b/app/app/views/pages/error_500.html.erb new file mode 100644 index 000000000..31842f8a3 --- /dev/null +++ b/app/app/views/pages/error_500.html.erb @@ -0,0 +1,13 @@ +<% header = t(".header") %> +<% content_for :title, header %> +

<%= header %>

+ +
+

<%= t(".error_code_html") %>

+ +

<%= t(".description") %>

+ +

+ <%= link_to t(".refresh"), "javascript:window.location.reload()" %> +

+
diff --git a/app/config/application.rb b/app/config/application.rb index c1af76417..79311d5f3 100644 --- a/app/config/application.rb +++ b/app/config/application.rb @@ -35,6 +35,9 @@ class Application < Rails::Application # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") + # Allow specifying /404 and /500 routes for error pages + config.exceptions_app = self.routes + # Don't generate system test files. config.generators.system_tests = nil config.autoload_paths += %W[#{config.root}/lib] diff --git a/app/config/i18n-tasks.yml b/app/config/i18n-tasks.yml index 2125a508e..f1cb2d12f 100644 --- a/app/config/i18n-tasks.yml +++ b/app/config/i18n-tasks.yml @@ -138,6 +138,7 @@ ignore_missing: - "cbv.expired_invitations.show.body_2" - "help.*" - "shared.header.help" + - "pages.{error_404,error_500}.*" # - 'errors.messages.{accepted,blank,invalid,too_short,too_long}' # - '{devise,simple_form}.*' diff --git a/app/config/locales/en.yml b/app/config/locales/en.yml index 2d7f464e3..b2659df16 100644 --- a/app/config/locales/en.yml +++ b/app/config/locales/en.yml @@ -517,6 +517,16 @@ en: title: Contact your employer's Human Resource Team title: I don't know my username pages: + error_404: + error_code_html: 'Error code: 404' + header: We can't find the page you're looking for + return_to_entry: Return to entry page + return_to_welcome: Return to welcome page + error_500: + description: This is a problem on our end. There was an error with the server and our team has been notified. Please refresh your page, or try again later. + error_code_html: 'Error code: 500' + header: It looks like something went wrong + refresh: Refresh page home: description_1: The SNAP Income Pilot is a new tool designed to help you connect your income details from your employer or payroll provider directly to your SNAP agency. description_2: Please note this pilot is not currently available. diff --git a/app/config/routes.rb b/app/config/routes.rb index b877cddcf..9d6838c9b 100644 --- a/app/config/routes.rb +++ b/app/config/routes.rb @@ -70,4 +70,7 @@ post :user_action, to: "user_events#user_action" end end + + match "/404", to: "pages#error_404", via: :all + match "/500", to: "pages#error_500", via: :all end diff --git a/app/public/404.html b/app/public/404.html deleted file mode 100644 index 2be3af26f..000000000 --- a/app/public/404.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - - -
-
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/app/public/422.html b/app/public/422.html deleted file mode 100644 index c08eac0d1..000000000 --- a/app/public/422.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - - -
-
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/app/public/500.html b/app/public/500.html deleted file mode 100644 index 78a030af2..000000000 --- a/app/public/500.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - - -
-
-

We're sorry, but something went wrong.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/app/spec/controllers/pages_controller_spec.rb b/app/spec/controllers/pages_controller_spec.rb new file mode 100644 index 000000000..d3b4450c5 --- /dev/null +++ b/app/spec/controllers/pages_controller_spec.rb @@ -0,0 +1,40 @@ +require "rails_helper" + +RSpec.describe PagesController do + render_views + + describe "#home" do + it "renders" do + get :home + expect(response).to be_successful + expect(response.body).to include("Welcome") + end + end + + describe "#error_404" do + it "renders with a link to the homepage" do + get :error_404 + expect(response.status).to eq(404) + expect(response.body).to include("We can't find the page") + expect(response.body).to include("Return to welcome") + end + + describe "when a cbv_flow_id is in the session" do + let(:cbv_flow) { create(:cbv_flow) } + + it "renders with a link to restart that CBV flow" do + get :error_404, session: { cbv_flow_id: cbv_flow.id } + expect(response.status).to eq(404) + expect(response.body).to include("Return to entry page") + end + end + end + + describe "#error_500" do + it "renders" do + get :error_500 + expect(response.status).to eq(500) + expect(response.body).to include("It looks like something went wrong") + end + end +end diff --git a/app/zap.conf b/app/zap.conf index 8248449fb..673c1c40d 100644 --- a/app/zap.conf +++ b/app/zap.conf @@ -37,6 +37,7 @@ 10036 WARN (HTTP Server Response Header - Passive/beta) 10037 WARN (Server Leaks Information via "X-Powered-By" HTTP Response Header Field(s) - Passive/release) 10038 FAIL (Content Security Policy (CSP) Header Not Set - Passive/beta) +10038 OUTOFSCOPE sitemap.xml 10039 WARN (X-Backend-Server Header Information Leak - Passive/beta) 10040 FAIL (Secure Pages Include Mixed Content - Passive/release) 10041 WARN (HTTP to HTTPS Insecure Transition in Form Post - Passive/beta) diff --git a/zap_options.conf b/zap_options.conf index 74ae025eb..be0f58ec3 100644 --- a/zap_options.conf +++ b/zap_options.conf @@ -1,3 +1,16 @@ network.globalExclusions.exclusions(0).exclusion.name=Search network.globalExclusions.exclusions(0).exclusion.enabled=true network.globalExclusions.exclusions(0).exclusion.value=/.*\/(?:.{2}\/)?cbv\/employer_search\?authenticity\_token.*/gm + +# Ignore CSP warnings on sitemap.xml +globalalertfilter.filters.filter(0).ruleid=10038 +globalalertfilter.filters.filter(0).newrisk=-1 +globalalertfilter.filters.filter(0).url=.*/sitemap.xml$ +globalalertfilter.filters.filter(0).urlregex=true +globalalertfilter.filters.filter(0).param= +globalalertfilter.filters.filter(0).paramregex=false +globalalertfilter.filters.filter(0).attack= +globalalertfilter.filters.filter(0).attackregex=false +globalalertfilter.filters.filter(0).evidence= +globalalertfilter.filters.filter(0).evidenceregex=false +globalalertfilter.filters.filter(0).enabled=true