camaleon_cms 2.9.1 → 2.9.3
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.
- checksums.yaml +4 -4
- data/README.md +29 -9
- data/Rakefile +3 -16
- data/app/apps/plugins/attack/admin_controller.rb +9 -6
- data/app/apps/plugins/attack/attack_helper.rb +35 -25
- data/app/apps/plugins/authoring_post/authoring_post_helper.rb +23 -16
- data/app/apps/plugins/front_cache/admin_controller.rb +16 -10
- data/app/apps/plugins/front_cache/config/initializer.rb +1 -1
- data/app/apps/plugins/front_cache/front_cache_helper.rb +57 -24
- data/app/apps/plugins/visibility_post/config/config.json +1 -0
- data/app/apps/plugins/visibility_post/config/routes_front.txt +1 -0
- data/app/apps/plugins/visibility_post/front_controller.rb +23 -0
- data/app/apps/plugins/visibility_post/visibility_post_helper.rb +141 -70
- data/app/apps/themes/camaleon_first/main_helper.rb +18 -12
- data/app/apps/themes/default/assets/css/style.css.scss +24 -0
- data/app/apps/themes/default/assets/genericons/genericons.css +3 -8
- data/app/apps/themes/default/default_helper.rb +2 -1
- data/app/apps/themes/default/views/category.html.erb +1 -1
- data/app/apps/themes/default/views/layouts/index.html.erb +3 -1
- data/app/apps/themes/default/views/post_tag.html.erb +1 -1
- data/app/apps/themes/default/views/post_type.html.erb +1 -1
- data/app/apps/themes/default/views/search.html.erb +1 -1
- data/app/apps/themes/new/assets/css/styles.css.scss +24 -0
- data/app/apps/themes/new/custom_helper.rb +5 -9
- data/app/apps/themes/new/views/category.html.erb +1 -1
- data/app/apps/themes/new/views/layouts/_header.html.erb +3 -1
- data/app/apps/themes/new/views/post_tag.html.erb +1 -1
- data/app/apps/themes/new/views/post_type.html.erb +1 -1
- data/app/apps/themes/new/views/search.html.erb +1 -1
- data/app/assets/javascripts/camaleon_cms/admin/_data.js +16 -0
- data/app/assets/javascripts/camaleon_cms/admin/_post.js +5 -2
- data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js +14 -3
- data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js +5 -0
- data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +29 -10
- data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +8 -5
- data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +9 -2
- data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +4 -3
- data/app/controllers/camaleon_cms/admin/appearances/widgets/sidebar_controller.rb +2 -2
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +27 -8
- data/app/controllers/camaleon_cms/admin/comments_controller.rb +0 -1
- data/app/controllers/camaleon_cms/admin/installers_controller.rb +32 -1
- data/app/controllers/camaleon_cms/admin/media_controller.rb +84 -19
- data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -3
- data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +15 -6
- data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +40 -11
- data/app/controllers/camaleon_cms/admin/posts_controller.rb +58 -22
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +238 -45
- data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +103 -18
- data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +17 -5
- data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +33 -7
- data/app/controllers/camaleon_cms/admin/settings_controller.rb +11 -6
- data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +9 -7
- data/app/controllers/camaleon_cms/admin/users_controller.rb +89 -18
- data/app/controllers/camaleon_cms/admin_controller.rb +144 -26
- data/app/controllers/camaleon_cms/apps/plugins_admin_controller.rb +5 -0
- data/app/controllers/camaleon_cms/camaleon_controller.rb +37 -92
- data/app/controllers/camaleon_cms/frontend_controller.rb +140 -70
- data/app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb +44 -0
- data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +46 -17
- data/app/controllers/concerns/camaleon_cms/frontend_visited_state_concern.rb +72 -0
- data/app/controllers/concerns/camaleon_cms/hook_lifecycle_concern.rb +104 -0
- data/app/controllers/concerns/camaleon_cms/request_context_concern.rb +113 -0
- data/app/controllers/concerns/camaleon_cms/runtime_admin_menu_concern.rb +237 -0
- data/app/controllers/concerns/camaleon_cms/runtime_captcha_image_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_html_content_concern.rb +143 -0
- data/app/controllers/concerns/camaleon_cms/runtime_shortcode_theme_concern.rb +246 -0
- data/app/controllers/concerns/camaleon_cms/runtime_state_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_uploader_concern.rb +54 -0
- data/app/controllers/concerns/camaleon_cms/session_captcha_runtime_concern.rb +19 -0
- data/app/controllers/concerns/camaleon_cms/session_runtime_concern.rb +40 -0
- data/app/decorators/camaleon_cms/application_decorator.rb +11 -8
- data/app/decorators/camaleon_cms/category_decorator.rb +3 -2
- data/app/decorators/camaleon_cms/post_comment_decorator.rb +13 -5
- data/app/decorators/camaleon_cms/post_decorator.rb +67 -51
- data/app/decorators/camaleon_cms/post_type_decorator.rb +1 -1
- data/app/decorators/camaleon_cms/site_decorator.rb +29 -23
- data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +21 -10
- data/app/decorators/camaleon_cms/theme_decorator.rb +3 -3
- data/app/decorators/camaleon_cms/user_decorator.rb +26 -5
- data/app/helpers/camaleon_cms/admin/application_helper.rb +21 -24
- data/app/helpers/camaleon_cms/admin/breadcrumb_helper.rb +1 -1
- data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +24 -23
- data/app/helpers/camaleon_cms/admin/menus_helper.rb +249 -139
- data/app/helpers/camaleon_cms/admin/post_type_helper.rb +51 -31
- data/app/helpers/camaleon_cms/camaleon_helper.rb +31 -39
- data/app/helpers/camaleon_cms/captcha_helper.rb +73 -53
- data/app/helpers/camaleon_cms/comment_helper.rb +87 -41
- data/app/helpers/camaleon_cms/content_helper.rb +13 -6
- data/app/helpers/camaleon_cms/email_helper.rb +7 -3
- data/app/helpers/camaleon_cms/frontend/content_select_helper.rb +34 -20
- data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +144 -67
- data/app/helpers/camaleon_cms/frontend/seo_helper.rb +39 -28
- data/app/helpers/camaleon_cms/frontend/site_helper.rb +32 -12
- data/app/helpers/camaleon_cms/hooks_helper.rb +14 -4
- data/app/helpers/camaleon_cms/html_helper.rb +73 -38
- data/app/helpers/camaleon_cms/plugins_helper.rb +23 -24
- data/app/helpers/camaleon_cms/session_helper.rb +195 -39
- data/app/helpers/camaleon_cms/short_code_helper.rb +181 -85
- data/app/helpers/camaleon_cms/site_helper.rb +43 -9
- data/app/helpers/camaleon_cms/theme_helper.rb +35 -19
- data/app/helpers/camaleon_cms/uploader_helper.rb +19 -422
- data/app/helpers/camaleon_cms/user_roles_helper.rb +5 -4
- data/app/mailers/camaleon_cms/html_mailer.rb +4 -4
- data/app/models/camaleon_cms/ability.rb +65 -105
- data/app/models/camaleon_cms/category.rb +7 -5
- data/app/models/camaleon_cms/custom_field.rb +29 -6
- data/app/models/camaleon_cms/custom_field_group.rb +75 -21
- data/app/models/camaleon_cms/custom_fields_relationship.rb +133 -2
- data/app/models/camaleon_cms/media.rb +8 -2
- data/app/models/camaleon_cms/meta.rb +2 -2
- data/app/models/camaleon_cms/nav_menu.rb +6 -2
- data/app/models/camaleon_cms/nav_menu_item.rb +18 -8
- data/app/models/camaleon_cms/plugin.rb +4 -3
- data/app/models/camaleon_cms/post.rb +113 -27
- data/app/models/camaleon_cms/post_comment.rb +10 -6
- data/app/models/camaleon_cms/post_default.rb +42 -12
- data/app/models/camaleon_cms/post_relationship.rb +6 -4
- data/app/models/camaleon_cms/post_tag.rb +4 -3
- data/app/models/camaleon_cms/post_type.rb +22 -12
- data/app/models/camaleon_cms/site.rb +40 -28
- data/app/models/camaleon_cms/term_relationship.rb +10 -7
- data/app/models/camaleon_cms/term_taxonomy.rb +51 -5
- data/app/models/camaleon_cms/theme.rb +3 -3
- data/app/models/camaleon_cms/user.rb +17 -5
- data/app/models/camaleon_cms/user_role.rb +77 -4
- data/app/models/camaleon_cms/widget/assigned.rb +11 -6
- data/app/models/camaleon_cms/widget/main.rb +13 -7
- data/app/models/camaleon_cms/widget/sidebar.rb +3 -6
- data/app/models/camaleon_record.rb +123 -5
- data/app/models/concerns/camaleon_cms/categories_tags_for_posts.rb +20 -38
- data/app/models/concerns/camaleon_cms/common_relationships.rb +18 -5
- data/app/models/concerns/camaleon_cms/custom_fields_read.rb +115 -58
- data/app/models/concerns/camaleon_cms/metas.rb +32 -7
- data/app/models/concerns/camaleon_cms/normalize_attrs.rb +2 -8
- data/app/models/concerns/camaleon_cms/site_default_settings.rb +120 -16
- data/app/models/concerns/camaleon_cms/user_methods.rb +44 -19
- data/app/models/current_request.rb +23 -0
- data/app/uploaders/camaleon_cms_aws_uploader.rb +39 -11
- data/app/uploaders/camaleon_cms_local_uploader.rb +76 -19
- data/app/uploaders/camaleon_cms_uploader.rb +23 -10
- data/app/validators/camaleon_cms/post_uniq_validator.rb +21 -8
- data/app/validators/camaleon_cms/uniq_validator.rb +1 -1
- data/app/validators/camaleon_cms/user_url_validator.rb +215 -36
- data/app/views/camaleon_cms/admin/appearances/nav_menus/_left_menu_items.html.erb +2 -2
- data/app/views/camaleon_cms/admin/appearances/widgets/main/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/categories/index.html.erb +3 -3
- data/app/views/camaleon_cms/admin/comments/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/comments/list.html.erb +1 -1
- data/app/views/camaleon_cms/admin/installers/form.html.erb +5 -0
- data/app/views/camaleon_cms/admin/installers/welcome.html.erb +30 -6
- data/app/views/camaleon_cms/admin/plugins/_plugins_list.html.erb +2 -2
- data/app/views/camaleon_cms/admin/post_tags/index.html.erb +3 -3
- data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +2 -2
- data/app/views/camaleon_cms/admin/posts/form.html.erb +3 -2
- data/app/views/camaleon_cms/admin/posts/index.html.erb +6 -6
- data/app/views/camaleon_cms/admin/search.html.erb +1 -1
- data/app/views/camaleon_cms/admin/sessions/back_to_parent.html.erb +39 -0
- data/app/views/camaleon_cms/admin/sessions/logout_confirm.html.erb +27 -0
- data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +4 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +42 -6
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render_category_simple.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +5 -4
- data/app/views/camaleon_cms/admin/settings/custom_fields/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/shortcodes.html.erb +4 -4
- data/app/views/camaleon_cms/admin/settings/site.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/user_roles/form.html.erb +102 -7
- data/app/views/camaleon_cms/admin/user_roles/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/users/form.html.erb +8 -4
- data/app/views/camaleon_cms/admin/users/index.html.erb +2 -2
- data/app/views/camaleon_cms/default_theme/partials/_render_custom_field.html.erb +8 -2
- data/app/views/camaleon_cms/default_theme/sitemap.html.erb +1 -1
- data/app/views/camaleon_cms/default_theme/sitemap.xml.builder +1 -1
- data/app/views/layouts/camaleon_cms/admin/_flash_messages.html.erb +2 -2
- data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
- data/config/initializers/action_view.rb +42 -5
- data/config/initializers/active_record_extension.rb +13 -27
- data/config/initializers/assets.rb +52 -23
- data/config/initializers/custom_initializers.rb +3 -3
- data/config/locales/camaleon_cms/admin/ar.yml +7 -2
- data/config/locales/camaleon_cms/admin/de.yml +7 -2
- data/config/locales/camaleon_cms/admin/en.yml +39 -2
- data/config/locales/camaleon_cms/admin/es.yml +7 -2
- data/config/locales/camaleon_cms/admin/fr.yml +7 -2
- data/config/locales/camaleon_cms/admin/it.yml +7 -2
- data/config/locales/camaleon_cms/admin/nl.yml +8 -2
- data/config/locales/camaleon_cms/admin/pt-BR.yml +7 -2
- data/config/locales/camaleon_cms/admin/pt.yml +7 -2
- data/config/locales/camaleon_cms/admin/ru.yml +7 -2
- data/config/locales/camaleon_cms/admin/uk.yml +7 -2
- data/config/locales/camaleon_cms/admin/zh-CH.yml +7 -2
- data/config/routes/admin.rb +33 -15
- data/config/routes/frontend.rb +21 -15
- data/db/migrate/20150611161134_post_table_into_utf8.rb +14 -14
- data/db/migrate/20150926095310_rename_column_posts.rb +3 -3
- data/db/migrate/20151212095328_add_confirm_token_to_users.rb +3 -3
- data/db/migrate/20160504155652_add_feature_to_posts.rb +1 -1
- data/db/migrate/20160504155653_move_first_name_of_users.rb +2 -2
- data/db/migrate/20160609121449_add_group_to_custom_field_values.rb +1 -1
- data/db/migrate/20161215202255_drop_user_relationship_table.rb +1 -1
- data/db/migrate/20180124132318_create_media.rb +1 -1
- data/db/migrate/20180704211100_adjust_field_length.rb +1 -1
- data/lib/camaleon_cms/assets_precompile.rb +86 -0
- data/lib/camaleon_cms/captcha_image_generation.rb +65 -0
- data/lib/camaleon_cms/content_security.rb +158 -0
- data/lib/camaleon_cms/engine.rb +47 -9
- data/lib/camaleon_cms/media_security_headers.rb +27 -0
- data/lib/camaleon_cms/setup_token.rb +69 -0
- data/lib/camaleon_cms/svg_content_checker.rb +123 -0
- data/lib/camaleon_cms/task_reporter.rb +14 -0
- data/lib/camaleon_cms/unsafe_markup.rb +207 -0
- data/lib/camaleon_cms/uploader_content_security.rb +248 -0
- data/lib/camaleon_cms/uploader_image_processing.rb +166 -0
- data/lib/camaleon_cms/uploader_path_security.rb +146 -0
- data/lib/camaleon_cms/uploader_pipeline.rb +350 -0
- data/lib/camaleon_cms/uploader_support.rb +86 -0
- data/lib/camaleon_cms/version.rb +1 -1
- data/lib/camaleon_cms.rb +11 -0
- data/lib/ext/hash.rb +28 -2
- data/lib/ext/string.rb +13 -8
- data/lib/ext/translator.rb +10 -2
- data/lib/generators/camaleon_cms/gem_plugin_template/app/controllers/plugins/my_plugin/admin_controller.rb +5 -1
- data/lib/generators/camaleon_cms/install_generator.rb +7 -4
- data/lib/generators/camaleon_cms/install_template/plugin_routes.rb +5 -12
- data/lib/generators/camaleon_cms/theme_generator.rb +5 -10
- data/lib/generators/camaleon_cms/theme_template/views/layouts/index.html.erb +3 -1
- data/lib/plugin_routes.rb +412 -368
- data/lib/tasks/camaleon_cms/camaleon_tasks.rake +2 -1
- data/lib/tasks/cross_site_field_groups.rake +74 -0
- data/lib/tasks/custom_fields_roles.rake +58 -0
- data/lib/tasks/orphaned_comments.rake +42 -0
- data/lib/tasks/private_upload_acls.rake +31 -0
- data/lib/tasks/site_custom_field_groups.rake +36 -0
- data/lib/tasks/unsafe_stored_content.rake +42 -0
- data/lib/tasks/unsafe_stored_uploads.rake +70 -0
- data/lib/tasks/user_field_groups.rake +27 -0
- metadata +185 -7
|
@@ -126,6 +126,7 @@ pt-BR:
|
|
|
126
126
|
message:
|
|
127
127
|
success: 'Bem-vindo!!!'
|
|
128
128
|
fail: 'Usuário ou senha incorreta'
|
|
129
|
+
too_many_attempts: 'Muitas tentativas malsucedidas. Tente novamente mais tarde.'
|
|
129
130
|
forgot_url_incorrect: 'URL incorreta'
|
|
130
131
|
forgot_expired: 'Expirou o prazo para redefinir a senha.'
|
|
131
132
|
hello: 'Olá'
|
|
@@ -555,7 +556,10 @@ pt-BR:
|
|
|
555
556
|
requires_different_username: 'Requer usuário diferente'
|
|
556
557
|
requires_different_email: 'Requer email diferente'
|
|
557
558
|
new_photo: 'Nova foto'
|
|
558
|
-
|
|
559
|
+
other_permissions: 'Outras permissões'
|
|
560
|
+
select_eval_modal:
|
|
561
|
+
title: 'Permissao perigosa'
|
|
562
|
+
description: 'A permissao select_eval permite executar codigo dinamico a partir das opcoes de campos personalizados. Ao habilitar, pode causar execucao arbitraria de codigo, exposicao de dados e comprometimento total do site caso conteudo nao confiavel seja avaliado.'
|
|
559
563
|
profile: 'Perfil'
|
|
560
564
|
slogan: 'Slogan'
|
|
561
565
|
type_contents: 'TIpo de conteúdos'
|
|
@@ -581,7 +585,7 @@ pt-BR:
|
|
|
581
585
|
media: 'Permissão para o meio'
|
|
582
586
|
publish: 'Você precisa permitir Criar ou Editar, Editar Outro, Editar, Publicar , para habilitar esta permissão'
|
|
583
587
|
themes: 'Permissão para a seção Temas'
|
|
584
|
-
widgets: '
|
|
588
|
+
widgets: 'Permitir a edição de widgets, incluindo salvar código não higienizado.'
|
|
585
589
|
menus: 'Permissão para a seção Menu'
|
|
586
590
|
plugins: 'Permissão para a seção Plugins'
|
|
587
591
|
users: 'Permissão to criar, editar, excluir Usuários'
|
|
@@ -623,6 +627,7 @@ pt-BR:
|
|
|
623
627
|
error_created: 'Nenhum Widget criado.'
|
|
624
628
|
error_updated: 'Nenhum Widget atualizado.'
|
|
625
629
|
not_registered_widgets: 'Não há widgets registrados'
|
|
630
|
+
warning: "Aviso: Os widgets podem armazenar HTML e Javascript não higienizados. Insira apenas o código que você entende e confia."
|
|
626
631
|
intro:
|
|
627
632
|
profile: "Neste lugar você pode ver suas opções de perfis."
|
|
628
633
|
content: "Este bloco contém todo o grupo de conteúdo de seu site. Cada conteúdo pode ter uma estrutura diferente configurada em Configurações => Grupos de conteúdo"
|
|
@@ -124,6 +124,7 @@ pt:
|
|
|
124
124
|
message:
|
|
125
125
|
success: 'Benvindo!!!'
|
|
126
126
|
fail: 'Utilizador ou password incorreta'
|
|
127
|
+
too_many_attempts: 'Demasiadas tentativas falhadas. Tente novamente mais tarde.'
|
|
127
128
|
forgot_url_incorrect: 'Endereço incorreto'
|
|
128
129
|
forgot_expired: 'Expirou o prazo para redefinir a password.'
|
|
129
130
|
hello: 'Olá'
|
|
@@ -553,7 +554,10 @@ pt:
|
|
|
553
554
|
requires_different_username: 'Requer utilizador diferente'
|
|
554
555
|
requires_different_email: 'Requer email diferente'
|
|
555
556
|
new_photo: 'Nova foto'
|
|
556
|
-
|
|
557
|
+
other_permissions: 'Outras permissões'
|
|
558
|
+
select_eval_modal:
|
|
559
|
+
title: 'Permissao perigosa'
|
|
560
|
+
description: 'A permissao select_eval permite executar codigo dinamico a partir das opcoes dos campos personalizados. Ao ativar, pode causar execucao arbitraria de codigo, exposicao de dados e comprometimento total do site se conteudo nao confiavel for avaliado.'
|
|
557
561
|
profile: 'Perfil'
|
|
558
562
|
slogan: 'Slogan'
|
|
559
563
|
type_contents: 'TIpo de conteúdos'
|
|
@@ -579,7 +583,7 @@ pt:
|
|
|
579
583
|
media: 'Permissão para o meio'
|
|
580
584
|
publish: 'Permissão para Criar ou Editar, Editar Outro, Editar, Publicar, para habilitar esta permissão'
|
|
581
585
|
themes: 'Permissão para a secção Temas'
|
|
582
|
-
widgets: '
|
|
586
|
+
widgets: 'Permite a edição de widgets, incluindo salvar código não higienizado.'
|
|
583
587
|
menus: 'Permissão para a secção Menu'
|
|
584
588
|
plugins: 'Permissão para a secção Plugins'
|
|
585
589
|
users: 'Permissão para criar, editar, apagar utilizadores'
|
|
@@ -621,6 +625,7 @@ pt:
|
|
|
621
625
|
error_created: 'Nenhum Widget criado.'
|
|
622
626
|
error_updated: 'Nenhum Widget atualizado.'
|
|
623
627
|
not_registered_widgets: 'Não há widgets registados'
|
|
628
|
+
warning: "Aviso: Os widgets podem armazenar HTML e Javascript não higienizados. Introduza apenas o código que compreende e em que confia."
|
|
624
629
|
intro:
|
|
625
630
|
profile: "Neste lugar pode ver suas opções de perfis."
|
|
626
631
|
content: "Este bloco contém todo o grupo de conteúdo de seu site. Cada conteúdo pode ter uma estrutura diferente configurada em Configurações => Grupos de conteúdo"
|
|
@@ -137,6 +137,7 @@ ru:
|
|
|
137
137
|
message:
|
|
138
138
|
success: 'Добро пожаловать!!!'
|
|
139
139
|
fail: 'Неверное имя пользователя или пароль'
|
|
140
|
+
too_many_attempts: 'Слишком много неудачных попыток. Повторите попытку позже.'
|
|
140
141
|
forgot_url_incorrect: 'Неверный URL'
|
|
141
142
|
forgot_expired: 'Сброс истек.'
|
|
142
143
|
hello: 'Привет'
|
|
@@ -574,7 +575,10 @@ ru:
|
|
|
574
575
|
requires_different_email: 'Требуется другая эл. почта'
|
|
575
576
|
created_pending_validate_email: "Пользователь был создан, пожалуйста, подтвердите вашу электронную почту"
|
|
576
577
|
new_photo: 'Новая фотография'
|
|
577
|
-
|
|
578
|
+
other_permissions: 'Другие разрешения'
|
|
579
|
+
select_eval_modal:
|
|
580
|
+
title: 'Опасное право доступа'
|
|
581
|
+
description: 'Поле типа select_eval позволяет выполнять динамический код из параметров, введённых пользователем. Это может привести к произвольному выполнению кода, утечке данных (в том числе паролей и ключей авторизации) и полной компрометации сайта. Включайте это правл доступа только для доверенных пользователей!'
|
|
578
582
|
profile: 'Профиль'
|
|
579
583
|
slogan: 'Слоган'
|
|
580
584
|
type_contents: 'Тип контента'
|
|
@@ -600,7 +604,7 @@ ru:
|
|
|
600
604
|
media: 'Permission to the midsection'
|
|
601
605
|
publish: 'Вам требуется разрешение на Создание, Редактирование, Редактирование других или Опубликовать чтобы включить это разрешение'
|
|
602
606
|
themes: 'Разрешение тем на раздел'
|
|
603
|
-
widgets: '
|
|
607
|
+
widgets: 'Разрешите редактирование виджетов, в том числе сохранение неочищенного кода.'
|
|
604
608
|
menus: 'Разрешение на раздел Меню'
|
|
605
609
|
plugins: 'Разрешение на раздел Плагинов'
|
|
606
610
|
users: 'Разрешение на создание, редактирование и удаление Пользователей'
|
|
@@ -651,6 +655,7 @@ ru:
|
|
|
651
655
|
error_created: "Боковая панель не создана."
|
|
652
656
|
error_updated: "Боковая панель не обновлена."
|
|
653
657
|
error_deleted: "Боковая панель удалена."
|
|
658
|
+
warning: "Предупреждение: Виджеты могут хранить неочищенный HTML и Javascript. Вводите только тот код, который вы понимаете и которому доверяете."
|
|
654
659
|
intro:
|
|
655
660
|
profile: "Здесь вы можете увидеть настройки вашего профиля."
|
|
656
661
|
content: "Этот блок содержит все группы контента вашего сайта. Каждый контент может иметь различную структуру, их можно настроить в Настройки => Группа контентов"
|
|
@@ -134,6 +134,7 @@ uk:
|
|
|
134
134
|
message:
|
|
135
135
|
success: 'Ласкаво просимо !!!'
|
|
136
136
|
fail: "Неправильне ім'я користувача або пароль"
|
|
137
|
+
too_many_attempts: 'Забагато невдалих спроб. Спробуйте пізніше.'
|
|
137
138
|
forgot_url_incorrect: 'Неправильний URL'
|
|
138
139
|
forgot_expired: 'Скидання закінчилось.'
|
|
139
140
|
hello: 'Привіт'
|
|
@@ -574,7 +575,10 @@ uk:
|
|
|
574
575
|
requires_different_email: 'Потрібні інші ел. пошта '
|
|
575
576
|
created_pending_validate_email: "Користувач був створений, будь ласка, підтвердіть вашу електронну пошту"
|
|
576
577
|
new_photo: 'Нова фотографія'
|
|
577
|
-
|
|
578
|
+
other_permissions: 'Інші роздільності'
|
|
579
|
+
select_eval_modal:
|
|
580
|
+
title: 'Небезпечний дозвіл'
|
|
581
|
+
description: 'Дозвіл select_eval дозволяє виконувати динамічний код з параметрів користувацьких полів. Увімкнення може призвести до довільного виконання коду, витоку даних і повної компрометації сайту, якщо обробляється недовірений вміст.'
|
|
578
582
|
profile: 'Профіль'
|
|
579
583
|
slogan: 'Слоган'
|
|
580
584
|
type_contents: 'Тип Контенту'
|
|
@@ -600,7 +604,7 @@ uk:
|
|
|
600
604
|
media: 'Permission to the midsection'
|
|
601
605
|
publish: 'Вам потрібен дозвіл на Створення, редагування, Редагування інших або Опублікувати щоб включити цей дозвіл'
|
|
602
606
|
themes: 'Дозвіл тим на розділ'
|
|
603
|
-
widgets: '
|
|
607
|
+
widgets: 'Уможливлено редагування віджетів, зокрема збереження непродезінфікованого коду.'
|
|
604
608
|
menus: 'Дозвіл на розділ Меню'
|
|
605
609
|
plugins: 'Дозвіл на розділ Плагінів'
|
|
606
610
|
users: 'Дозвіл на створення, редагування і видалення користувачів'
|
|
@@ -651,6 +655,7 @@ uk:
|
|
|
651
655
|
error_created: "Бічна панель не створена."
|
|
652
656
|
error_updated: "Бічна панель не оновлена."
|
|
653
657
|
error_deleted: "Бічна панель видалена."
|
|
658
|
+
warning: "Попередження: Віджети можуть зберігати непродезінфіковані HTML та Javascript. Вводьте лише той код, який ви розумієте та якому довіряєте."
|
|
654
659
|
intro:
|
|
655
660
|
profile: "Тут ви можете побачити налаштування вашого профілю."
|
|
656
661
|
content: "Цей блок містить всі групи контенту вашого сайту. Кожен контент може мати різну структуру, яких можна налаштувати в Налаштування => Група контентів"
|
|
@@ -143,6 +143,7 @@ zh-CN:
|
|
|
143
143
|
message:
|
|
144
144
|
success: '欢迎登录!!!'
|
|
145
145
|
fail: '用户名或密码不正确'
|
|
146
|
+
too_many_attempts: '尝试次数过多,请稍后再试。'
|
|
146
147
|
forgot_url_incorrect: '链接错误'
|
|
147
148
|
forgot_expired: '重置链接已过期。'
|
|
148
149
|
hello: '您好'
|
|
@@ -607,7 +608,10 @@ zh-CN:
|
|
|
607
608
|
role_can_not_be_deleted: '无法删除此角色'
|
|
608
609
|
user_can_not_delete_own_account: '用户不能删除自己的帐户'
|
|
609
610
|
new_photo: '新建照片'
|
|
610
|
-
|
|
611
|
+
other_permissions: '其他权限'
|
|
612
|
+
select_eval_modal:
|
|
613
|
+
title: '危险权限'
|
|
614
|
+
description: 'select_eval 权限允许从自定义字段选项中执行动态代码。启用后,如果评估不受信任的内容,可能导致任意代码执行、数据泄露以及站点被完全攻陷。'
|
|
611
615
|
profile: '资料'
|
|
612
616
|
slogan: '标语'
|
|
613
617
|
type_contents: '内容的类型'
|
|
@@ -633,7 +637,7 @@ zh-CN:
|
|
|
633
637
|
media: '媒体资源部分'
|
|
634
638
|
publish: '开启该权限,允许创建,编辑, 或公开'
|
|
635
639
|
themes: '主题部分'
|
|
636
|
-
widgets: '
|
|
640
|
+
widgets: '允许编辑小部件,包括保存未经清理的代码。'
|
|
637
641
|
menus: '菜单部分'
|
|
638
642
|
plugins: '插件部分'
|
|
639
643
|
users: '创建,编辑,删除用户'
|
|
@@ -684,6 +688,7 @@ zh-CN:
|
|
|
684
688
|
error_created: '侧边栏创建失败'
|
|
685
689
|
error_updated: '侧边栏更新失败'
|
|
686
690
|
error_deleted: "侧边栏已删除."
|
|
691
|
+
warning: "警告:小组件可以存储未经清理的 HTML 和 Javascript。仅输入您理解和信任的代码。"
|
|
687
692
|
intro:
|
|
688
693
|
profile: "在这个地方,您可以看到您的个人资料选项."
|
|
689
694
|
content: "此块包含您网站的所有内容组。 每个内容可以具有在 设置 => 内容组"
|
data/config/routes/admin.rb
CHANGED
|
@@ -8,17 +8,22 @@ Rails.application.routes.draw do
|
|
|
8
8
|
get 'search'
|
|
9
9
|
get 'login' => 'sessions#login'
|
|
10
10
|
post 'login' => 'sessions#login_post'
|
|
11
|
-
|
|
11
|
+
# Security (audit M6): logout changes state, so it acts only over POST. The GET renders a
|
|
12
|
+
# confirmation page instead of 404ing -- frontend themes across the ecosystem link this
|
|
13
|
+
# path -- and the impersonation flow keeps its redirect (see SessionsController#logout).
|
|
14
|
+
match 'logout' => 'sessions#logout', via: %i[get post]
|
|
15
|
+
match 'back_to_parent' => 'sessions#back_to_parent', via: %i[get post]
|
|
12
16
|
match 'forgot' => 'sessions#forgot', via: %i[get post patch]
|
|
13
|
-
match 'confirm_email' => 'sessions#confirm_email', via: %i[get post
|
|
17
|
+
match 'confirm_email' => 'sessions#confirm_email', via: %i[get post patch]
|
|
14
18
|
match 'register' => 'sessions#register', via: %i[get post patch]
|
|
15
19
|
match 'api/:method', action: :api, via: %i[get post], as: :api
|
|
16
20
|
|
|
17
21
|
resources :post_type, as: :post_type do
|
|
18
22
|
resources :posts, controller: 'posts' do
|
|
19
23
|
# resources :comments
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
# Security (audit M6): state-changing member actions must not ride GET links.
|
|
25
|
+
patch :trash
|
|
26
|
+
patch :restore
|
|
22
27
|
collection do
|
|
23
28
|
match 'ajax', via: %i[get post patch]
|
|
24
29
|
end
|
|
@@ -41,7 +46,8 @@ Rails.application.routes.draw do
|
|
|
41
46
|
match 'profile/edit' => 'users#profile_edit', via: %i[get post patch]
|
|
42
47
|
resources :users, controller: 'users' do
|
|
43
48
|
patch 'updated_ajax'
|
|
44
|
-
|
|
49
|
+
# Security (audit M6): forces a session switch -- the highest-value CSRF target here.
|
|
50
|
+
post :impersonate, on: :member
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
resources :user_roles, controller: 'user_roles' do
|
|
@@ -53,11 +59,11 @@ Rails.application.routes.draw do
|
|
|
53
59
|
collection do
|
|
54
60
|
post 'get_items/:key', action: :get_items, as: :get_items
|
|
55
61
|
post 'reorder'
|
|
56
|
-
|
|
62
|
+
match 'list', via: %i[get post]
|
|
57
63
|
end
|
|
58
64
|
end
|
|
59
65
|
get 'site'
|
|
60
|
-
|
|
66
|
+
post 'test_email' # Security (audit M6): sends mail; must not be a CSRF-able GET
|
|
61
67
|
get 'theme'
|
|
62
68
|
post 'save_theme'
|
|
63
69
|
get 'languages'
|
|
@@ -73,25 +79,33 @@ Rails.application.routes.draw do
|
|
|
73
79
|
resources :comments, controller: 'comments' do
|
|
74
80
|
get 'answer'
|
|
75
81
|
post 'save_answer'
|
|
76
|
-
|
|
82
|
+
patch 'toggle_status' # Security (audit M6): flips moderation state
|
|
77
83
|
end
|
|
78
84
|
end
|
|
79
85
|
|
|
80
86
|
namespace :appearances do
|
|
81
|
-
|
|
87
|
+
# Security (audit M6): this legacy widgets surface predates the widgets/{main,sidebar,
|
|
88
|
+
# assign} controllers (its target controller is long gone) but still declared delete
|
|
89
|
+
# endpoints reachable over CSRF-exempt GET. The non-GET verbs keep the paths and helpers
|
|
90
|
+
# routable for any external binding.
|
|
91
|
+
delete 'widgets'
|
|
82
92
|
match 'widgets_save', via: %i[post patch]
|
|
83
|
-
|
|
93
|
+
patch 'widget_delete'
|
|
84
94
|
get 'render_form'
|
|
85
95
|
|
|
86
96
|
resources :themes, only: [:index] do
|
|
87
97
|
collection do
|
|
88
98
|
get 'preview'
|
|
89
99
|
# match "settings", via: [:get, :post, :patch]
|
|
90
|
-
|
|
100
|
+
# Security (audit M6): load_data clears and re-imports post types, nav menus and sliders
|
|
101
|
+
# -- a state change that must not ride a CSRF-exempt GET link.
|
|
102
|
+
match 'load_data', via: %i[post patch]
|
|
91
103
|
end
|
|
92
104
|
end
|
|
93
105
|
resources :nav_menus, except: :show do
|
|
94
|
-
|
|
106
|
+
# Security (audit M6): destroys a menu item -- must not ride a CSRF-exempt GET. The
|
|
107
|
+
# admin JS sends a token-bearing DELETE (nav_menu.js).
|
|
108
|
+
delete 'item_delete/:id' => :delete_menu_item, as: :delete_menu_item
|
|
95
109
|
get 'custom_settings/:id' => :custom_settings, as: :custom_settings
|
|
96
110
|
post 'save_custom_settings/:id' => :save_custom_settings, as: :save_custom_settings
|
|
97
111
|
get 'edit_menu_item/:id' => :edit_menu_item, as: :edit_menu_item
|
|
@@ -114,8 +128,10 @@ Rails.application.routes.draw do
|
|
|
114
128
|
end
|
|
115
129
|
|
|
116
130
|
resources :plugins, only: %i[index destroy] do
|
|
117
|
-
|
|
118
|
-
|
|
131
|
+
# Security (audit M6): activating/deactivating and upgrading a plugin run install and
|
|
132
|
+
# upgrade hooks -- state changes, not reads.
|
|
133
|
+
patch 'toggle', on: :collection
|
|
134
|
+
post 'upgrade'
|
|
119
135
|
end
|
|
120
136
|
|
|
121
137
|
# installer
|
|
@@ -125,7 +141,9 @@ Rails.application.routes.draw do
|
|
|
125
141
|
end
|
|
126
142
|
|
|
127
143
|
resources :media, only: [:index] do
|
|
128
|
-
|
|
144
|
+
# Security (audit M6): crop writes a cropped upload and can rewrite a user avatar
|
|
145
|
+
# (saved_avatar); via: :all admitted every verb, the CSRF-exempt GET/HEAD included.
|
|
146
|
+
post 'crop', on: :collection
|
|
129
147
|
get 'ajax', on: :collection
|
|
130
148
|
get 'download_private_file', on: :collection
|
|
131
149
|
post 'upload', on: :collection
|
data/config/routes/frontend.rb
CHANGED
|
@@ -29,11 +29,12 @@ Rails.application.routes.draw do
|
|
|
29
29
|
multilingual_segment = PluginRoutes.all_translations('routes.category', default: 'category')
|
|
30
30
|
request.params[:category_id].match(/[0-9]+/) && request.params[:label_cat].in?(multilingual_segment)
|
|
31
31
|
}
|
|
32
|
-
get ':post_type_title/:label_cat/:category_id-:title/:slug' => :post, as: 'post_of_category_post_type',
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
get ':post_type_title/:label_cat/:category_id-:title/:slug' => :post, as: 'post_of_category_post_type',
|
|
33
|
+
constraints: lambda { |request|
|
|
34
|
+
multilingual_segment = PluginRoutes.all_translations('routes.category', default: 'category')
|
|
35
|
+
request.params[:post_type_title].match(/^(?!(#{PluginRoutes.all_locales})$)[\w.-]+$/) &&
|
|
36
|
+
request.params[:category_id].match(/[0-9]+/) && request.params[:label_cat].in?(multilingual_segment)
|
|
37
|
+
}
|
|
37
38
|
get ':label/:post_tag_id-:title' => :post_tag, as: 'post_tag', constraints: lambda { |request|
|
|
38
39
|
multilingual_segment = PluginRoutes.all_translations('routes.tag', default: 'tag')
|
|
39
40
|
request.params[:post_tag_id].match(/[0-9]+/) && request.params[:label].in?(multilingual_segment)
|
|
@@ -44,12 +45,14 @@ Rails.application.routes.draw do
|
|
|
44
45
|
}
|
|
45
46
|
get ':label/:post_tag_slug' => :post_tag, as: 'post_tag_simple', constraints: lambda { |request|
|
|
46
47
|
multilingual_segment = PluginRoutes.all_translations('routes.tag', default: 'tag')
|
|
47
|
-
request.params[:post_tag_slug].match(%r{[a-zA-Z0-9_=\s\-/]+}) &&
|
|
48
|
-
|
|
49
|
-
get ':label/:user_id-:user_name' => :profile, as: :profile, defaults: { label: 'profile' }, constraints: lambda { |request|
|
|
50
|
-
multilingual_segment = PluginRoutes.all_translations('routes.profile', default: 'profile') | %w[profile]
|
|
51
|
-
request.params[:user_id].match(/[0-9]+/) && request.params[:label].in?(multilingual_segment)
|
|
48
|
+
request.params[:post_tag_slug].match(%r{[a-zA-Z0-9_=\s\-/]+}) &&
|
|
49
|
+
request.params[:label].in?(multilingual_segment)
|
|
52
50
|
}
|
|
51
|
+
get ':label/:user_id-:user_name' => :profile, as: :profile, defaults: { label: 'profile' },
|
|
52
|
+
constraints: lambda { |request|
|
|
53
|
+
multilingual_segment = PluginRoutes.all_translations('routes.profile', default: 'profile') | %w[profile]
|
|
54
|
+
request.params[:user_id].match(/[0-9]+/) && request.params[:label].in?(multilingual_segment)
|
|
55
|
+
}
|
|
53
56
|
get ':label' => :search, as: :search, defaults: { label: 'search' }, constraints: lambda { |request|
|
|
54
57
|
multilingual_segment = PluginRoutes.all_translations('routes.search', default: 'search') | %w[search]
|
|
55
58
|
request.params[:label].in?(multilingual_segment)
|
|
@@ -71,11 +74,14 @@ Rails.application.routes.draw do
|
|
|
71
74
|
# post types
|
|
72
75
|
controller 'camaleon_cms/frontend' do
|
|
73
76
|
PluginRoutes.get_sites.each do |s|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
# get_sites eager-loads :post_types, so map in memory instead of a per-site pluck query.
|
|
78
|
+
s.post_types.map { |pt| [pt.slug, pt.id] }.each do |pt_slug, pt_id|
|
|
79
|
+
get ':post_type_slug' => :post_type, as: "post_type_#{pt_id}", post_type_id: pt_id,
|
|
80
|
+
constraints: lambda { |request|
|
|
81
|
+
multilingual_segment =
|
|
82
|
+
PluginRoutes.all_translations("routes.post_types.#{pt_slug}", default: pt_slug)
|
|
83
|
+
request.params[:post_type_slug].in?(multilingual_segment)
|
|
84
|
+
}
|
|
79
85
|
end
|
|
80
86
|
end
|
|
81
87
|
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
class PostTableIntoUtf8 < CamaManager.migration_class
|
|
2
2
|
def change
|
|
3
3
|
if table_exists? CamaleonCms::User.table_name
|
|
4
|
-
add_column(CamaleonCms::User.table_name, :email, :string
|
|
5
|
-
add_column(CamaleonCms::User.table_name, :username, :string
|
|
6
|
-
add_column(CamaleonCms::User.table_name, :role, :string, default: 'client', index: true
|
|
7
|
-
add_column(CamaleonCms::User.table_name, :parent_id, :integer
|
|
8
|
-
add_column(CamaleonCms::User.table_name, :site_id, :integer, index: true, default: -1
|
|
9
|
-
add_column(CamaleonCms::User.table_name, :auth_token, :string
|
|
4
|
+
add_column(CamaleonCms::User.table_name, :email, :string, if_not_exists: true)
|
|
5
|
+
add_column(CamaleonCms::User.table_name, :username, :string, if_not_exists: true)
|
|
6
|
+
add_column(CamaleonCms::User.table_name, :role, :string, default: 'client', index: true, if_not_exists: true)
|
|
7
|
+
add_column(CamaleonCms::User.table_name, :parent_id, :integer, if_not_exists: true)
|
|
8
|
+
add_column(CamaleonCms::User.table_name, :site_id, :integer, index: true, default: -1, if_not_exists: true)
|
|
9
|
+
add_column(CamaleonCms::User.table_name, :auth_token, :string, if_not_exists: true)
|
|
10
10
|
else
|
|
11
11
|
create_table CamaleonCms::User.table_name do |t|
|
|
12
12
|
t.string "username", index: true
|
|
@@ -26,7 +26,7 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}term_taxonomy" do |t|
|
|
29
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}term_taxonomy", if_not_exists: true do |t|
|
|
30
30
|
t.string "taxonomy", index: true
|
|
31
31
|
t.text "description", limit: 1073741823
|
|
32
32
|
t.integer "parent_id", index: true
|
|
@@ -41,7 +41,7 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
41
41
|
t.belongs_to :user, index: true#, foreign_key: true
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}posts" do |t|
|
|
44
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}posts", if_not_exists: true do |t|
|
|
45
45
|
t.string "title"
|
|
46
46
|
t.string "slug", index: true
|
|
47
47
|
t.text "content", limit: 1073741823
|
|
@@ -58,13 +58,13 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
58
58
|
t.belongs_to :user, index: true#, foreign_key: true
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}term_relationships" do |t|
|
|
61
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}term_relationships", if_not_exists: true do |t|
|
|
62
62
|
t.integer "objectid", index: true
|
|
63
63
|
t.integer "term_order", index: true
|
|
64
64
|
t.belongs_to :term_taxonomy, index: true
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}user_relationships" do |t|
|
|
67
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}user_relationships", if_not_exists: true do |t|
|
|
68
68
|
t.integer "term_order"
|
|
69
69
|
t.integer "active", default: 1
|
|
70
70
|
|
|
@@ -72,7 +72,7 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
72
72
|
t.belongs_to :user, index: true
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}comments" do |t|
|
|
75
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}comments", if_not_exists: true do |t|
|
|
76
76
|
t.string "author"
|
|
77
77
|
t.string "author_email"
|
|
78
78
|
t.string "author_url"
|
|
@@ -87,7 +87,7 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
87
87
|
t.timestamps null: false
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields" do |t|
|
|
90
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields", if_not_exists: true do |t|
|
|
91
91
|
t.string "object_class", index: true
|
|
92
92
|
t.string "name"
|
|
93
93
|
t.string "slug", index: true
|
|
@@ -100,7 +100,7 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
100
100
|
t.string "status"
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields_relationships" do |t|
|
|
103
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields_relationships", if_not_exists: true do |t|
|
|
104
104
|
t.integer "objectid", index: true
|
|
105
105
|
t.integer "custom_field_id", index: true
|
|
106
106
|
t.integer "term_order"
|
|
@@ -109,7 +109,7 @@ class PostTableIntoUtf8 < CamaManager.migration_class
|
|
|
109
109
|
t.string "custom_field_slug", index: true
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}metas" do |t|
|
|
112
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}metas", if_not_exists: true do |t|
|
|
113
113
|
t.string "key", index: true
|
|
114
114
|
t.text "value", limit: 1073741823
|
|
115
115
|
t.integer "objectid", index: true
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# change post structure to optimize query speed
|
|
2
2
|
class RenameColumnPosts < CamaManager.migration_class
|
|
3
3
|
def change
|
|
4
|
-
remove_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :comment_count
|
|
5
|
-
add_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :post_order, :integer, default: 0
|
|
6
|
-
add_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :taxonomy_id, :integer, default: nil, index: true
|
|
4
|
+
remove_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :comment_count, if_exists: true
|
|
5
|
+
add_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :post_order, :integer, default: 0, if_not_exists: true
|
|
6
|
+
add_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :taxonomy_id, :integer, default: nil, index: true, if_not_exists: true
|
|
7
7
|
CamaleonCms::Post.all.each do |post|
|
|
8
8
|
begin
|
|
9
9
|
post_id = post.get_post_type_depre.id
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class AddConfirmTokenToUsers < CamaManager.migration_class
|
|
2
2
|
def change
|
|
3
|
-
add_column CamaleonCms::User.table_name, :confirm_email_token, :string, default: nil
|
|
4
|
-
add_column CamaleonCms::User.table_name, :confirm_email_sent_at, :datetime, default: nil
|
|
5
|
-
add_column CamaleonCms::User.table_name, :is_valid_email, :boolean, default: true
|
|
3
|
+
add_column CamaleonCms::User.table_name, :confirm_email_token, :string, default: nil, if_not_exists: true
|
|
4
|
+
add_column CamaleonCms::User.table_name, :confirm_email_sent_at, :datetime, default: nil, if_not_exists: true
|
|
5
|
+
add_column CamaleonCms::User.table_name, :is_valid_email, :boolean, default: true, if_not_exists: true
|
|
6
6
|
end
|
|
7
7
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
class AddFeatureToPosts < CamaManager.migration_class
|
|
2
2
|
def change
|
|
3
|
-
add_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :is_feature, :boolean, default: false
|
|
3
|
+
add_column "#{PluginRoutes.static_system_info["db_prefix"]}posts", :is_feature, :boolean, default: false, if_not_exists: true
|
|
4
4
|
end
|
|
5
5
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class MoveFirstNameOfUsers < CamaManager.migration_class
|
|
2
2
|
def change
|
|
3
|
-
add_column CamaleonCms::User.table_name, :first_name, :string
|
|
4
|
-
add_column CamaleonCms::User.table_name, :last_name, :string
|
|
3
|
+
add_column CamaleonCms::User.table_name, :first_name, :string, if_not_exists: true
|
|
4
|
+
add_column CamaleonCms::User.table_name, :last_name, :string, if_not_exists: true
|
|
5
5
|
CamaleonCms::User.all.each do |u|
|
|
6
6
|
u.update_columns(first_name: u.get_meta('first_name'), last_name: u.get_meta('last_name')) if u.get_meta('first_name').present?
|
|
7
7
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
class AddGroupToCustomFieldValues < CamaManager.migration_class
|
|
2
2
|
def change
|
|
3
|
-
add_column "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields_relationships", :group_number, :integer, default: 0
|
|
3
|
+
add_column "#{PluginRoutes.static_system_info["db_prefix"]}custom_fields_relationships", :group_number, :integer, default: 0, if_not_exists: true
|
|
4
4
|
end
|
|
5
5
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class CreateMedia < CamaManager.migration_class
|
|
2
2
|
def change
|
|
3
|
-
create_table "#{PluginRoutes.static_system_info["db_prefix"]}media" do |t|
|
|
3
|
+
create_table "#{PluginRoutes.static_system_info["db_prefix"]}media", if_not_exists: true do |t|
|
|
4
4
|
t.references :site, index: true
|
|
5
5
|
t.string :name, index: true
|
|
6
6
|
t.boolean :is_folder, index: true, default: false
|
|
@@ -2,7 +2,7 @@ class AdjustFieldLength < CamaManager.migration_class
|
|
|
2
2
|
def change
|
|
3
3
|
post_table = CamaleonCms::Post.table_name
|
|
4
4
|
change_column post_table, :title, :text
|
|
5
|
-
remove_index(post_table, :slug
|
|
5
|
+
remove_index(post_table, :slug, if_exists: true)
|
|
6
6
|
change_column post_table, :slug, :text
|
|
7
7
|
add_index post_table, :slug, length: 255
|
|
8
8
|
change_column "#{PluginRoutes.static_system_info["db_prefix"]}term_taxonomy", :name, :text
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module CamaleonCms
|
|
2
|
+
# Helper used by config/initializers/assets.rb to declare plugin/theme assets as
|
|
3
|
+
# precompiled.
|
|
4
|
+
#
|
|
5
|
+
# Plugin and theme assets can live in three different layouts:
|
|
6
|
+
# * host app: <app>/app/apps/{plugins,themes}/<key>/assets/...
|
|
7
|
+
# * the camaleon_cms gem: <gem>/app/apps/{plugins,themes}/<key>/assets/...
|
|
8
|
+
# * separate "gem_mode" gems: <gem>/app/assets/<type>/{plugins,themes}/<key>/...
|
|
9
|
+
# (e.g. cama_contact_form ships app/assets/javascripts/plugins/cama_contact_form/...)
|
|
10
|
+
#
|
|
11
|
+
# Rails' default Sprockets precompile rules only cover the app/assets top level, so none
|
|
12
|
+
# of these are declared as precompiled. On modern Sprockets (>= 4) with
|
|
13
|
+
# `config.assets.unknown_asset_fallback = false`, requesting such an asset (e.g. via
|
|
14
|
+
# `javascript_include_tag "plugins/visibility_post/assets/js/form.js"`) raises
|
|
15
|
+
# `Sprockets::Rails::Helper::AssetNotPrecompiledError` unless it is declared.
|
|
16
|
+
#
|
|
17
|
+
# We enumerate the concrete asset files from the *real* Sprockets load paths and declare
|
|
18
|
+
# their exact logical paths as strings. Strings are the canonical, Sprockets-version
|
|
19
|
+
# agnostic form (work on both 3.x and 4.x). Scanning `config.assets.paths` (instead of a
|
|
20
|
+
# couple of hardcoded directories) ensures host, gem-bundled and separately gem-packaged
|
|
21
|
+
# (gem_mode) plugins/themes are all covered, matching the reach of the old precompile
|
|
22
|
+
# `proc` this replaced. Because the declaration is computed from the on-disk files, every
|
|
23
|
+
# installed plugin/theme is declared regardless of whether it is currently active, so
|
|
24
|
+
# switching themes / enabling-disabling plugins (DB-only operations) never requires a
|
|
25
|
+
# recompile.
|
|
26
|
+
module AssetsPrecompile
|
|
27
|
+
PRECOMPILE_EXTENSIONS = /\.(css|js|svg|ttf|woff|woff2|eot|otf|swf|pdf|png|jpe?g|gif|ico|mp3|mp4|webm|ogg|webp)\z/i
|
|
28
|
+
PRECOMPILE_CONTENT_TYPES = %r{(javascript|image/|audio|video|font)}
|
|
29
|
+
|
|
30
|
+
module_function
|
|
31
|
+
|
|
32
|
+
# path: logical asset path relative to an asset load path, e.g.
|
|
33
|
+
# "plugins/visibility_post/assets/js/form.js", "themes/my_theme/assets/css/app.css"
|
|
34
|
+
# or "plugins/cama_contact_form/admin_editor.js" (gem_mode layout).
|
|
35
|
+
# Returns true when the asset must be precompiled.
|
|
36
|
+
def match?(path)
|
|
37
|
+
dirname = File.dirname(path)
|
|
38
|
+
return false unless dirname.start_with?('plugins/', 'themes/')
|
|
39
|
+
|
|
40
|
+
name = File.basename(path)
|
|
41
|
+
return false if name.start_with?('_') || path.include?('/views/')
|
|
42
|
+
|
|
43
|
+
PRECOMPILE_EXTENSIONS.match?(path) || content_type_for(name).scan(PRECOMPILE_CONTENT_TYPES).any?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def content_type_for(name)
|
|
47
|
+
MIME::Types.type_for(name).first.content_type
|
|
48
|
+
rescue StandardError
|
|
49
|
+
''
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Enumerate the logical paths of every plugin/theme asset found under the given asset
|
|
53
|
+
# roots. For each root, only the `plugins/` and `themes/` subtrees are scanned, and each
|
|
54
|
+
# file is converted to its logical path (relative to the root) and filtered by `match?`.
|
|
55
|
+
def logical_paths(asset_roots = default_asset_roots)
|
|
56
|
+
asset_roots.flat_map do |root|
|
|
57
|
+
root = root.to_s
|
|
58
|
+
next [] if root.empty? || !Dir.exist?(root)
|
|
59
|
+
|
|
60
|
+
prefix = "#{root.chomp('/')}/"
|
|
61
|
+
Dir.glob(File.join(root, '{plugins,themes}', '**', '*')).filter_map do |file|
|
|
62
|
+
next unless File.file?(file)
|
|
63
|
+
|
|
64
|
+
logical = file.delete_prefix(prefix)
|
|
65
|
+
logical if match?(logical)
|
|
66
|
+
end
|
|
67
|
+
end.uniq
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Asset roots to scan: the configured Sprockets load paths (which cover host,
|
|
71
|
+
# gem-bundled and gem_mode plugin/theme assets), plus the host and camaleon_cms gem
|
|
72
|
+
# `app/apps` folders as a fallback in case the asset paths are not yet populated when
|
|
73
|
+
# this is called during initialization.
|
|
74
|
+
def default_asset_roots
|
|
75
|
+
roots = []
|
|
76
|
+
if defined?(Rails) && Rails.respond_to?(:application) && Rails.application
|
|
77
|
+
roots.concat(Array(Rails.application.config.assets.paths).map(&:to_s))
|
|
78
|
+
end
|
|
79
|
+
roots << Rails.root.join('app/apps').to_s if defined?(Rails) && Rails.respond_to?(:root) && Rails.root
|
|
80
|
+
# rubocop:disable Style/GlobalVars
|
|
81
|
+
roots << File.join($camaleon_engine_dir, 'app', 'apps') if defined?($camaleon_engine_dir) && $camaleon_engine_dir
|
|
82
|
+
# rubocop:enable Style/GlobalVars
|
|
83
|
+
roots.uniq
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|