diff --git a/Gemfile b/Gemfile index e875ce35e..32fd73707 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ ruby "~> #{File.read(File.join(__dir__ , '.ruby-version')).chomp.split('.').slic gem 'lockbox' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 6.1.1' +gem 'rails', '~> 7.0.0' # Our JS/CSS/asset bundler gem "vite_rails", "~> 3.0" @@ -18,6 +18,14 @@ gem "vite_rails", "~> 3.0" # this line is no longer needed once 2.8.0 final is released: gem "mail", ">= 2.8.0.rc1", "< 3" +# avoid buggy net-protocol 0.2.0 which causes some problems with shrine. +# +# See: +# * https://github.com/shrinerb/shrine/issues/609#issuecomment-1340133144 +# * https://github.com/shrinerb/shrine/issues/610 +# +gem "net-protocol", "!= 0.2.0" + gem "view_component", "~> 2.49" gem "alba", "~> 1.6" # for JSON serialization of models @@ -98,7 +106,7 @@ gem 'font-awesome-rails', '~> 4.7' gem "lograge", "< 2" gem "device_detector", "~> 1.0" # user-agent parsing we use for logging -gem 'kithe', "~> 2.6" +gem 'kithe', "~> 2.7", ">= 2.7.1" # attr_son is a dependency of kithe, but we want to make sure it gets require'd directly # to avoid weird auto-loading issues. gem "attr_json", "~> 1.0" @@ -107,7 +115,7 @@ gem "traject", ">= 3.5" # to include support for HTTP basic auth in Solr url gem 'simple_form', "~> 5.0" gem "browse-everything", "~> 1.2" -gem "qa", "~> 5.2" +gem "qa", "~> 5.2", ">= 5.2.10" gem "shrine", "~> 3.3" #, path: "../shrine" # shrine-compat endpoint to get uppy to direct upload to S3 with resumable multi-part upload gem "uppy-s3_multipart" diff --git a/Gemfile.lock b/Gemfile.lock index 3a782d4ee..2f481b4af 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,40 +3,47 @@ GEM specs: Ascii85 (1.1.0) access-granted (1.3.3) - actioncable (6.1.7) - actionpack (= 6.1.7) - activesupport (= 6.1.7) + actioncable (7.0.4) + actionpack (= 7.0.4) + activesupport (= 7.0.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7) - actionpack (= 6.1.7) - activejob (= 6.1.7) - activerecord (= 6.1.7) - activestorage (= 6.1.7) - activesupport (= 6.1.7) + actionmailbox (7.0.4) + actionpack (= 7.0.4) + activejob (= 7.0.4) + activerecord (= 7.0.4) + activestorage (= 7.0.4) + activesupport (= 7.0.4) mail (>= 2.7.1) - actionmailer (6.1.7) - actionpack (= 6.1.7) - actionview (= 6.1.7) - activejob (= 6.1.7) - activesupport (= 6.1.7) + net-imap + net-pop + net-smtp + actionmailer (7.0.4) + actionpack (= 7.0.4) + actionview (= 7.0.4) + activejob (= 7.0.4) + activesupport (= 7.0.4) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.7) - actionview (= 6.1.7) - activesupport (= 6.1.7) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.4) + actionview (= 7.0.4) + activesupport (= 7.0.4) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7) - actionpack (= 6.1.7) - activerecord (= 6.1.7) - activestorage (= 6.1.7) - activesupport (= 6.1.7) + actiontext (7.0.4) + actionpack (= 7.0.4) + activerecord (= 7.0.4) + activestorage (= 7.0.4) + activesupport (= 7.0.4) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.7) - activesupport (= 6.1.7) + actionview (7.0.4) + activesupport (= 7.0.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -44,32 +51,31 @@ GEM active_encode (1.0.0) addressable (~> 2.8) rails - activejob (6.1.7) - activesupport (= 6.1.7) + activejob (7.0.4) + activesupport (= 7.0.4) globalid (>= 0.3.6) - activemodel (6.1.7) - activesupport (= 6.1.7) - activerecord (6.1.7) - activemodel (= 6.1.7) - activesupport (= 6.1.7) + activemodel (7.0.4) + activesupport (= 7.0.4) + activerecord (7.0.4) + activemodel (= 7.0.4) + activesupport (= 7.0.4) activerecord-import (1.4.1) activerecord (>= 4.2) activerecord-postgres_enum (2.0.1) activerecord (>= 5.2) pg - activestorage (6.1.7) - actionpack (= 6.1.7) - activejob (= 6.1.7) - activerecord (= 6.1.7) - activesupport (= 6.1.7) + activestorage (7.0.4) + actionpack (= 7.0.4) + activejob (= 7.0.4) + activerecord (= 7.0.4) + activesupport (= 7.0.4) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7) + activesupport (7.0.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) afm (0.2.2) @@ -229,12 +235,12 @@ GEM factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) - faraday (2.6.0) + faraday (2.7.1) faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-follow_redirects (0.3.0) faraday (>= 1, < 3) - faraday-net_http (3.0.1) + faraday-net_http (3.0.2) faraday-retry (2.0.0) faraday (~> 2.0) faster_s3_url (1.0.0) @@ -309,7 +315,7 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - kithe (2.6.1) + kithe (2.7.1) attr_json (< 2.0.0) fastimage (~> 2.0) fx (>= 0.6.0, < 1) @@ -347,7 +353,7 @@ GEM loofah (2.19.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) - mail (2.8.0.rc1) + mail (2.8.0) mini_mime (>= 0.1.1) net-imap net-pop @@ -378,7 +384,7 @@ GEM net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.1.3) + net-protocol (0.2.1) timeout net-smtp (0.3.3) net-protocol @@ -435,14 +441,14 @@ GEM public_suffix (5.0.0) puma (5.6.5) nio4r (~> 2.0) - qa (5.9.0) + qa (5.10.0) activerecord-import deprecation faraday (< 3.0, != 2.0.0) geocoder ldpath nokogiri (~> 1.6) - rails (>= 5.0, < 6.2) + rails (>= 5.0, < 7.1) rdf racc (1.6.1) rack (2.2.4) @@ -454,21 +460,20 @@ GEM rack rack-test (2.0.2) rack (>= 1.3) - rails (6.1.7) - actioncable (= 6.1.7) - actionmailbox (= 6.1.7) - actionmailer (= 6.1.7) - actionpack (= 6.1.7) - actiontext (= 6.1.7) - actionview (= 6.1.7) - activejob (= 6.1.7) - activemodel (= 6.1.7) - activerecord (= 6.1.7) - activestorage (= 6.1.7) - activesupport (= 6.1.7) + rails (7.0.4) + actioncable (= 7.0.4) + actionmailbox (= 7.0.4) + actionmailer (= 7.0.4) + actionpack (= 7.0.4) + actiontext (= 7.0.4) + actionview (= 7.0.4) + activejob (= 7.0.4) + activemodel (= 7.0.4) + activerecord (= 7.0.4) + activestorage (= 7.0.4) + activesupport (= 7.0.4) bundler (>= 1.15.0) - railties (= 6.1.7) - sprockets-rails (>= 2.0.0) + railties (= 7.0.4) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -478,12 +483,13 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.4.3) loofah (~> 2.3) - railties (6.1.7) - actionpack (= 6.1.7) - activesupport (= 6.1.7) + railties (7.0.4) + actionpack (= 7.0.4) + activesupport (= 7.0.4) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rake (13.0.6) ransack (3.2.1) activerecord (>= 6.1.5) @@ -494,7 +500,7 @@ GEM ffi (~> 1.0) rdf (3.2.9) link_header (~> 0.0, >= 0.0.8) - rdf-vocab (3.2.2) + rdf-vocab (3.2.3) rdf (~> 3.2, >= 3.2.4) redis (5.0.5) redis-client (>= 0.9.0) @@ -620,7 +626,7 @@ GEM thor (1.2.1) thread_safe (0.3.6) tilt (2.0.11) - timeout (0.3.0) + timeout (0.3.1) trailblazer-option (0.1.2) traject (3.7.0) concurrent-ruby (>= 0.8.0) @@ -734,12 +740,13 @@ DEPENDENCIES irb (>= 1.3.1) jbuilder (~> 2.5) kaminari (~> 1.2) - kithe (~> 2.6) + kithe (~> 2.7, >= 2.7.1) listen (~> 3.3) lockbox lograge (< 2) mail (>= 2.8.0.rc1, < 3) matrix (~> 0.4) + net-protocol (!= 0.2.0) oai (~> 1.0, >= 1.0.1) pdf-reader (~> 2.2) pg (>= 0.18, < 2.0) @@ -748,9 +755,9 @@ DEPENDENCIES prawn-svg (< 2) pry-byebug puma (~> 5.6) - qa (~> 5.2) + qa (~> 5.2, >= 5.2.10) rack-attack (~> 6.6) - rails (~> 6.1.1) + rails (~> 7.0.0) rails-controller-testing ransack (~> 3.0) reline (>= 0.2.1) diff --git a/README.md b/README.md index 1fef9ff94..38f9952ec 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,8 @@ We preferentially use Vite.js (an ES6-style JS bundler, https://vite-ruby.netlif * image files and other static assets are for the moment still handled by sprockets, located in ./app/assets/images and fonts/, and referenced via rails sprockets helper methods. We could potentially switch some of these over to vite too. +* vite-ruby tries to install yarn deps using `npx`, but heroku ruby buildpack doesn't offer `npx` we have a workaround to run `yarn install` with `assets:precompile` in local `./Rakefile`. + #### Individual asset dependency special handling notes * blacklight JS and CSS now comes from the [blacklight-frontend npm package](https://www.npmjs.com/package/blacklight-frontend). If you update the blacklight rubygem, you will have to manually make sure to remember to check if a new `blacklight_frontend` npm package is available and update with yarn too! Letting these get out of sync could be disastrous, and is a somewhat confusing manual process. diff --git a/Rakefile b/Rakefile index 102e66219..4bc9cbd6d 100644 --- a/Rakefile +++ b/Rakefile @@ -4,3 +4,17 @@ require_relative 'config/application' Rails.application.load_tasks + + +# Vite tries to install yarn/npm dependencies with `npx ci`, but heroku +# ruby buildpack doesn't have `npx` available, so it will fail. +# +# So we wire up assets:precompile to run `yarn install`, like it did pre-Rails 7, +# as `yarn` is available on heroku ruby buidpack. At worst, this might mean +# yarn install gets run twice, which should be pretty cheap. +# +# See: https://github.com/ElMassimo/vite_ruby/discussions/316 +# +if Rake::Task.task_defined?("assets:precompile") && File.exist?(Rails.root.join("yarn.lock")) + Rake::Task["assets:precompile"].enhance [ "yarn:install" ] +end diff --git a/app/controllers/admin/collections_controller.rb b/app/controllers/admin/collections_controller.rb index a8fa9518f..004e59029 100644 --- a/app/controllers/admin/collections_controller.rb +++ b/app/controllers/admin/collections_controller.rb @@ -113,7 +113,7 @@ def set_collection # enough for now. def collection_params permitted_attributes = [:title, :description, :department] - permitted_attributes << :published if can?(:publish, @collection || Collection) + permitted_attributes << :published if can?(:publish, @collection || Kithe::Model) Kithe::Parameters.new(params). require(:collection). diff --git a/app/controllers/admin/works_controller.rb b/app/controllers/admin/works_controller.rb index fb95cfb57..d8e149576 100644 --- a/app/controllers/admin/works_controller.rb +++ b/app/controllers/admin/works_controller.rb @@ -383,7 +383,7 @@ def batch_update end def batch_publish_toggle - authorize! :publish, Work + authorize! :publish, Kithe::Model unless params[:publish].in?(["on", "off"]) raise ArgumentError.new("Need `publish` param to be `on` or off`") diff --git a/app/policies/access_policy.rb b/app/policies/access_policy.rb index 3889e0dbc..580d687c1 100644 --- a/app/policies/access_policy.rb +++ b/app/policies/access_policy.rb @@ -8,31 +8,19 @@ class AccessPolicy include AccessGranted::Policy def configure - # The most important admin role, gets checked first - - role :admin, proc { |user| !user.nil? && user.admin_user? } do - can :destroy, Work - can :publish, Work - - can :destroy, Collection - can :publish, Collection - - can :destroy, Asset - can :publish, Asset + role :admin, proc { |user| user&.admin_user? } do + can [:destroy, :publish], Kithe::Model + can :access_staff_functions can :admin, User end - # Any logged-in staff considered staff at present role :staff, proc { |user| !user.nil? } do - can :read, Kithe::Model # whether publisehd or not - can :update, Kithe::Model - + can [:read, :update], Kithe::Model # whether published or not can :access_staff_functions can :destroy, Admin::QueueItemComment do |comment, user| comment.user_id == user.id end - end role :public do diff --git a/app/presenters/description_display_formatter.rb b/app/presenters/description_display_formatter.rb index de0ec36ed..2cb3e7449 100644 --- a/app/presenters/description_display_formatter.rb +++ b/app/presenters/description_display_formatter.rb @@ -49,7 +49,8 @@ def format def format_plain return "" if description.blank? - str = strip_tags(description) + # remove all tags, but no need or desire to escape punctuation etc into HTML entities + str = Loofah.fragment(description).text(:encode_special_chars => false) if @truncate str = "#{truncate(str, escape: false, length: @truncate, separator: /\s/)}" diff --git a/spec/presenters/description_display_formatter_spec.rb b/spec/presenters/description_display_formatter_spec.rb index a2313684b..45fe2192f 100644 --- a/spec/presenters/description_display_formatter_spec.rb +++ b/spec/presenters/description_display_formatter_spec.rb @@ -70,5 +70,14 @@ expect(formatted.length).to be < 400 end end + + describe "with html-unsafe chars" do + let(:html_description) { "2 < 3" } + + it "leaves chars alone" do + expect(formatted).to eq "2 < 3" + end + end + end end