From d5ee8d3191b2a3dc6ab5f8028eeb06677ceef144 Mon Sep 17 00:00:00 2001 From: Andrew Tomaka Date: Thu, 5 Jun 2025 19:25:11 -0400 Subject: [PATCH 1/4] Bump Ruby dependencies --- Gemfile.lock | 133 +++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7922ede..3350abb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/rails/rails.git - revision: 57c24948eb5cc9e5f9a4cecb6f2060f53e2246e1 + revision: 4b7fb1d14b954d2348d2065ff955466479509656 branch: main specs: actioncable (8.1.0.alpha) @@ -34,6 +34,7 @@ GIT rails-html-sanitizer (~> 1.6) useragent (~> 0.16) actiontext (8.1.0.alpha) + action_text-trix (~> 2.1.15) actionpack (= 8.1.0.alpha) activerecord (= 8.1.0.alpha) activestorage (= 8.1.0.alpha) @@ -100,17 +101,19 @@ GIT GEM remote: https://rubygems.org/ specs: + action_text-trix (2.1.15) + railties addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) - ast (2.4.2) - base64 (0.2.0) + ast (2.4.3) + base64 (0.3.0) bcrypt (3.1.20) - benchmark (0.4.0) - bigdecimal (3.1.9) + benchmark (0.4.1) + bigdecimal (3.2.2) bindex (0.8.1) - bootsnap (1.18.4) + bootsnap (1.18.6) msgpack (~> 1.2) - brakeman (7.0.0) + brakeman (7.0.2) racc builder (3.3.0) capybara (3.40.0) @@ -123,13 +126,14 @@ GEM regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) concurrent-ruby (1.3.5) - connection_pool (2.5.0) + connection_pool (2.5.3) crass (1.0.6) date (3.4.1) debug (1.10.0) irb (~> 1.10) reline (>= 0.3.8) - drb (2.2.1) + drb (2.2.3) + erb (5.0.1) erubi (1.13.1) et-orbi (1.2.11) tzinfo @@ -145,17 +149,18 @@ GEM activesupport (>= 6.0.0) railties (>= 6.0.0) io-console (0.8.0) - irb (1.15.1) + irb (1.15.2) pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jbuilder (2.13.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) - json (2.10.1) - language_server-protocol (3.17.0.4) - logger (1.6.5) - loofah (2.24.0) + json (2.12.2) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + loofah (2.24.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -166,9 +171,9 @@ GEM marcel (1.0.4) matrix (0.4.2) mini_mime (1.1.5) - minitest (5.25.4) + minitest (5.25.5) msgpack (1.8.0) - net-imap (0.5.6) + net-imap (0.5.8) date net-protocol net-pop (0.1.2) @@ -178,41 +183,42 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) - nokogiri (1.18.2-aarch64-linux-gnu) + nokogiri (1.18.8-aarch64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.2-arm64-darwin) + nokogiri (1.18.8-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.2-x86_64-linux-gnu) + nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) - parallel (1.26.3) - parser (3.3.7.1) + parallel (1.27.0) + parser (3.3.8.0) ast (~> 2.4.1) racc pp (0.6.2) prettyprint prettyprint (0.2.0) + prism (1.4.0) propshaft (1.1.0) actionpack (>= 7.0.0) activesupport (>= 7.0.0) rack railties (>= 7.0.0) - psych (5.2.3) + psych (5.2.6) date stringio - public_suffix (6.0.1) + public_suffix (6.0.2) puma (6.6.0) nio4r (~> 2.0) raabro (1.4.0) racc (1.8.1) - rack (3.1.9) - rack-session (2.1.0) + rack (3.1.16) + rack-session (2.1.1) base64 (>= 0.1.0) rack (>= 3.0.0) rack-test (2.2.0) rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails-dom-testing (2.2.0) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) @@ -220,51 +226,52 @@ GEM loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) rainbow (3.1.1) - rake (13.2.1) - rdoc (6.12.0) + rake (13.3.0) + rdoc (6.14.0) + erb psych (>= 4.0.0) regexp_parser (2.10.0) - reline (0.6.0) + reline (0.6.1) io-console (~> 0.5) - rexml (3.4.0) - rubocop (1.71.2) + rexml (3.4.1) + rubocop (1.76.0) json (~> 2.3) - language_server-protocol (>= 3.17.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.38.0, < 2.0) + rubocop-ast (>= 1.45.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.38.0) - parser (>= 3.3.1.0) - rubocop-minitest (0.36.0) - rubocop (>= 1.61, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-performance (1.23.1) - rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.29.1) + rubocop-ast (1.45.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-performance (1.25.0) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rails (2.32.0) activesupport (>= 4.2.0) + lint_roller (~> 1.1) rack (>= 1.1) - rubocop (>= 1.52.0, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails-omakase (1.0.0) - rubocop - rubocop-minitest - rubocop-performance - rubocop-rails + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rails-omakase (1.1.0) + rubocop (>= 1.72) + rubocop-performance (>= 1.24) + rubocop-rails (>= 2.30) ruby-progressbar (1.13.0) rubyzip (2.4.1) securerandom (0.4.1) - selenium-webdriver (4.28.0) + selenium-webdriver (4.33.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - solid_cable (3.0.7) + solid_cable (3.0.8) actioncable (>= 7.2) activejob (>= 7.2) activerecord (>= 7.2) @@ -273,20 +280,20 @@ GEM activejob (>= 7.2) activerecord (>= 7.2) railties (>= 7.2) - solid_queue (1.1.3) + solid_queue (1.1.5) activejob (>= 7.1) activerecord (>= 7.1) concurrent-ruby (>= 1.3.1) fugit (~> 1.11.0) railties (>= 7.1) thor (~> 1.3.1) - sqlite3 (2.5.0-aarch64-linux-gnu) - sqlite3 (2.5.0-arm64-darwin) - sqlite3 (2.5.0-x86_64-linux-gnu) + sqlite3 (2.6.0-aarch64-linux-gnu) + sqlite3 (2.6.0-arm64-darwin) + sqlite3 (2.6.0-x86_64-linux-gnu) stimulus-rails (1.3.4) railties (>= 6.0.0) - stringio (3.1.2) - tailwindcss-rails (3.3.1) + stringio (3.1.7) + tailwindcss-rails (3.3.2) railties (>= 7.0.0) tailwindcss-ruby (~> 3.0) tailwindcss-ruby (3.4.17-aarch64-linux) @@ -294,15 +301,15 @@ GEM tailwindcss-ruby (3.4.17-x86_64-linux) thor (1.3.2) timeout (0.4.3) - turbo-rails (2.0.11) - actionpack (>= 6.0.0) - railties (>= 6.0.0) + turbo-rails (2.0.16) + actionpack (>= 7.1.0) + railties (>= 7.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (3.1.4) unicode-emoji (~> 4.0, >= 4.0.4) unicode-emoji (4.0.4) - uri (1.0.2) + uri (1.0.3) useragent (0.16.11) web-console (4.2.1) actionview (>= 6.0.0) @@ -310,13 +317,13 @@ GEM bindex (>= 0.4.0) railties (>= 6.0.0) websocket (1.2.11) - websocket-driver (0.7.7) + websocket-driver (0.8.0) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.7.1) + zeitwerk (2.7.3) PLATFORMS aarch64-linux -- 2.45.3 From c1213aa57f6cbb5486f6dfc38fd853e48a6b69dd Mon Sep 17 00:00:00 2001 From: Andrew Tomaka Date: Thu, 5 Jun 2025 19:26:00 -0400 Subject: [PATCH 2/4] Bump to Rails 8.1 defaults --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index 36fd491..10190b7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ Bundler.require(*Rails.groups) module FamilyBudget 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. -- 2.45.3 From 89fdef1e8a1a50f5b2c3a9859096f4ad1a6fb31c Mon Sep 17 00:00:00 2001 From: Andrew Tomaka Date: Thu, 5 Jun 2025 21:04:49 -0400 Subject: [PATCH 3/4] Run bin/rails app:update --- bin/bundler-audit | 6 +++++ bin/ci | 6 +++++ bin/setup | 1 + config/bundler-audit.yml | 5 ++++ config/ci.rb | 23 +++++++++++++++++++ config/environments/production.rb | 2 +- .../initializers/content_security_policy.rb | 4 ++++ config/initializers/cors.rb | 16 +++++++++++++ .../new_framework_defaults_8_1.rb | 18 +++++++++++++++ 9 files changed, 80 insertions(+), 1 deletion(-) 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/cors.rb diff --git a/bin/bundler-audit b/bin/bundler-audit new file mode 100755 index 0000000..e2ef226 --- /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 0000000..4137ad5 --- /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/setup b/bin/setup index be3db3c..81be011 100755 --- a/bin/setup +++ b/bin/setup @@ -22,6 +22,7 @@ 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" diff --git a/config/bundler-audit.yml b/config/bundler-audit.yml new file mode 100644 index 0000000..e74b3af --- /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 0000000..71e1d2c --- /dev/null +++ b/config/ci.rb @@ -0,0 +1,23 @@ +# 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" + + step "Tests: Rails", "bin/rails test" + step "Tests: System", "bin/rails test:system" + step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant" + + # Optional: set a green GitHub commit status to unblock PR merge. + # Requires the `gh` CLI and 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/environments/production.rb b/config/environments/production.rb index 153be7e..257987c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -59,7 +59,7 @@ Rails.application.configure do # Set host to be used by links generated in mailer templates. config.action_mailer.default_url_options = { host: "example.com" } - # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. + # Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit. # config.action_mailer.smtp_settings = { # user_name: Rails.application.credentials.dig(:smtp, :user_name), # password: Rails.application.credentials.dig(:smtp, :password), diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index b3076b3..d51d713 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -20,6 +20,10 @@ # 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/cors.rb b/config/initializers/cors.rb new file mode 100644 index 0000000..0c5dd99 --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Avoid CORS issues when API is called from the frontend app. +# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin Ajax requests. + +# Read more: https://github.com/cyu/rack-cors + +# Rails.application.config.middleware.insert_before 0, Rack::Cors do +# allow do +# origins "example.com" +# +# resource "*", +# headers: :any, +# methods: [:get, :post, :put, :patch, :delete, :options, :head] +# end +# end diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb index dc5b118..8514864 100644 --- a/config/initializers/new_framework_defaults_8_1.rb +++ b/config/initializers/new_framework_defaults_8_1.rb @@ -8,3 +8,21 @@ # # 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 -- 2.45.3 From b5e9642b21efe40eff2f9362313fa6f56f9b00a5 Mon Sep 17 00:00:00 2001 From: Andrew Tomaka Date: Fri, 6 Jun 2025 00:12:42 -0400 Subject: [PATCH 4/4] Add bundler-audit gem to fix CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rails 8.1 generates bin/bundler-audit but doesn't include the gem by default. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- Gemfile | 3 +++ Gemfile.lock | 13 ++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index 3655681..e0739f8 100644 --- a/Gemfile +++ b/Gemfile @@ -51,6 +51,9 @@ group :development, :test do # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] gem "rubocop-rails-omakase", require: false + + # Audit bundle for known vulnerabilities + gem "bundler-audit", require: false end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 0d78053..f5b4ea1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -116,6 +116,9 @@ GEM brakeman (7.0.2) racc builder (3.3.0) + bundler-audit (0.9.2) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) capybara (3.40.0) addressable matrix @@ -242,7 +245,6 @@ GEM regexp_parser (2.10.0) reline (0.6.1) io-console (~> 0.5) - rexml (3.4.1) rubocop (1.76.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -272,14 +274,7 @@ GEM rubocop-performance (>= 1.24) rubocop-rails (>= 2.30) ruby-progressbar (1.13.0) - rubyzip (2.3.2) securerandom (0.4.1) - selenium-webdriver (4.33.0) - base64 (~> 0.2) - logger (~> 1.4) - rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) - websocket (~> 1.0) solid_cable (3.0.8) actioncable (>= 7.2) activejob (>= 7.2) @@ -326,7 +321,6 @@ GEM bindex (>= 0.4.0) railties (>= 6.0.0) webrick (1.9.1) - websocket (1.2.11) websocket-driver (0.8.0) base64 websocket-extensions (>= 0.1.0) @@ -345,6 +339,7 @@ DEPENDENCIES bcrypt bootsnap brakeman + bundler-audit capybara cuprite debug -- 2.45.3