camaleon_cms 2.9.2 → 2.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -4
  3. data/Rakefile +3 -16
  4. data/app/apps/plugins/attack/admin_controller.rb +9 -6
  5. data/app/apps/plugins/attack/attack_helper.rb +35 -25
  6. data/app/apps/plugins/authoring_post/authoring_post_helper.rb +23 -16
  7. data/app/apps/plugins/front_cache/admin_controller.rb +14 -10
  8. data/app/apps/plugins/front_cache/config/initializer.rb +1 -1
  9. data/app/apps/plugins/front_cache/config/locales/translation.yml +0 -7
  10. data/app/apps/plugins/front_cache/front_cache_helper.rb +109 -37
  11. data/app/apps/plugins/front_cache/views/admin/settings.html.erb +0 -5
  12. data/app/apps/plugins/visibility_post/config/config.json +1 -0
  13. data/app/apps/plugins/visibility_post/config/routes_front.txt +1 -0
  14. data/app/apps/plugins/visibility_post/front_controller.rb +23 -0
  15. data/app/apps/plugins/visibility_post/visibility_post_helper.rb +141 -70
  16. data/app/apps/themes/camaleon_first/main_helper.rb +18 -12
  17. data/app/apps/themes/default/assets/css/style.css.scss +24 -0
  18. data/app/apps/themes/default/assets/genericons/genericons.css +3 -8
  19. data/app/apps/themes/default/default_helper.rb +2 -1
  20. data/app/apps/themes/default/views/layouts/index.html.erb +3 -1
  21. data/app/apps/themes/new/assets/css/styles.css.scss +24 -0
  22. data/app/apps/themes/new/custom_helper.rb +5 -9
  23. data/app/apps/themes/new/views/layouts/_header.html.erb +3 -1
  24. data/app/assets/javascripts/camaleon_cms/admin/_data.js +16 -0
  25. data/app/assets/javascripts/camaleon_cms/admin/_post.js +5 -2
  26. data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js +14 -3
  27. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js +5 -0
  28. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +8 -6
  29. data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +8 -5
  30. data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +7 -2
  31. data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +2 -1
  32. data/app/controllers/camaleon_cms/admin/categories_controller.rb +19 -4
  33. data/app/controllers/camaleon_cms/admin/comments_controller.rb +0 -1
  34. data/app/controllers/camaleon_cms/admin/installers_controller.rb +32 -1
  35. data/app/controllers/camaleon_cms/admin/media_controller.rb +66 -14
  36. data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -3
  37. data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +10 -4
  38. data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +40 -11
  39. data/app/controllers/camaleon_cms/admin/posts_controller.rb +55 -22
  40. data/app/controllers/camaleon_cms/admin/sessions_controller.rb +237 -44
  41. data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +80 -13
  42. data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +5 -2
  43. data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +26 -3
  44. data/app/controllers/camaleon_cms/admin/settings_controller.rb +5 -3
  45. data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +7 -5
  46. data/app/controllers/camaleon_cms/admin/users_controller.rb +78 -11
  47. data/app/controllers/camaleon_cms/admin_controller.rb +136 -26
  48. data/app/controllers/camaleon_cms/camaleon_controller.rb +37 -92
  49. data/app/controllers/camaleon_cms/frontend_controller.rb +146 -74
  50. data/app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb +20 -5
  51. data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +46 -17
  52. data/app/controllers/concerns/camaleon_cms/frontend_visited_state_concern.rb +72 -0
  53. data/app/controllers/concerns/camaleon_cms/hook_lifecycle_concern.rb +104 -0
  54. data/app/controllers/concerns/camaleon_cms/request_context_concern.rb +113 -0
  55. data/app/controllers/concerns/camaleon_cms/runtime_admin_menu_concern.rb +237 -0
  56. data/app/controllers/concerns/camaleon_cms/runtime_captcha_image_concern.rb +13 -0
  57. data/app/controllers/concerns/camaleon_cms/runtime_html_content_concern.rb +143 -0
  58. data/app/controllers/concerns/camaleon_cms/runtime_shortcode_theme_concern.rb +246 -0
  59. data/app/controllers/concerns/camaleon_cms/runtime_state_concern.rb +13 -0
  60. data/app/controllers/concerns/camaleon_cms/runtime_uploader_concern.rb +54 -0
  61. data/app/controllers/concerns/camaleon_cms/session_captcha_runtime_concern.rb +19 -0
  62. data/app/controllers/concerns/camaleon_cms/session_runtime_concern.rb +40 -0
  63. data/app/decorators/camaleon_cms/application_decorator.rb +11 -8
  64. data/app/decorators/camaleon_cms/category_decorator.rb +3 -2
  65. data/app/decorators/camaleon_cms/post_comment_decorator.rb +13 -5
  66. data/app/decorators/camaleon_cms/post_decorator.rb +68 -50
  67. data/app/decorators/camaleon_cms/post_type_decorator.rb +1 -1
  68. data/app/decorators/camaleon_cms/site_decorator.rb +33 -25
  69. data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +21 -10
  70. data/app/decorators/camaleon_cms/theme_decorator.rb +3 -3
  71. data/app/decorators/camaleon_cms/user_decorator.rb +26 -5
  72. data/app/helpers/camaleon_cms/admin/application_helper.rb +5 -8
  73. data/app/helpers/camaleon_cms/admin/breadcrumb_helper.rb +1 -1
  74. data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +24 -23
  75. data/app/helpers/camaleon_cms/admin/menus_helper.rb +249 -139
  76. data/app/helpers/camaleon_cms/admin/post_type_helper.rb +34 -17
  77. data/app/helpers/camaleon_cms/camaleon_helper.rb +31 -39
  78. data/app/helpers/camaleon_cms/captcha_helper.rb +73 -53
  79. data/app/helpers/camaleon_cms/comment_helper.rb +19 -7
  80. data/app/helpers/camaleon_cms/content_helper.rb +13 -6
  81. data/app/helpers/camaleon_cms/email_helper.rb +7 -3
  82. data/app/helpers/camaleon_cms/frontend/application_helper.rb +6 -1
  83. data/app/helpers/camaleon_cms/frontend/content_select_helper.rb +34 -20
  84. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +143 -66
  85. data/app/helpers/camaleon_cms/frontend/seo_helper.rb +39 -28
  86. data/app/helpers/camaleon_cms/frontend/site_helper.rb +32 -12
  87. data/app/helpers/camaleon_cms/hooks_helper.rb +14 -4
  88. data/app/helpers/camaleon_cms/html_helper.rb +58 -37
  89. data/app/helpers/camaleon_cms/plugins_helper.rb +23 -24
  90. data/app/helpers/camaleon_cms/session_helper.rb +188 -44
  91. data/app/helpers/camaleon_cms/short_code_helper.rb +181 -85
  92. data/app/helpers/camaleon_cms/site_helper.rb +34 -13
  93. data/app/helpers/camaleon_cms/theme_helper.rb +35 -19
  94. data/app/helpers/camaleon_cms/uploader_helper.rb +19 -473
  95. data/app/helpers/camaleon_cms/user_roles_helper.rb +5 -4
  96. data/app/mailers/camaleon_cms/html_mailer.rb +4 -4
  97. data/app/models/camaleon_cms/ability.rb +15 -7
  98. data/app/models/camaleon_cms/category.rb +6 -6
  99. data/app/models/camaleon_cms/custom_field.rb +15 -6
  100. data/app/models/camaleon_cms/custom_field_group.rb +39 -22
  101. data/app/models/camaleon_cms/custom_fields_relationship.rb +140 -2
  102. data/app/models/camaleon_cms/media.rb +8 -2
  103. data/app/models/camaleon_cms/meta.rb +2 -2
  104. data/app/models/camaleon_cms/nav_menu.rb +5 -3
  105. data/app/models/camaleon_cms/nav_menu_item.rb +16 -8
  106. data/app/models/camaleon_cms/plugin.rb +3 -4
  107. data/app/models/camaleon_cms/post.rb +137 -27
  108. data/app/models/camaleon_cms/post_comment.rb +10 -6
  109. data/app/models/camaleon_cms/post_default.rb +42 -12
  110. data/app/models/camaleon_cms/post_relationship.rb +6 -4
  111. data/app/models/camaleon_cms/post_tag.rb +4 -5
  112. data/app/models/camaleon_cms/post_type.rb +21 -13
  113. data/app/models/camaleon_cms/site.rb +39 -29
  114. data/app/models/camaleon_cms/term_relationship.rb +10 -7
  115. data/app/models/camaleon_cms/term_taxonomy.rb +58 -4
  116. data/app/models/camaleon_cms/theme.rb +2 -4
  117. data/app/models/camaleon_cms/user.rb +17 -5
  118. data/app/models/camaleon_cms/user_role.rb +81 -6
  119. data/app/models/camaleon_cms/widget/assigned.rb +11 -6
  120. data/app/models/camaleon_cms/widget/main.rb +12 -8
  121. data/app/models/camaleon_cms/widget/sidebar.rb +3 -8
  122. data/app/models/camaleon_record.rb +89 -5
  123. data/app/models/concerns/camaleon_cms/categories_tags_for_posts.rb +36 -42
  124. data/app/models/concerns/camaleon_cms/common_relationships.rb +18 -5
  125. data/app/models/concerns/camaleon_cms/content_shortcode_gate.rb +73 -0
  126. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +111 -54
  127. data/app/models/concerns/camaleon_cms/metas.rb +31 -6
  128. data/app/models/concerns/camaleon_cms/normalize_attrs.rb +2 -8
  129. data/app/models/concerns/camaleon_cms/site_default_settings.rb +120 -16
  130. data/app/models/concerns/camaleon_cms/user_methods.rb +44 -19
  131. data/app/models/current_request.rb +8 -1
  132. data/app/uploaders/camaleon_cms_aws_uploader.rb +31 -10
  133. data/app/uploaders/camaleon_cms_local_uploader.rb +76 -19
  134. data/app/uploaders/camaleon_cms_uploader.rb +23 -10
  135. data/app/validators/camaleon_cms/post_uniq_validator.rb +5 -4
  136. data/app/validators/camaleon_cms/uniq_validator.rb +1 -1
  137. data/app/validators/camaleon_cms/user_url_validator.rb +215 -36
  138. data/app/views/camaleon_cms/admin/categories/index.html.erb +2 -2
  139. data/app/views/camaleon_cms/admin/installers/form.html.erb +5 -0
  140. data/app/views/camaleon_cms/admin/installers/welcome.html.erb +30 -6
  141. data/app/views/camaleon_cms/admin/plugins/_plugins_list.html.erb +2 -2
  142. data/app/views/camaleon_cms/admin/post_tags/index.html.erb +2 -2
  143. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +1 -1
  144. data/app/views/camaleon_cms/admin/posts/form.html.erb +3 -2
  145. data/app/views/camaleon_cms/admin/posts/index.html.erb +5 -5
  146. data/app/views/camaleon_cms/admin/sessions/back_to_parent.html.erb +39 -0
  147. data/app/views/camaleon_cms/admin/sessions/logout_confirm.html.erb +27 -0
  148. data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +4 -1
  149. data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +1 -1
  150. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +19 -4
  151. data/app/views/camaleon_cms/admin/settings/custom_fields/_render_category_simple.html.erb +1 -1
  152. data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +4 -3
  153. data/app/views/camaleon_cms/admin/settings/shortcodes.html.erb +4 -4
  154. data/app/views/camaleon_cms/admin/settings/site.html.erb +1 -1
  155. data/app/views/camaleon_cms/admin/settings/sites/form.html.erb +1 -1
  156. data/app/views/camaleon_cms/admin/user_roles/form.html.erb +24 -3
  157. data/app/views/camaleon_cms/admin/users/form.html.erb +8 -4
  158. data/app/views/camaleon_cms/admin/users/index.html.erb +1 -1
  159. data/app/views/camaleon_cms/default_theme/partials/_render_custom_field.html.erb +8 -2
  160. data/app/views/camaleon_cms/default_theme/sitemap.html.erb +1 -1
  161. data/app/views/camaleon_cms/default_theme/sitemap.xml.builder +1 -1
  162. data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
  163. data/config/initializers/action_view.rb +42 -5
  164. data/config/initializers/active_record_extension.rb +13 -27
  165. data/config/initializers/assets.rb +52 -23
  166. data/config/initializers/custom_initializers.rb +1 -1
  167. data/config/locales/camaleon_cms/admin/ar.yml +1 -0
  168. data/config/locales/camaleon_cms/admin/de.yml +1 -0
  169. data/config/locales/camaleon_cms/admin/en.yml +36 -0
  170. data/config/locales/camaleon_cms/admin/es.yml +1 -0
  171. data/config/locales/camaleon_cms/admin/fr.yml +1 -0
  172. data/config/locales/camaleon_cms/admin/it.yml +1 -0
  173. data/config/locales/camaleon_cms/admin/nl.yml +1 -0
  174. data/config/locales/camaleon_cms/admin/pt-BR.yml +1 -0
  175. data/config/locales/camaleon_cms/admin/pt.yml +1 -0
  176. data/config/locales/camaleon_cms/admin/ru.yml +1 -0
  177. data/config/locales/camaleon_cms/admin/uk.yml +1 -0
  178. data/config/locales/camaleon_cms/admin/zh-CH.yml +1 -0
  179. data/config/routes/admin.rb +33 -15
  180. data/config/routes/frontend.rb +21 -15
  181. data/lib/camaleon_cms/assets_precompile.rb +86 -0
  182. data/lib/camaleon_cms/captcha_image_generation.rb +65 -0
  183. data/lib/camaleon_cms/content_security.rb +158 -0
  184. data/lib/camaleon_cms/engine.rb +45 -21
  185. data/lib/camaleon_cms/media_security_headers.rb +27 -0
  186. data/lib/camaleon_cms/setup_token.rb +69 -0
  187. data/lib/camaleon_cms/shortcode_registry.rb +102 -0
  188. data/lib/camaleon_cms/svg_content_checker.rb +123 -0
  189. data/lib/camaleon_cms/task_reporter.rb +14 -0
  190. data/lib/camaleon_cms/unsafe_markup.rb +207 -0
  191. data/lib/camaleon_cms/uploader_content_security.rb +248 -0
  192. data/lib/camaleon_cms/uploader_image_processing.rb +166 -0
  193. data/lib/camaleon_cms/uploader_path_security.rb +146 -0
  194. data/lib/camaleon_cms/uploader_pipeline.rb +350 -0
  195. data/lib/camaleon_cms/uploader_support.rb +86 -0
  196. data/lib/camaleon_cms/version.rb +1 -1
  197. data/lib/camaleon_cms.rb +23 -0
  198. data/lib/ext/hash.rb +28 -2
  199. data/lib/ext/string.rb +10 -5
  200. data/lib/ext/translator.rb +10 -2
  201. data/lib/generators/camaleon_cms/gem_plugin_template/app/controllers/plugins/my_plugin/admin_controller.rb +5 -1
  202. data/lib/generators/camaleon_cms/install_generator.rb +7 -4
  203. data/lib/generators/camaleon_cms/install_template/plugin_routes.rb +5 -12
  204. data/lib/generators/camaleon_cms/theme_generator.rb +5 -10
  205. data/lib/generators/camaleon_cms/theme_template/views/layouts/index.html.erb +3 -1
  206. data/lib/plugin_routes.rb +412 -368
  207. data/lib/tasks/camaleon_cms/camaleon_tasks.rake +2 -1
  208. data/lib/tasks/cross_site_field_groups.rake +74 -0
  209. data/lib/tasks/custom_fields_roles.rake +15 -13
  210. data/lib/tasks/orphaned_comments.rake +42 -0
  211. data/lib/tasks/private_upload_acls.rake +31 -0
  212. data/lib/tasks/site_custom_field_groups.rake +36 -0
  213. data/lib/tasks/unsafe_stored_content.rake +42 -0
  214. data/lib/tasks/unsafe_stored_uploads.rake +70 -0
  215. data/lib/tasks/user_field_groups.rake +27 -0
  216. metadata +125 -4
data/lib/ext/string.rb CHANGED
@@ -109,7 +109,7 @@ class String
109
109
  name = tr('\\', '/') # work-around for IE
110
110
  name = File.basename(name)
111
111
  name = name.gsub(sanitize_regexp, '_')
112
- name = "_#{name}" if name =~ /\A\.+\z/
112
+ name = "_#{name}" if /\A\.+\z/.match?(name)
113
113
  name = 'unnamed' if name.empty?
114
114
  name
115
115
  end
@@ -122,7 +122,9 @@ class String
122
122
  end
123
123
 
124
124
  # convert url into custom url with postfix,
125
- # sample: "http://localhost/company/rack_multipart20160124_2288_8xcdjs.jpg".cama_add_postfix_url('thumbs/') into http://localhost/company/thumbs/rack_multipart20160124_2288_8xcdjs.jpg
125
+ # sample:
126
+ # "http://localhost/company/rack_multipart20160124_2288_8xcdjs.jpg".cama_add_postfix_url('thumbs/')
127
+ # into http://localhost/company/thumbs/rack_multipart20160124_2288_8xcdjs.jpg
126
128
  def cama_add_postfix_url(postfix)
127
129
  File.join(File.dirname(self), "#{postfix}#{File.basename(self)}")
128
130
  end
@@ -135,9 +137,12 @@ class String
135
137
 
136
138
  # Parse the url to get the image version
137
139
  # version_name: (String, default empty) version name,
138
- # if this is empty, this will return the image version for thumb of the image, sample: 'http://localhost/my_image.png'.cama_parse_image_version('') => http://localhost/thumb/my_image.png
139
- # if this is present, this will return the image version generated, sample: , sample: 'http://localhost/my_image.png'.cama_parse_image_version('200x200') => http://localhost/thumb/my_image_200x200.png
140
- # check_url: (boolean, default false) if true the image version will be verified, i.e. if the url exist will return version url, if not will return current url
140
+ # if this is empty, this will return the image version for thumb of the image, sample:
141
+ # 'http://localhost/my_image.png'.cama_parse_image_version('') => http://localhost/thumb/my_image.png
142
+ # if this is present, this will return the image version generated, sample:
143
+ # 'http://localhost/my_image.png'.cama_parse_image_version('200x200') => http://localhost/thumb/my_image_200x200.png
144
+ # check_url: (boolean, default false) if true the image version will be verified,
145
+ # i.e. if the url exist will return version url, if not will return current url
141
146
  def cama_parse_image_version(version_name = '', check_url = false)
142
147
  res = File.join(File.dirname(self), 'thumb', "#{File.basename(self).parameterize}#{File.extname(self)}")
143
148
  res = res.cama_add_postfix_file_name("_#{version_name}") if version_name.present?
@@ -6,7 +6,8 @@ class String
6
6
  # The default value if translation is not provided is all text
7
7
  #
8
8
  # $ WpPost.post_title
9
- # $ => "<!--:en-->And this is how the Universe ended.<!--:--><!--:fr-->Et c'est ainsi que l'univers connu cessa d'exister.<!--:-->"
9
+ # $ => "<!--:en-->And this is how the Universe ended.<!--:-->" \
10
+ # "<!--:fr-->Et c'est ainsi que l'univers connu cessa d'exister.<!--:-->"
10
11
  # $ I18n.locale = :en
11
12
  # $ WpPost.post_title.translate
12
13
  # $ => "And this is how the Universe ended."
@@ -33,6 +34,13 @@ class String
33
34
  # return hash of translations for this string
34
35
  # sample: {es: "hola mundo", en: "Hello World"}
35
36
  def translations
37
+ # A frozen receiver cannot carry the memo: Ruby 3.4's nil.to_s returns a frozen —
38
+ # and process-wide shared — empty string, and every literal in a file with the
39
+ # frozen_string_literal magic comment is frozen too. Parse without memoizing for
40
+ # those rather than raising FrozenError (memoizing on a shared instance would be
41
+ # wrong even where it is permitted).
42
+ return split_locales if frozen?
43
+
36
44
  @translations ||= split_locales
37
45
  end
38
46
 
@@ -40,7 +48,7 @@ class String
40
48
  # sample: ["hola mundo", "Hello World"]
41
49
  def translations_array
42
50
  r = translations.map { |_key, value| value }
43
- r.present? ? r : [self]
51
+ r.presence || [self]
44
52
  end
45
53
 
46
54
  protected
@@ -2,6 +2,8 @@ module Plugins
2
2
  module PluginClass
3
3
  class AdminController < CamaleonCms::Apps::PluginsAdminController
4
4
  include Plugins::PluginClass::MainHelper
5
+ # Confines submitted field_options to slugs the plugin actually registered (see save_settings).
6
+ include CamaleonCms::Admin::CustomFieldsConcern
5
7
  def index; end
6
8
 
7
9
  # show settings form
@@ -11,7 +13,9 @@ module Plugins
11
13
  def save_settings
12
14
  @plugin.set_options(params[:options]) if params[:options].present? # save option values
13
15
  @plugin.set_metas(params[:metas]) if params[:metas].present? # save meta values
14
- @plugin.set_field_values(params[:field_options]) if params[:field_options].present? # save custom field values
16
+ # Save custom field values, confined to this plugin's registered slugs (like core's admin
17
+ # controllers) so a forged request cannot write values for slugs the plugin never defined.
18
+ @plugin.set_field_values(cama_permitted_field_options('Plugin')) if params[:field_options].present?
15
19
  redirect_to url_for(action: :settings), notice: 'Settings Saved Successfully'
16
20
  end
17
21
  # add custom methods below ....
@@ -1,5 +1,6 @@
1
1
  require 'rails/generators/base'
2
2
  require 'securerandom'
3
+
3
4
  module CamaleonCms
4
5
  module Generators
5
6
  class InstallGenerator < Rails::Generators::Base
@@ -9,13 +10,13 @@ module CamaleonCms
9
10
  def create_initializer_file
10
11
  copy_file 'system.json', 'config/system.json'
11
12
  copy_file 'plugin_routes.rb', 'lib/plugin_routes.rb'
12
- Dir.mkdir Rails.root.join('app', 'apps').to_s unless Dir.exist?(Rails.root.join('app', 'apps').to_s)
13
+ FileUtils.mkdir_p(Rails.root.join('app/apps'))
13
14
  directory('apps', 'app/apps')
14
15
  directory(File.join($camaleon_engine_dir, 'app/apps/themes').to_s, 'app/apps/themes')
15
16
 
16
17
  sprokects_4_or_newer = defined?(Sprockets::BabelProcessor)
17
18
  if sprokects_4_or_newer
18
- assets_config_dir = Rails.root.join('app', 'assets', 'config')
19
+ assets_config_dir = Rails.root.join('app/assets/config')
19
20
  FileUtils.makedirs(assets_config_dir)
20
21
  assets_config_file = assets_config_dir.join('manifest.js')
21
22
  FileUtils.touch(assets_config_file) unless File.file?(assets_config_file)
@@ -27,7 +28,7 @@ module CamaleonCms
27
28
  //= link_tree ../../apps/themes/default/assets
28
29
  //= link_tree ../../apps/themes/new/assets
29
30
  ASSETS
30
- append_to_file Rails.root.join('config', 'initializers', 'assets.rb'),
31
+ append_to_file Rails.root.join('config/initializers/assets.rb'),
31
32
  <<~PRECOMPILE_MANIFEST
32
33
 
33
34
  Rails.application.config.assets.precompile += %w( manifest.js )
@@ -35,7 +36,9 @@ module CamaleonCms
35
36
  end
36
37
 
37
38
  append_to_file 'Gemfile' do
38
- "\n\n#################### Camaleon CMS include all gems for plugins and themes #################### \nrequire_relative './lib/plugin_routes' \ninstance_eval(PluginRoutes.draw_gems)"
39
+ "\n\n#################### Camaleon CMS include all gems for plugins and themes #################### \n" \
40
+ "require_relative './lib/plugin_routes' \n" \
41
+ 'instance_eval(PluginRoutes.draw_gems)'
39
42
  end
40
43
  end
41
44
  end
@@ -2,22 +2,15 @@ require 'json'
2
2
  class PluginRoutes
3
3
  # draw "all" gems registered for the plugins or themes and camaleon gems
4
4
  def self.draw_gems
5
- res = []
6
- dirs = [] + Dir["#{apps_dir}/plugins/*"] + Dir["#{apps_dir}/themes/*"]
5
+ gemfiles = Dir["#{apps_dir}/{plugins,themes}/*/config/Gemfile"]
7
6
 
8
- dirs.each do |path|
9
- next if ['.', '..'].include?(path)
10
-
11
- g = File.join(path, 'config', 'Gemfile')
12
- res << File.read(g) if File.exist?(g)
13
- end
14
- res.join("\n")
7
+ # map + read + join is very memory efficient for strings
8
+ # Ensuring a newline between files prevents syntax errors if a file lacks a trailing newline
9
+ gemfiles.map { |gem| File.read(gem, encoding: 'UTF-8') }.join("\n\n")
15
10
  end
16
11
 
17
12
  # return apps directory path
18
13
  def self.apps_dir
19
- dir = File.dirname(__FILE__).to_s.split('/')
20
- dir.pop
21
- "#{dir.join('/')}/app/apps"
14
+ File.join(File.dirname(__dir__), 'app', 'apps')
22
15
  end
23
16
  end
@@ -1,5 +1,6 @@
1
1
  require 'rails/generators/base'
2
2
  require 'securerandom'
3
+
3
4
  module CamaleonCms
4
5
  module Generators
5
6
  class ThemeGenerator < Rails::Generators::Base
@@ -12,19 +13,13 @@ module CamaleonCms
12
13
  if behavior == :revoke
13
14
  if Dir.exist?(theme_folder)
14
15
  FileUtils.rm_rf(theme_folder)
15
- puts 'Theme destroyed successfully'
16
+ say 'Theme destroyed successfully'
16
17
  else
17
- puts "This theme doesn't exist"
18
+ say "This theme doesn't exist"
18
19
  end
19
-
20
20
  elsif Dir.exist?(theme_folder)
21
-
22
- puts 'This theme already exist'
21
+ say 'This theme already exist'
23
22
  else
24
-
25
- theme_folder = Rails.root.join('app', 'apps', 'themes', get_theme_name)
26
- return puts("There is already a theme with the same name in: #{theme_folder}") if Dir.exist?(theme_folder)
27
-
28
23
  # tmp copy
29
24
  FileUtils.mkdir_p(theme_folder)
30
25
  FileUtils.copy_entry(File.join($camaleon_engine_dir, 'lib', 'generators', 'camaleon_cms', 'theme_template'),
@@ -37,7 +32,7 @@ module CamaleonCms
37
32
  # helper
38
33
  t = fix_text(File.read(File.join(theme_folder, 'main_helper.rb')))
39
34
  File.open(File.join(theme_folder, 'main_helper.rb'), 'w') { |f| f << t }
40
- puts "Theme successfully created in: #{theme_folder}"
35
+ say "Theme successfully created in: #{theme_folder}"
41
36
  end
42
37
  end
43
38
 
@@ -38,7 +38,9 @@
38
38
  <ul class="dropdown-menu">
39
39
  <li><a href="<%= cama_admin_dashboard_path %>"><%= I18n.t('camaleon_cms.common.dashboard') %></a></li>
40
40
  <li><a href="<%= cama_admin_profile_path %>"><%= I18n.t('camaleon_cms.common.profile') %></a></li>
41
- <li><a href="<%= cama_admin_logout_path %>"><%= I18n.t('camaleon_cms.common.logout') %></a></li>
41
+ <%# Security (audit M6): logout acts only over POST; button_to carries the CSRF
42
+ token without needing rails-ujs on the frontend. %>
43
+ <li><%= button_to I18n.t('camaleon_cms.common.logout'), cama_admin_logout_path, method: :post, class: 'btn btn-link' %></li>
42
44
  </ul>
43
45
  </li>
44
46
  <% else %>