spina 2.10.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of spina might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd9893ef78c55c7d8a448cce6e8bc04fe22d3f48cde3f07bbef32c03d9aaf00e
4
- data.tar.gz: bc9fd36b1599b808d0313fabb1508506e4cf9e9e4f26908f645f906db3c5c79a
3
+ metadata.gz: 68c17b8a615a45c86dce79d2e4b32a5f7bc4fdbf8f71d94fbdc2f530a68baa48
4
+ data.tar.gz: a85f8e9b3a922c1b3de5866d37bab8bdae583c264e35894baa7871b95aa2eaf5
5
5
  SHA512:
6
- metadata.gz: 6c71bf70aa732fe118cdac86c234a99d88adfd0bf2669551a5f94c6847401ca87d0ebabc5afe522749d95d6c9e5f79c1abec95916080f735e5e29d36461c042c
7
- data.tar.gz: 8d2da67450bc5c70cfd73c61dadca688ccbacb6b971d465559cca95c9cc2969a02c6f8e84e7dd02e794329a08f94e7fcff31f48382ce93ad64ac84c75333e480
6
+ metadata.gz: be079dbe9d681c2d2912946c01127d40ffe84fd28c600be31be1a0a3d56aa0e7591f4ab8423943490aa52f5f70adc04d8eac73df8bd827397ea536e5fb53fce1
7
+ data.tar.gz: fdbb328aba58cbdc660869b2745d6469cbb10a9e40576a3b09205862e4deef8e6ca5f717bb7171039915010c4227e2998a2c1bb86907b194f5844e68a4925dd4
@@ -32,6 +32,13 @@
32
32
  <% if !@page.custom_page? %>
33
33
  <%= link_to t('spina.pages.change_view_template') + "...", helpers.spina.edit_template_admin_page_path(@page), class: "block px-4 py-2 text-sm font-medium leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900", data: {turbo_frame: "modal", action: "reveal#hide"} %>
34
34
  <% end %>
35
+
36
+ <% if @locale.to_sym != I18n.locale.to_sym %>
37
+ <% @page.translations.where(locale: @locale).each do |translation| %>
38
+ <%= button_to t("spina.page_translations.delete", translation: @locale.upcase), helpers.spina.admin_page_translation_path(translation), method: :delete, class: "block w-full text-left px-4 py-2 text-sm leading-5 font-medium text-red-500 cursor-pointer bg-white hover:bg-red-100 hover:bg-opacity-50 hover:text-red-500 focus:outline-none focus:bg-gray-100 focus:text-gray-900", form: {data: {controller: "confirm", confirm_message: t('spina.page_translations.delete_confirmation', subject: @locale.upcase)}} %>
39
+ <% end %>
40
+ <% end %>
41
+
35
42
  <% if @page.deletable? %>
36
43
  <%= button_to t('spina.pages.delete'), helpers.spina.admin_page_path(@page), method: :delete, class: "block w-full text-left px-4 py-2 text-sm leading-5 font-medium text-red-500 cursor-pointer bg-white hover:bg-red-100 hover:bg-opacity-50 hover:text-red-500 focus:outline-none focus:bg-gray-100 focus:text-gray-900", form: {data: {controller: "confirm", confirm_message: t('spina.pages.delete_confirmation', subject: @page.title)}} %>
37
44
  <% else %>
@@ -24,7 +24,7 @@ module Spina
24
24
  private
25
25
 
26
26
  def spina_locales
27
- Spina.config.locales.map(&:to_sym)
27
+ Spina.locales.map(&:to_sym)
28
28
  end
29
29
 
30
30
  end
@@ -18,7 +18,7 @@ module Spina
18
18
  private
19
19
 
20
20
  def spina_locales
21
- Spina.config.locales.map(&:to_sym)
21
+ Spina.locales.map(&:to_sym)
22
22
  end
23
23
 
24
24
  end
@@ -0,0 +1,14 @@
1
+ module Spina
2
+ module Admin
3
+ class PageTranslationsController < AdminController
4
+
5
+ def destroy
6
+ @translation = Spina::Page::Translation.find(params[:id])
7
+ @translation.destroy
8
+ flash[:info] = t("spina.page_translations.deleted")
9
+ redirect_to spina.edit_admin_page_path(@translation.translated_model), status: :see_other
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -6,7 +6,7 @@ module Spina
6
6
 
7
7
  included do
8
8
  # Store each locale's content in [locale]_content as an array of parts
9
- Spina.config.locales.each do |locale|
9
+ Spina.locales.each do |locale|
10
10
  attr_json "#{locale}_content".to_sym, AttrJson::Type::SpinaPartsModel.new, array: true, default: -> { [] }
11
11
  attr_json_setter_monkeypatch "#{locale}_content".to_sym
12
12
  attr_json_accepts_nested_attributes_for "#{locale}_content".to_sym
@@ -15,15 +15,25 @@ module Spina
15
15
  name
16
16
  end
17
17
 
18
+ # Spina previously stored account preferences with symbols as keys.
19
+ # Because of CVE-2022-32224 we're changing that to strings instead.
20
+ # This fallback ensures backwards compatibility, but in the long run this
21
+ # should be refactored to use a simple JSONB-column with Postgres.
18
22
  def self.serialized_attr_accessor(*args)
19
23
  args.each do |method_name|
20
24
  define_method method_name do
25
+ if self.preferences.try(:[], method_name.to_sym).present?
26
+ ActiveSupport::Deprecation.warn("#{method_name} is stored as a symbol. Please set and save it again using #{method_name}= on your Spina::Account model to store it as a string. You can do this from the UI by saving your account preferences.")
27
+ end
28
+
29
+ self.preferences.try(:[], method_name.to_s) ||
21
30
  self.preferences.try(:[], method_name.to_sym)
22
31
  end
23
32
 
24
33
  define_method "#{method_name}=" do |value|
25
34
  self.preferences ||= {}
26
- self.preferences[method_name.to_sym] = value
35
+ self.preferences.except!(method_name.to_sym)
36
+ self.preferences[method_name.to_s] = value
27
37
  end
28
38
  end
29
39
  end
@@ -17,16 +17,16 @@ module Spina
17
17
  has_many :navigations, through: :navigation_items
18
18
 
19
19
  # Pages can belong to a resource
20
- belongs_to :resource, optional: true
20
+ belongs_to :resource, optional: true, touch: true
21
21
 
22
- scope :main, -> { where(resource_id: nil) }
22
+ scope :main, -> { where(resource_id: nil) }
23
23
  scope :regular_pages, -> { main }
24
24
  scope :resource_pages, -> { where.not(resource: nil) }
25
25
  scope :active, -> { where(active: true) }
26
26
  scope :sorted, -> { order(:position) }
27
27
  scope :live, -> { active.where(draft: false) }
28
28
  scope :in_menu, -> { where(show_in_menu: true) }
29
-
29
+
30
30
  before_create :set_default_position
31
31
 
32
32
  # Copy resource from parent
@@ -57,7 +57,7 @@ module Spina
57
57
  def slug
58
58
  url_title.to_s.to_slug.transliterate(*Spina.config.transliterations).normalize.to_s
59
59
  end
60
-
60
+
61
61
  def homepage?
62
62
  name == 'homepage'
63
63
  end
@@ -81,11 +81,11 @@ module Spina
81
81
  def next_sibling
82
82
  siblings.where('position > ?', position).sorted.first
83
83
  end
84
-
84
+
85
85
  def set_materialized_path
86
86
  self.old_path = materialized_path
87
87
  self.materialized_path = localized_materialized_path
88
-
88
+
89
89
  # Append counter to duplicate materialized_path
90
90
  i = 0
91
91
  while duplicate_materialized_path?
@@ -104,7 +104,7 @@ module Spina
104
104
  end
105
105
 
106
106
  private
107
-
107
+
108
108
  def set_default_position
109
109
  self.position ||= self.class.maximum(:position).to_i.next
110
110
  end
@@ -136,7 +136,7 @@ module Spina
136
136
  path_fragments.append(slug) unless homepage?
137
137
  path_fragments.compact.map(&:parameterize).join('/')
138
138
  end
139
-
139
+
140
140
  def duplicate_materialized_path?
141
141
  self.class.where.not(id: id).i18n.where(materialized_path: materialized_path).exists?
142
142
  end
@@ -7,7 +7,7 @@ xml.urlset "xmlns" => "http://www.google.com/schemas/sitemap/0.9", "xmlns:xhtml"
7
7
 
8
8
  # Translations
9
9
  page.translations.each do |translation|
10
- if translation.locale.in? Spina.config.locales.map(&:to_s)
10
+ if translation.locale.in? Spina.locales.map(&:to_s)
11
11
  Mobility.with_locale(translation.locale) do
12
12
  xml.xhtml(:link, rel: "alternate", hreflang: translation.locale, href: "#{request.protocol}#{request.host}#{page.materialized_path}")
13
13
  end
@@ -0,0 +1,16 @@
1
+ # CVE-2022-32224 RAILS
2
+ #
3
+ # There was a bug in Rails allowing YAML-serialized data to be vulnerable to RCE.
4
+ # Spina uses the serialize method to store various preferences stored using symbols.
5
+ # We've now changed this so preferences are stored with strings as keys instead of
6
+ # symbols, but in order to not break existing projects we're adding 'Symbol' to the
7
+ # list of permitted classes.
8
+ # This can be removed in the future.
9
+ #
10
+ # More information:
11
+ # https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
12
+
13
+ if ActiveRecord.respond_to?(:yaml_column_permitted_classes)
14
+ Rails.application.config.active_record.yaml_column_permitted_classes ||= []
15
+ Rails.application.config.active_record.yaml_column_permitted_classes += [Symbol]
16
+ end
@@ -281,6 +281,10 @@ en:
281
281
  show_in_menu: invisible
282
282
  skip_to_first_child: forward to first child page
283
283
  sorting_saved: Sorting saved
284
+ page_translations:
285
+ delete: Delete translation (%{translation})
286
+ delete_confirmation: Are you sure you want to delete this translation <strong>(%{subject})</strong>?
287
+ deleted: Translation deleted
284
288
  permanently_delete: Permanently delete
285
289
  photos:
286
290
  cannot_be_created: 'Image could not be processed:'
@@ -254,6 +254,10 @@ nl:
254
254
  show_in_menu: onzichtbaar
255
255
  skip_to_first_child: doorsturen naar 1<sup>e</sup> subpagina
256
256
  sorting_saved: Volgorde opgeslagen
257
+ page_translations:
258
+ delete: Verwijder vertaling (%{translation})
259
+ delete_confirmation: Weet je zeker dat je deze vertaling <strong>(%{subject})</strong> wilt verwijderen?
260
+ deleted: Vertaling verwijderd
257
261
  permanently_delete: Definitief verwijderen
258
262
  photos:
259
263
  cannot_be_created: 'Foto kon niet worden verwerkt:'
data/config/routes.rb CHANGED
@@ -53,6 +53,7 @@ Spina::Engine.routes.draw do
53
53
 
54
54
  post :sort, on: :collection
55
55
  end
56
+ resources :page_translations, only: [:destroy]
56
57
  resources :parent_pages
57
58
  resource :layout, controller: :layout, only: [:edit, :update]
58
59
 
@@ -92,8 +93,8 @@ Spina::Engine.routes.draw do
92
93
  root to: "pages#homepage"
93
94
 
94
95
  # Pages
95
- get '/:locale/*id' => 'pages#show', constraints: {locale: /#{Spina.config.locales.join('|')}/ }
96
- get '/:locale/' => 'pages#homepage', constraints: {locale: /#{Spina.config.locales.join('|')}/ }
96
+ get '/:locale/*id' => 'pages#show', constraints: {locale: /#{Spina.locales.join('|')}/ }
97
+ get '/:locale/' => 'pages#homepage', constraints: {locale: /#{Spina.locales.join('|')}/ }
97
98
  get '/*id' => 'pages#show', as: "page", controller: 'pages', constraints: -> (request) {
98
99
  request.path.exclude?(ActiveStorage.routes_prefix) &&
99
100
  !(Rails.env.development? && request.path.starts_with?('/rails/'))
@@ -1,7 +1,7 @@
1
1
  module.exports = {
2
2
  content: [
3
3
  <%= Spina.config.tailwind_content.map{|path|"'#{path}'"}.join(",\n") %>
4
- ],
4
+ ],
5
5
  theme: {
6
6
  fontFamily: {
7
7
  body: ['Metropolis'],
@@ -18,8 +18,6 @@ module.exports = {
18
18
  }
19
19
  },
20
20
  plugins: [
21
- require('@tailwindcss/forms'),
22
- require('@tailwindcss/aspect-ratio'),
23
- require('@tailwindcss/typography'),
21
+ <%= Spina.config.tailwind_plugins.map {|plugin|"require('#{plugin}')"}.join(",\n\t") %>
24
22
  ]
25
23
  }
@@ -1,5 +1,5 @@
1
- <% if Spina.config.locales.size > 1 %>
1
+ <% if Spina.locales.size > 1 %>
2
2
  <div id="languages">
3
- <%= Spina.config.locales.map{|l| link_to_unless(l == I18n.locale, l.upcase, root_url(params: {locale: l}))}.join(' / ').html_safe %>
3
+ <%= Spina.locales.map{|l| link_to_unless(l == I18n.locale, l.upcase, root_url(params: {locale: l}))}.join(' / ').html_safe %>
4
4
  </div>
5
5
  <% end %>
@@ -2,7 +2,8 @@ Spina.configure do |config|
2
2
  # Locales
3
3
  # ===============
4
4
  # All locales your content should be available in.
5
- # config.locales = [I18n.default_locale]
5
+ # Defaults to I18n.default_locale
6
+ # config.locales = [:en, :nl]
6
7
 
7
8
  # Backend path
8
9
  # ===============
data/lib/spina/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Spina
2
- VERSION = "2.10.0"
2
+ VERSION = "2.11.0"
3
3
  end
data/lib/spina.rb CHANGED
@@ -22,17 +22,18 @@ module Spina
22
22
  config_accessor :api_key,
23
23
  :api_path,
24
24
  :authentication,
25
- :backend_path,
25
+ :backend_path,
26
26
  :importmap,
27
27
  :frontend_parent_controller,
28
28
  :disable_frontend_routes,
29
29
  :disable_decorator_load,
30
- :locales,
30
+ :locales,
31
31
  :embedded_image_size,
32
32
  :mailer_defaults,
33
33
  :thumbnail_image_size,
34
34
  :party_pooper,
35
35
  :tailwind_content,
36
+ :tailwind_plugins,
36
37
  :queues,
37
38
  :transliterations
38
39
 
@@ -50,17 +51,17 @@ module Spina
50
51
  self.locales = [I18n.default_locale]
51
52
  self.party_pooper = false
52
53
  self.transliterations = %i(latin)
53
-
54
+
54
55
  # Queues for background jobs
55
56
  # - config.queues.page_updates
56
57
  self.queues = ActiveSupport::InheritableOptions.new
57
-
58
+
58
59
  # An importmap specifically meant for Spina
59
60
  self.importmap = Importmap::Map.new
60
-
61
+
61
62
  # Tailwind content
62
- # In order for Tailwind to generate all of the CSS Spina needs,
63
- # it needs to know about every single file in your project
63
+ # In order for Tailwind to generate all of the CSS Spina needs,
64
+ # it needs to know about every single file in your project
64
65
  # that contains any Tailwind class names.
65
66
  # Make sure to add your own glob patterns if you're extending
66
67
  # Spina's UI.
@@ -70,39 +71,41 @@ module Spina
70
71
  "#{Spina::Engine.root}/app/assets/javascripts/**/*.js",
71
72
  "#{Spina::Engine.root}/app/**/application.tailwind.css"]
72
73
 
74
+ self.tailwind_plugins = %w[@tailwindcss/forms @tailwindcss/aspect-ratio @tailwindcss/typography]
75
+
73
76
  # Images that are embedded in the Trix editor are resized to fit
74
77
  # You can optimize this for your website and go for a smaller (or larger) size
75
78
  # Default: 2000x2000px
76
79
  class << self
77
80
  alias_method :config_original, :config
78
-
81
+
79
82
  def config
80
83
  config_obj = self.config_original
81
-
84
+
82
85
  def config_obj.tailwind_purge_content
83
86
  ActiveSupport::Deprecation.warn("config.tailwind_purge_content has been renamed to config.tailwind_content")
84
87
  tailwind_content
85
88
  end
86
-
89
+
87
90
  def config_obj.tailwind_purge_content=(paths)
88
91
  ActiveSupport::Deprecation.warn("config.tailwind_purge_content has been renamed to config.tailwind_content")
89
92
  tailwind_content = paths
90
93
  end
91
-
94
+
92
95
  def config_obj.embedded_image_size=(image_size)
93
96
  if image_size.is_a? String
94
97
  ActiveSupport::Deprecation.warn("Spina embedded_image_size should be set to an array of arguments to be passed to the :resize_to_limit ImageProcessing macro. https://github.com/janko/image_processing/blob/master/doc/minimagick.md#resize_to_limit")
95
98
  end
96
-
99
+
97
100
  self[:embedded_image_size] = image_size
98
101
  end
99
-
102
+
100
103
  config_obj
101
104
  end
102
-
105
+
103
106
  def mounted_at
104
107
  Spina::Engine.routes.find_script_name({})
105
108
  end
106
-
109
+
107
110
  end
108
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spina
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.0
4
+ version: 2.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bram Jetten
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-06 00:00:00.000000000 Z
11
+ date: 2022-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -948,6 +948,7 @@ files:
948
948
  - app/controllers/spina/admin/move_pages_controller.rb
949
949
  - app/controllers/spina/admin/navigation_items_controller.rb
950
950
  - app/controllers/spina/admin/navigations_controller.rb
951
+ - app/controllers/spina/admin/page_translations_controller.rb
951
952
  - app/controllers/spina/admin/pages_controller.rb
952
953
  - app/controllers/spina/admin/parent_pages_controller.rb
953
954
  - app/controllers/spina/admin/password_resets_controller.rb
@@ -1096,6 +1097,7 @@ files:
1096
1097
  - app/views/spina/user_mailer/forgot_password.html.erb
1097
1098
  - app/views/spina/user_mailer/forgot_password.text.erb
1098
1099
  - config/initializers/importmap.rb
1100
+ - config/initializers/yaml_column_permitted_classes.rb
1099
1101
  - config/locales/TH.yml
1100
1102
  - config/locales/bg.yml
1101
1103
  - config/locales/de.yml
@@ -1177,7 +1179,7 @@ metadata:
1177
1179
  documentation_uri: https://www.spinacms.com/docs
1178
1180
  changelog_uri: https://github.com/SpinaCMS/Spina/blob/main/CHANGELOG.md
1179
1181
  source_code_uri: https://github.com/SpinaCMS/Spina
1180
- post_install_message:
1182
+ post_install_message:
1181
1183
  rdoc_options: []
1182
1184
  require_paths:
1183
1185
  - lib
@@ -1192,8 +1194,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1192
1194
  - !ruby/object:Gem::Version
1193
1195
  version: '0'
1194
1196
  requirements: []
1195
- rubygems_version: 3.3.7
1196
- signing_key:
1197
+ rubygems_version: 3.1.6
1198
+ signing_key:
1197
1199
  specification_version: 4
1198
1200
  summary: Spina
1199
1201
  test_files: []