From 3c7f1f2f3a30eadffa40fe32409e48caca3a3c9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 23:25:51 +0000 Subject: [PATCH 01/11] Bump rails from 8.0.4 to 8.1.1 Bumps [rails](https://github.com/rails/rails) from 8.0.4 to 8.1.1. - [Release notes](https://github.com/rails/rails/releases) - [Commits](https://github.com/rails/rails/compare/v8.0.4...v8.1.1) --- updated-dependencies: - dependency-name: rails dependency-version: 8.1.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 116 ++++++++++++++++++++++++++------------------------- 2 files changed, 60 insertions(+), 58 deletions(-) diff --git a/Gemfile b/Gemfile index 726f3e6a6..d303b97e8 100644 --- a/Gemfile +++ b/Gemfile @@ -14,7 +14,7 @@ ruby file: '.ruby-version' source 'https://rubygems.org' source 'https://rubygems.org' do # Rails 8.0 - gem 'rails', '~> 8.0.4' + gem 'rails', '~> 8.1.1' # Load ENV from .env(.*) files gem 'dotenv-rails', require: 'dotenv/load' diff --git a/Gemfile.lock b/Gemfile.lock index 31c62c1d4..e439933c3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -181,29 +181,31 @@ PATH GEM remote: https://rubygems.org/ specs: - actioncable (8.0.4) - actionpack (= 8.0.4) - activesupport (= 8.0.4) + action_text-trix (2.1.15) + railties + actioncable (8.1.1) + actionpack (= 8.1.1) + activesupport (= 8.1.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.0.4) - actionpack (= 8.0.4) - activejob (= 8.0.4) - activerecord (= 8.0.4) - activestorage (= 8.0.4) - activesupport (= 8.0.4) + actionmailbox (8.1.1) + actionpack (= 8.1.1) + activejob (= 8.1.1) + activerecord (= 8.1.1) + activestorage (= 8.1.1) + activesupport (= 8.1.1) mail (>= 2.8.0) - actionmailer (8.0.4) - actionpack (= 8.0.4) - actionview (= 8.0.4) - activejob (= 8.0.4) - activesupport (= 8.0.4) + actionmailer (8.1.1) + actionpack (= 8.1.1) + actionview (= 8.1.1) + activejob (= 8.1.1) + activesupport (= 8.1.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.0.4) - actionview (= 8.0.4) - activesupport (= 8.0.4) + actionpack (8.1.1) + actionview (= 8.1.1) + activesupport (= 8.1.1) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -211,27 +213,28 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.0.4) - actionpack (= 8.0.4) - activerecord (= 8.0.4) - activestorage (= 8.0.4) - activesupport (= 8.0.4) + actiontext (8.1.1) + action_text-trix (~> 2.1.15) + actionpack (= 8.1.1) + activerecord (= 8.1.1) + activestorage (= 8.1.1) + activesupport (= 8.1.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.0.4) - activesupport (= 8.0.4) + actionview (8.1.1) + activesupport (= 8.1.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.0.4) - activesupport (= 8.0.4) + activejob (8.1.1) + activesupport (= 8.1.1) globalid (>= 0.3.6) - activemodel (8.0.4) - activesupport (= 8.0.4) - activerecord (8.0.4) - activemodel (= 8.0.4) - activesupport (= 8.0.4) + activemodel (8.1.1) + activesupport (= 8.1.1) + activerecord (8.1.1) + activemodel (= 8.1.1) + activesupport (= 8.1.1) timeout (>= 0.4.0) activerecord-session_store (2.2.0) actionpack (>= 7.0) @@ -239,20 +242,20 @@ GEM cgi (>= 0.3.6) rack (>= 2.0.8, < 4) railties (>= 7.0) - activestorage (8.0.4) - actionpack (= 8.0.4) - activejob (= 8.0.4) - activerecord (= 8.0.4) - activesupport (= 8.0.4) + activestorage (8.1.1) + actionpack (= 8.1.1) + activejob (= 8.1.1) + activerecord (= 8.1.1) + activesupport (= 8.1.1) marcel (~> 1.0) - activesupport (8.0.4) + activesupport (8.1.1) base64 - benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + json logger (>= 1.4.2) minitest (>= 5.1) securerandom (>= 0.3) @@ -317,7 +320,6 @@ GEM thread_safe (~> 0.3, >= 0.3.1) base64 (0.3.0) bcrypt (3.1.20) - benchmark (0.5.0) better_html (2.1.1) actionview (>= 6.0) activesupport (>= 6.0) @@ -544,7 +546,7 @@ GEM timeout net-smtp (0.5.1) net-protocol - nio4r (2.7.4) + nio4r (2.7.5) nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -614,20 +616,20 @@ GEM rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails (8.0.4) - actioncable (= 8.0.4) - actionmailbox (= 8.0.4) - actionmailer (= 8.0.4) - actionpack (= 8.0.4) - actiontext (= 8.0.4) - actionview (= 8.0.4) - activejob (= 8.0.4) - activemodel (= 8.0.4) - activerecord (= 8.0.4) - activestorage (= 8.0.4) - activesupport (= 8.0.4) + rails (8.1.1) + actioncable (= 8.1.1) + actionmailbox (= 8.1.1) + actionmailer (= 8.1.1) + actionpack (= 8.1.1) + actiontext (= 8.1.1) + actionview (= 8.1.1) + activejob (= 8.1.1) + activemodel (= 8.1.1) + activerecord (= 8.1.1) + activestorage (= 8.1.1) + activesupport (= 8.1.1) bundler (>= 1.15.0) - railties (= 8.0.4) + railties (= 8.1.1) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest @@ -648,9 +650,9 @@ GEM request_store sassc-rails (>= 2.0.0) turbolinks - railties (8.0.4) - actionpack (= 8.0.4) - activesupport (= 8.0.4) + railties (8.1.1) + actionpack (= 8.1.1) + activesupport (= 8.1.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -916,7 +918,7 @@ DEPENDENCIES rack (~> 3.2.4)! rack-attack! rack-session (~> 2.1.1)! - rails (~> 8.0.4)! + rails (~> 8.1.1)! rails-pg-extras! rails_email_preview! rspec-instafail! From 5eb3b1e32589c5e8c452ba156463609fe2a35cb7 Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 17:20:14 +0000 Subject: [PATCH 02/11] Start of 8.1 upgrade --- bin/bundler-audit | 6 + bin/ci | 6 + bin/rubocop | 2 +- config/application.rb | 10 +- config/bundler-audit.yml | 5 + config/ci.rb | 19 ++ .../initializers/content_security_policy.rb | 6 +- .../new_framework_defaults_8_1.rb | 74 +++++++ config/puma.rb | 2 +- public/400.html | 31 ++- public/404.html | 200 ++++++++++++------ public/406-unsupported-browser.html | 199 +++++++++++------ public/422.html | 200 ++++++++++++------ public/500.html | 199 +++++++++++------ public/icon.png | Bin 5599 -> 4166 bytes public/icon.svg | 4 +- 16 files changed, 686 insertions(+), 277 deletions(-) create mode 100755 bin/bundler-audit create mode 100755 bin/ci create mode 100644 config/bundler-audit.yml create mode 100644 config/ci.rb create mode 100644 config/initializers/new_framework_defaults_8_1.rb diff --git a/bin/bundler-audit b/bin/bundler-audit new file mode 100755 index 000000000..e2ef22690 --- /dev/null +++ b/bin/bundler-audit @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "bundler/audit/cli" + +ARGV.concat %w[ --config config/bundler-audit.yml ] if ARGV.empty? || ARGV.include?("check") +Bundler::Audit::CLI.start diff --git a/bin/ci b/bin/ci new file mode 100755 index 000000000..4137ad5bb --- /dev/null +++ b/bin/ci @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "active_support/continuous_integration" + +CI = ActiveSupport::ContinuousIntegration +require_relative "../config/ci.rb" diff --git a/bin/rubocop b/bin/rubocop index 40330c0ff..5a2050471 100755 --- a/bin/rubocop +++ b/bin/rubocop @@ -2,7 +2,7 @@ require "rubygems" require "bundler/setup" -# explicit rubocop config increases performance slightly while avoiding config confusion. +# Explicit RuboCop config increases performance slightly while avoiding config confusion. ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) load Gem.bin_path("rubocop", "rubocop") diff --git a/config/application.rb b/config/application.rb index 5e9a3da5a..15d03f013 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,6 +35,11 @@ class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 8.0 + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib( ignore: %w[ assets generators tasks ] ) + # Configuration for the application, engines, and railties goes here. # # These settings can be overridden in specific environments using the files @@ -43,11 +48,6 @@ class Application < Rails::Application # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") - # Please, add to the `ignore` list any other `lib` subdirectories that do - # not contain `.rb` files, or that should not be reloaded or eager loaded. - # Common ones are `templates`, `generators`, or `middleware`, for example. - config.autoload_lib( ignore: %w[ assets generators tasks ] ) - # Add autoloaded paths into `$LOAD_PATH` config.add_autoload_paths_to_load_path = true diff --git a/config/bundler-audit.yml b/config/bundler-audit.yml new file mode 100644 index 000000000..e74b3af94 --- /dev/null +++ b/config/bundler-audit.yml @@ -0,0 +1,5 @@ +# Audit all gems listed in the Gemfile for known security problems by running bin/bundler-audit. +# CVEs that are not relevant to the application can be enumerated on the ignore list below. + +ignore: + - CVE-THAT-DOES-NOT-APPLY diff --git a/config/ci.rb b/config/ci.rb new file mode 100644 index 000000000..8e21e9056 --- /dev/null +++ b/config/ci.rb @@ -0,0 +1,19 @@ +# Run using bin/ci + +CI.run do + step "Setup", "bin/setup --skip-server" + + step "Style: Ruby", "bin/rubocop" + + step "Security: Gem audit", "bin/bundler-audit" + step "Security: Importmap vulnerability audit", "bin/importmap audit" + step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error" + + # Optional: set a green GitHub commit status to unblock PR merge. + # Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`. + # if success? + # step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff" + # else + # failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again." + # end +end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 42751dd88..74b18c5a1 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -18,10 +18,14 @@ # # policy.report_uri "/csp-violation-report-endpoint" # end # -# # Generate session nonces for permitted importmap, inline scripts, and inline styles +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } # config.content_security_policy_nonce_directives = %w(script-src style-src) # +# # Automatically add `nonce` to `javascript_tag`, `javascript_include_tag`, and `stylesheet_link_tag` +# # if the corresponding directives are specified in `content_security_policy_nonce_directives`. +# # config.content_security_policy_nonce_auto = true +# # # Report violations without enforcing the policy. # # config.content_security_policy_report_only = true # end diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb new file mode 100644 index 000000000..8569b5b1c --- /dev/null +++ b/config/initializers/new_framework_defaults_8_1.rb @@ -0,0 +1,74 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 8.1 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and set the `config.load_defaults` to `8.1`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html + +### +# Skips escaping HTML entities and line separators. When set to `false`, the +# JSON renderer no longer escapes these to improve performance. +# +# Example: +# class PostsController < ApplicationController +# def index +# render json: { key: "\u2028\u2029<>&" } +# end +# end +# +# Renders `{"key":"\u2028\u2029\u003c\u003e\u0026"}` with the previous default, but `{"key":"

<>&"}` with the config +# set to `false`. +# +# Applications that want to keep the escaping behavior can set the config to `true`. +#++ +# Rails.configuration.action_controller.escape_json_responses = false + +### +# Skips escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON. +# +# Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019. +# As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset. +#++ +# Rails.configuration.active_support.escape_js_separators_in_json = false + +### +# Raises an error when order dependent finder methods (e.g. `#first`, `#second`) are called without `order` values +# on the relation, and the model does not have any order columns (`implicit_order_column`, `query_constraints`, or +# `primary_key`) to fall back on. +# +# The current behavior of not raising an error has been deprecated, and this configuration option will be removed in +# Rails 8.2. +#++ +# Rails.configuration.active_record.raise_on_missing_required_finder_order_columns = true + +### +# Controls how Rails handles path relative URL redirects. +# When set to `:raise`, Rails will raise an `ActionController::Redirecting::UnsafeRedirectError` +# for relative URLs without a leading slash, which can help prevent open redirect vulnerabilities. +# +# Example: +# redirect_to "example.com" # Raises UnsafeRedirectError +# redirect_to "@attacker.com" # Raises UnsafeRedirectError +# redirect_to "/safe/path" # Works correctly +# +# Applications that want to allow these redirects can set the config to `:log` (previous default) +# to only log warnings, or `:notify` to send ActiveSupport notifications. +#++ +# Rails.configuration.action_controller.action_on_path_relative_redirect = :raise + +### +# Use a Ruby parser to track dependencies between Action View templates +#++ +# Rails.configuration.action_view.render_tracker = :ruby + +### +# When enabled, hidden inputs generated by `form_tag`, `token_tag`, `method_tag`, and the hidden parameter fields +# included in `button_to` forms will omit the `autocomplete="off"` attribute. +# +# Applications that want to keep generating the `autocomplete` attribute for those tags can set it to `false`. +#++ +# Rails.configuration.action_view.remove_hidden_field_autocomplete = true diff --git a/config/puma.rb b/config/puma.rb index ea6cfc07a..10b751864 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -41,7 +41,7 @@ # # preload_app! -# Allow puma to be restarted by `rails restart` command. +# Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart # Specify the PID file. Defaults to tmp/pids/server.pid in development. diff --git a/public/400.html b/public/400.html index 282dbc8cc..640de0339 100644 --- a/public/400.html +++ b/public/400.html @@ -35,12 +35,35 @@ font-weight: 400; letter-spacing: -0.0025em; line-height: 1.4; - min-height: 100vh; + min-height: 100dvh; place-items: center; text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; } + #error-description { + fill: #d30001; + } + + #error-id { + fill: #f0eff0; + } + + @media (prefers-color-scheme: dark) { + body { + background: #101010; + color: #e0e0e0; + } + + #error-description { + fill: #FF6161; + } + + #error-id { + fill: #2c2c2c; + } + } + a { color: inherit; font-weight: 700; @@ -83,13 +106,11 @@ } main article br { - display: none; @media(min-width: 48em) { display: inline; } - } @@ -102,10 +123,10 @@
- +
-

The server cannot process the request due to a client error. Please check the request and try again. If you’re the application owner check the logs for more information.

+

The server cannot process the request due to a client error. Please check the request and try again. If you're the application owner check the logs for more information.

diff --git a/public/404.html b/public/404.html index 2be3af26f..d7f0f1422 100644 --- a/public/404.html +++ b/public/404.html @@ -1,67 +1,135 @@ - - - - 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.

-
- + + + + + + + The page you were looking for doesn't exist (404 Not found) + + + + + + + + + + + + + +
+
+ +
+
+

The page you were looking for doesn't exist. You may have mistyped the address or the page may have moved. If you're the application owner check the logs for more information.

+
+
+ + + diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html index 7cf1e168e..43d2811e8 100644 --- a/public/406-unsupported-browser.html +++ b/public/406-unsupported-browser.html @@ -1,66 +1,135 @@ - - - - Your browser is not supported (406) - - - - - - -
-
-

Your browser is not supported.

-

Please upgrade your browser to continue.

-
-
- + + + + + + + Your browser is not supported (406 Not Acceptable) + + + + + + + + + + + + + +
+
+ +
+
+

Your browser is not supported.
Please upgrade your browser to continue.

+
+
+ + + diff --git a/public/422.html b/public/422.html index c08eac0d1..f12fb4aa1 100644 --- a/public/422.html +++ b/public/422.html @@ -1,67 +1,135 @@ - - - - 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.

-
- + + + + + + + The change you wanted was rejected (422 Unprocessable Entity) + + + + + + + + + + + + + +
+
+ +
+
+

The change you wanted was rejected. Maybe you tried to change something you didn't have access to. If you're the application owner check the logs for more information.

+
+
+ + + diff --git a/public/500.html b/public/500.html index 78a030af2..e4eb18a75 100644 --- a/public/500.html +++ b/public/500.html @@ -1,66 +1,135 @@ - - - - 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.

-
- + + + + + + + We're sorry, but something went wrong (500 Internal Server Error) + + + + + + + + + + + + + +
+
+ +
+
+

We're sorry, but something went wrong.
If you're the application owner check the logs for more information.

+
+
+ + + diff --git a/public/icon.png b/public/icon.png index f3b5abcbde91cf6d7a6a26e514eb7e30f476f950..c4c9dbfbbd2f7c1421ffd5727188146213abbcef 100644 GIT binary patch literal 4166 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 literal 5599 zcmeHL-D}fO6hCR_taXJlzs3}~RuB=Iujyo=i*=1|1FN%E=zNfMTjru|Q<6v{J{U!C zBEE}?j6I3sz>fzN!6}L_BKjcuASk~1;Dg|U_@d{g?V8mM`~#9U+>>*Ezw>c(PjYWA z4(;!cgge6k5E&d$G5`S-0}!Ik>CV(0Y#1}s-v_gAHhja2=W1?nBAte9D2HG<(+)uj z!5=W4u*{VKMw#{V@^NNs4TClr!FAA%ID-*gc{R%CFKEzG<6gm*9s_uy)oMGW*=nJf zw{(Mau|2FHfXIv6C0@Wk5k)F=3jo1srV-C{pl&k&)4_&JjYrnbJiul}d0^NCSh(#7h=F;3{|>EU>h z6U8_p;^wK6mAB(1b92>5-HxJ~V}@3?G`&Qq-TbJ2(&~-HsH6F#8mFaAG(45eT3VPO zM|(Jd<+;UZs;w>0Qw}0>D%{~r{uo_Fl5_Bo3ABWi zWo^j^_T3dxG6J6fH8X)$a^%TJ#PU!=LxF=#Fd9EvKx_x>q<(KY%+y-08?kN9dXjXK z**Q=yt-FTU*13ouhCdqq-0&;Ke{T3sQU9IdzhV9LhQIpq*P{N)+}|Mh+a-VV=x?R} c>%+pvTcMWshj-umO}|qP?%A)*_KlqT3uEqhU;qFB diff --git a/public/icon.svg b/public/icon.svg index 78307ccd4..04b34bf83 100644 --- a/public/icon.svg +++ b/public/icon.svg @@ -1,3 +1,3 @@ - - + + From 2cfbc16d41794bcba09935f2e80ec1b63421ffed Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 17:28:38 +0000 Subject: [PATCH 03/11] Get rid of unnecessary double-quoting --- config/ci.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/ci.rb b/config/ci.rb index 8e21e9056..a923de4e6 100644 --- a/config/ci.rb +++ b/config/ci.rb @@ -1,13 +1,13 @@ # Run using bin/ci CI.run do - step "Setup", "bin/setup --skip-server" + step 'Setup', 'bin/setup --skip-server' - step "Style: Ruby", "bin/rubocop" + step 'Style: Ruby', 'bin/rubocop' - step "Security: Gem audit", "bin/bundler-audit" - step "Security: Importmap vulnerability audit", "bin/importmap audit" - step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error" + step 'Security: Gem audit", "bin/bundler-audit' + step 'Security: Importmap vulnerability audit", "bin/importmap audit' + step 'Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error' # Optional: set a green GitHub commit status to unblock PR merge. # Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`. From 8fbf2f1b722989e52b845e282597352268a314d4 Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 17:49:27 +0000 Subject: [PATCH 04/11] Minor tweaks from 8.1 app:update --- .../initializers/filter_parameter_logging.rb | 2 +- config/puma.rb | 27 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 3babc73f0..d7a5ef02e 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -4,5 +4,5 @@ # Configure sensitive parameters which will be filtered from the log file. Rails.application.config.filter_parameters += %i[ - passw secret token _key crypt salt certificate otp ssn + passw secret token _key crypt salt certificate otp ssn cvn cvc ] diff --git a/config/puma.rb b/config/puma.rb index 10b751864..5ac9f963d 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,24 +1,10 @@ # frozen_string_literal: true -# Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers: a minimum and maximum. -# Any libraries that use thread pools should be configured to match -# the maximum value specified for Puma. Default is set to 5 threads for minimum -# and maximum; this matches the default thread size of Active Record. -# -max_threads_count = ENV.fetch( 'RAILS_MAX_THREADS', 5 ) -min_threads_count = ENV.fetch( 'RAILS_MIN_THREADS', max_threads_count ) -threads min_threads_count, max_threads_count - # Specifies the `worker_timeout` threshold that Puma will use to wait before # terminating a worker in development environments. # worker_timeout 3600 if ENV.fetch( 'RAILS_ENV', 'development' ) == 'development' -# Specifies the `port` Puma will listen on to receive requests; default is 3000 -# -port ENV.fetch( 'PORT', 3000 ) - # Specifies the `environment` that Puma will run in. # environment ENV.fetch( 'RAILS_ENV', 'development' ) @@ -41,6 +27,19 @@ # # preload_app! +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +max_threads_count = ENV.fetch( 'RAILS_MAX_THREADS', 5 ) +min_threads_count = ENV.fetch( 'RAILS_MIN_THREADS', max_threads_count ) +threads min_threads_count, max_threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +port ENV.fetch( 'PORT', 3000 ) + # Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart From 6a11852d552c74ddeb3b941edb8413f29e83c6a2 Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 17:55:32 +0000 Subject: [PATCH 05/11] Freeze string literal --- config/ci.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/ci.rb b/config/ci.rb index a923de4e6..348926291 100644 --- a/config/ci.rb +++ b/config/ci.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Run using bin/ci CI.run do From 9937ee168d5849e464655e970162490d167fd94d Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 17:58:56 +0000 Subject: [PATCH 06/11] Fix rubocop annoyances in temporary update config --- config/initializers/new_framework_defaults_8_1.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb index 8569b5b1c..d01f9171d 100644 --- a/config/initializers/new_framework_defaults_8_1.rb +++ b/config/initializers/new_framework_defaults_8_1.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # # This file eases your Rails 8.1 framework defaults upgrade. @@ -20,8 +22,10 @@ # end # end # +# rubocop:disable Style/AsciiComments # Renders `{"key":"\u2028\u2029\u003c\u003e\u0026"}` with the previous default, but `{"key":"

<>&"}` with the config # set to `false`. +# rubocop:enable Style/AsciiComments # # Applications that want to keep the escaping behavior can set the config to `true`. #++ From 95c292b299c2602bf18f93dbafc5ff717f33f7ae Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 18:44:45 +0000 Subject: [PATCH 07/11] Update setup script for Rails 8.1 --- bin/setup | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bin/setup b/bin/setup index b31090b2a..80bdecfa7 100755 --- a/bin/setup +++ b/bin/setup @@ -5,7 +5,7 @@ require 'fileutils' APP_ROOT = File.expand_path('..', __dir__) def system!(*args) - system(*args) || abort("\n== Command #{args} failed ==") + system(*args, exception: true) end FileUtils.chdir APP_ROOT do @@ -14,7 +14,6 @@ FileUtils.chdir APP_ROOT do # Add necessary setup steps to this file. puts '== Installing dependencies ==' - system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') # puts "\n== Copying sample files ==" @@ -24,14 +23,15 @@ FileUtils.chdir APP_ROOT do puts "\n== Preparing database ==" system! 'bin/rails db:prepare' + system! 'bin/rails db:reset' if ARGV.include?( '--reset' ) puts "\n== Removing old logs and tempfiles ==" system! 'bin/rails log:clear tmp:clear' - puts "\n== Restarting application server ==" - system! 'bin/rails restart' + unless ARGV.include?("--skip-server") + puts "\n== Starting development server ==" + STDOUT.flush # flush the output before exec(2) so that it displays - # puts "\n== Configuring puma-dev ==" - # system "ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}" - # system "curl -Is https://#{APP_NAME}.test/up | head -n 1" + exec 'bin/dev' + end end From e65f04190b0aa92479b49ab355e772990e3706e1 Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 19:48:38 +0000 Subject: [PATCH 08/11] Explicitly load benchmark gem --- Gemfile.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index fe8fda624..05eeb65ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,6 +36,7 @@ PATH amazing_print aws-sdk-s3 bcrypt (~> 3.1.16) + benchmark bugsnag cloudflare-rails devise @@ -320,6 +321,7 @@ GEM thread_safe (~> 0.3, >= 0.3.1) base64 (0.3.0) bcrypt (3.1.20) + benchmark (0.5.0) better_html (2.1.1) actionview (>= 6.0) activesupport (>= 6.0) From 597b99e5b12bbf8c8942bc504aa706912db1f949 Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 19:49:52 +0000 Subject: [PATCH 09/11] Explicitly load benchmark gem --- plugins/ShinyCMS/shinycms.gemspec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/ShinyCMS/shinycms.gemspec b/plugins/ShinyCMS/shinycms.gemspec index 1e8a7d867..ca9594da3 100644 --- a/plugins/ShinyCMS/shinycms.gemspec +++ b/plugins/ShinyCMS/shinycms.gemspec @@ -124,12 +124,15 @@ Gem::Specification.new do |spec| # Fix request.ip when running behind Cloudflare proxying spec.add_dependency 'cloudflare-rails' + # Used to export demo site data from the database + spec.add_dependency 'seed_dump' + # Must be explicitly required from Rails 7.2 onwards spec.add_dependency 'mutex_m' spec.add_dependency 'ostruct' - # Used to export demo site data from the database - spec.add_dependency 'seed_dump' + # Must be explicitly required from Rails 8.2 onwards (warns from 8.1) + spec.add_dependency 'benchmark' # Test coverage spec.add_development_dependency 'simplecov' From 07df379add4da0f29b8169e3160a9dca31542a7d Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Tue, 6 Jan 2026 20:03:51 +0000 Subject: [PATCH 10/11] Finish enabling all of transitional config --- Gemfile | 2 +- config/initializers/new_framework_defaults_8_1.rb | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 199e54ac1..2672f7179 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ ruby file: '.ruby-version' source 'https://rubygems.org' source 'https://rubygems.org' do - # Rails 8.0 + # Rails 8.1 gem 'rails', '~> 8.1.1' # Load ENV from .env(.*) files diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb index d01f9171d..f67c98d7d 100644 --- a/config/initializers/new_framework_defaults_8_1.rb +++ b/config/initializers/new_framework_defaults_8_1.rb @@ -29,7 +29,7 @@ # # Applications that want to keep the escaping behavior can set the config to `true`. #++ -# Rails.configuration.action_controller.escape_json_responses = false +Rails.configuration.action_controller.escape_json_responses = false ### # Skips escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON. @@ -37,7 +37,7 @@ # Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019. # As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset. #++ -# Rails.configuration.active_support.escape_js_separators_in_json = false +Rails.configuration.active_support.escape_js_separators_in_json = false ### # Raises an error when order dependent finder methods (e.g. `#first`, `#second`) are called without `order` values @@ -47,7 +47,7 @@ # The current behavior of not raising an error has been deprecated, and this configuration option will be removed in # Rails 8.2. #++ -# Rails.configuration.active_record.raise_on_missing_required_finder_order_columns = true +Rails.configuration.active_record.raise_on_missing_required_finder_order_columns = true ### # Controls how Rails handles path relative URL redirects. @@ -62,12 +62,12 @@ # Applications that want to allow these redirects can set the config to `:log` (previous default) # to only log warnings, or `:notify` to send ActiveSupport notifications. #++ -# Rails.configuration.action_controller.action_on_path_relative_redirect = :raise +Rails.configuration.action_controller.action_on_path_relative_redirect = :raise ### # Use a Ruby parser to track dependencies between Action View templates #++ -# Rails.configuration.action_view.render_tracker = :ruby +Rails.configuration.action_view.render_tracker = :ruby ### # When enabled, hidden inputs generated by `form_tag`, `token_tag`, `method_tag`, and the hidden parameter fields @@ -75,4 +75,4 @@ # # Applications that want to keep generating the `autocomplete` attribute for those tags can set it to `false`. #++ -# Rails.configuration.action_view.remove_hidden_field_autocomplete = true +Rails.configuration.action_view.remove_hidden_field_autocomplete = true From 04bc1ed2c5b6c01f49f11df4e0e904b6649c8474 Mon Sep 17 00:00:00 2001 From: Denny <2025@denny.me> Date: Wed, 7 Jan 2026 14:39:25 +0000 Subject: [PATCH 11/11] Finish moving to Rails 8.1 --- config/application.rb | 2 +- .../new_framework_defaults_8_1.rb | 78 ------------------- 2 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 config/initializers/new_framework_defaults_8_1.rb diff --git a/config/application.rb b/config/application.rb index 15d03f013..6199cd3c5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -33,7 +33,7 @@ module ShinyHostApp # Rails application class for the ShinyHostApp class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 8.0 + config.load_defaults 8.1 # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb deleted file mode 100644 index f67c98d7d..000000000 --- a/config/initializers/new_framework_defaults_8_1.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -# Be sure to restart your server when you modify this file. -# -# This file eases your Rails 8.1 framework defaults upgrade. -# -# Uncomment each configuration one by one to switch to the new default. -# Once your application is ready to run with all new defaults, you can remove -# this file and set the `config.load_defaults` to `8.1`. -# -# Read the Guide for Upgrading Ruby on Rails for more info on each option. -# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html - -### -# Skips escaping HTML entities and line separators. When set to `false`, the -# JSON renderer no longer escapes these to improve performance. -# -# Example: -# class PostsController < ApplicationController -# def index -# render json: { key: "\u2028\u2029<>&" } -# end -# end -# -# rubocop:disable Style/AsciiComments -# Renders `{"key":"\u2028\u2029\u003c\u003e\u0026"}` with the previous default, but `{"key":"

<>&"}` with the config -# set to `false`. -# rubocop:enable Style/AsciiComments -# -# Applications that want to keep the escaping behavior can set the config to `true`. -#++ -Rails.configuration.action_controller.escape_json_responses = false - -### -# Skips escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON. -# -# Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019. -# As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset. -#++ -Rails.configuration.active_support.escape_js_separators_in_json = false - -### -# Raises an error when order dependent finder methods (e.g. `#first`, `#second`) are called without `order` values -# on the relation, and the model does not have any order columns (`implicit_order_column`, `query_constraints`, or -# `primary_key`) to fall back on. -# -# The current behavior of not raising an error has been deprecated, and this configuration option will be removed in -# Rails 8.2. -#++ -Rails.configuration.active_record.raise_on_missing_required_finder_order_columns = true - -### -# Controls how Rails handles path relative URL redirects. -# When set to `:raise`, Rails will raise an `ActionController::Redirecting::UnsafeRedirectError` -# for relative URLs without a leading slash, which can help prevent open redirect vulnerabilities. -# -# Example: -# redirect_to "example.com" # Raises UnsafeRedirectError -# redirect_to "@attacker.com" # Raises UnsafeRedirectError -# redirect_to "/safe/path" # Works correctly -# -# Applications that want to allow these redirects can set the config to `:log` (previous default) -# to only log warnings, or `:notify` to send ActiveSupport notifications. -#++ -Rails.configuration.action_controller.action_on_path_relative_redirect = :raise - -### -# Use a Ruby parser to track dependencies between Action View templates -#++ -Rails.configuration.action_view.render_tracker = :ruby - -### -# When enabled, hidden inputs generated by `form_tag`, `token_tag`, `method_tag`, and the hidden parameter fields -# included in `button_to` forms will omit the `autocomplete="off"` attribute. -# -# Applications that want to keep generating the `autocomplete` attribute for those tags can set it to `false`. -#++ -Rails.configuration.action_view.remove_hidden_field_autocomplete = true