diff --git a/Gemfile b/Gemfile index 765a1118..47504f8f 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,7 @@ gem 'webpacker' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' gem 'device_detector' +gem 'htmlbeautifier' gem 'rubanok' gem 'after_commit_everywhere', '~> 1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 1b176336..e20d74be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -270,6 +270,7 @@ GEM hiredis (0.6.3-x86_64-linux-musl) hiredis-client (0.14.1-x86_64-linux-musl) redis-client (= 0.14.1) + htmlbeautifier (1.4.2) http_parser.rb (0.8.0-x86_64-linux-musl) httparty (0.21.0) mini_mime (>= 1.0.0) @@ -659,6 +660,7 @@ DEPENDENCIES hamlit-rails hiredis hiredis-client + htmlbeautifier httparty icalendar image_processing diff --git a/app/javascript/controllers/file_preview_controller.js b/app/javascript/controllers/file_preview_controller.js new file mode 100644 index 00000000..9eaaab2d --- /dev/null +++ b/app/javascript/controllers/file_preview_controller.js @@ -0,0 +1,19 @@ +import { Controller } from 'stimulus' +import bsCustomFileInput from "bs-custom-file-input"; + +document.addEventListener("turbolinks:load", () => { + bsCustomFileInput.init(); +}); + +export default class extends Controller { + static targets = ["preview", "input"]; + + connect() { + } + + update(event = undefined) { + if (!this.hasPreviewTarget) return; + + this.previewTarget.src = window.URL.createObjectURL(this.inputTarget.files[0]) + } +} diff --git a/app/javascript/etc/image_preview.js b/app/javascript/etc/image_preview.js deleted file mode 100644 index fcdeec85..00000000 --- a/app/javascript/etc/image_preview.js +++ /dev/null @@ -1,11 +0,0 @@ -document.addEventListener('turbolinks:load', () => { - document.querySelectorAll('input[type=file]').forEach(file => { - if (!file.dataset.preview) return - - file.addEventListener('change', event => { - if (file.files.length === 0) return - - document.querySelector('#' + file.dataset.preview).src = window.URL.createObjectURL(file.files[0]) - }) - }) -}) diff --git a/app/javascript/etc/index.js b/app/javascript/etc/index.js index d4b9f7a3..e19246af 100644 --- a/app/javascript/etc/index.js +++ b/app/javascript/etc/index.js @@ -1,5 +1,4 @@ import './external_links' -import './image_preview' import './input-date' import './input-tag' import './prosemirror' diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 30b0bb82..0fc32221 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'htmlbeautifier' + # Se encarga del contenido del artículo y quizás otros campos que # requieran texto largo. class MetadataContent < MetadataTemplate @@ -91,7 +93,7 @@ class MetadataContent < MetadataTemplate end end - html.to_s.html_safe + HtmlBeautifier.beautify(html.to_s).html_safe end # Limpia estilos en base a una lista de permitidos diff --git a/app/policies/site_usuarie_policy.rb b/app/policies/site_usuarie_policy.rb index f07dc1c9..31e98cfe 100644 --- a/app/policies/site_usuarie_policy.rb +++ b/app/policies/site_usuarie_policy.rb @@ -36,8 +36,7 @@ class SiteUsuariePolicy end def accept_invitation? - su = site_usuarie - (usuarie? || invitade?) && su.usuarie.rol_for_site(su.site).temporal + !!site_usuarie.usuarie.rol_for_site(site_usuarie.site)&.temporal end def reject_invitation? diff --git a/app/views/posts/attributes/_file.haml b/app/views/posts/attributes/_file.haml index 54f9f81a..20c27399 100644 --- a/app/views/posts/attributes/_file.haml +++ b/app/views/posts/attributes/_file.haml @@ -1,12 +1,14 @@ -.form-group +.form-group{ data: { controller: 'file-preview' } } - if metadata.static_file - case metadata.static_file.blob.content_type - when %r{\Avideo/} = video_tag url_for(metadata.static_file), - controls: true, class: 'img-fluid' + controls: true, class: 'img-fluid', + data: { target: 'file-preview.preview' } - when %r{\Aaudio/} = audio_tag url_for(metadata.static_file), - controls: true, class: 'img-fluid' + controls: true, class: 'img-fluid', + data: { target: 'file-preview.preview' } - when 'application/pdf' %iframe{ src: url_for(metadata.static_file) } - else @@ -24,7 +26,7 @@ = file_field(*field_name_for(base, attribute, :path), **field_options(attribute, metadata, required: (metadata.required && !metadata.path?)), class: "custom-file-input #{invalid(post, attribute)}", - data: { preview: "#{attribute}-preview" }) + data: { target: 'file-preview.input', action: 'file-preview#update' }) = label_tag "#{base}_#{attribute}_path", post_label_t(attribute, :path, post: post), class: 'custom-file-label' = render 'posts/attribute_feedback', diff --git a/app/views/posts/attributes/_image.haml b/app/views/posts/attributes/_image.haml index 84fe56fd..241a78e8 100644 --- a/app/views/posts/attributes/_image.haml +++ b/app/views/posts/attributes/_image.haml @@ -1,9 +1,9 @@ -.form-group +.form-group{ data: { controller: 'file-preview' } } - if metadata.static_file = image_tag url_for(metadata.static_file), alt: metadata.value['description'], class: 'img-fluid', - id: "#{attribute}-preview" + data: { target: 'file-preview.preview' } -# Mantener el valor si no enviamos ninguna imagen = hidden_field_tag "#{base}[#{attribute}][path]", metadata.value['path'] @@ -16,13 +16,14 @@ = image_tag '', alt: metadata.value['description'], class: 'img-fluid', - id: "#{attribute}-preview" + data: { target: 'file-preview.preview' } .custom-file = file_field(*field_name_for(base, attribute, :path), **field_options(attribute, metadata, required: (metadata.required && !metadata.path?)), class: "custom-file-input #{invalid(post, attribute)}", - accept: ActiveStorage.web_image_content_types.join(','), data: { preview: "#{attribute}-preview" }) + accept: ActiveStorage.web_image_content_types.join(','), + data: { target: 'file-preview.input', action: 'file-preview#update' }) = label_tag "#{base}_#{attribute}_path", post_label_t(attribute, :path, post: post), class: 'custom-file-label' = render 'posts/attribute_feedback', diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index 89d01a24..6419a138 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -24,30 +24,31 @@ = site.title %p.lead= site.description %br - = link_to t('.visit'), site.url, class: 'btn btn-secondary' - - if current_usuarie.rol_for_site(site).temporal? - = render 'components/btn_base', - text: t('sites.invitations.accept'), - path: site_usuaries_accept_invitation_path(site), - title: t('help.sites.invitations.accept'), - class: 'btn-secondary' - = render 'components/btn_base', - text: t('sites.invitations.reject'), - path: site_usuaries_reject_invitation_path(site), - title: t('help.sites.invitations.reject'), - class: 'btn-secondary' - - else - - if policy(site).show? - = render 'layouts/btn_with_tooltip', - tooltip: t('help.sites.edit_posts'), - type: 'success', - link: site_path(site), - text: t('sites.posts') - = render 'sites/build', site: site - = render 'sites/moderation_queue', site: site - - if policy(SiteUsuarie.new(site, current_usuarie)).index? - = render 'layouts/btn_with_tooltip', - tooltip: t('usuaries.index.help.self'), - text: t('usuaries.index.title'), - type: 'info', - link: site_usuaries_path(site) + .d-flex.flex-row + = link_to t('.visit'), site.url, class: 'btn btn-secondary' + - if current_usuarie.rol_for_site(site).temporal? + = render 'components/btn_base', + text: t('sites.invitations.accept'), + path: site_usuaries_accept_invitation_path(site), + title: t('help.sites.invitations.accept'), + class: 'btn-secondary' + = render 'components/btn_base', + text: t('sites.invitations.reject'), + path: site_usuaries_reject_invitation_path(site), + title: t('help.sites.invitations.reject'), + class: 'btn-secondary' + - else + - if policy(site).show? + = render 'layouts/btn_with_tooltip', + tooltip: t('help.sites.edit_posts'), + type: 'success', + link: site_path(site), + text: t('sites.posts') + = render 'sites/build', site: site + = render 'sites/moderation_queue', site: site + - if policy(SiteUsuarie.new(site, current_usuarie)).index? + = render 'layouts/btn_with_tooltip', + tooltip: t('usuaries.index.help.self'), + text: t('usuaries.index.title'), + type: 'info', + link: site_usuaries_path(site) diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 91d287e0..c07c7751 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -7,7 +7,7 @@ # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy Rails.application.config.content_security_policy do |policy| - policy.default_src :self + policy.default_src :self, :blob # XXX: Varios scripts generan estilos en línea policy.style_src :self, :unsafe_inline, :https # Repetimos la default para poder saber cuál es la política en falta diff --git a/package.json b/package.json index 870b8e9b..df76a58a 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@rails/webpacker": "5.4.4", "@suttyweb/editor": "^0.1.25", "babel-loader": "^8.2.2", + "bs-custom-file-input": "^1.3.4", "chart.js": "^3.5.1", "chartkick": "^4.0.5", "circular-dependency-plugin": "^5.2.2", diff --git a/public/assets/.sprockets-manifest-a1cbb907961024fc033716a7d30668dd.json b/public/assets/.sprockets-manifest-a1cbb907961024fc033716a7d30668dd.json index 6b2049d2..01faf5f2 100644 --- a/public/assets/.sprockets-manifest-a1cbb907961024fc033716a7d30668dd.json +++ b/public/assets/.sprockets-manifest-a1cbb907961024fc033716a7d30668dd.json @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19bfc9f10c16099768877ce142b05e8971d1a802ee9b0507617d44011ed8d755 +oid sha256:9f830e40700ddb47b0043c2c581794208fea4c9dc11727d541670debcfd7c2c9 size 10243 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js b/public/packs/js/application-59000072ac88ea7cfdf0.js new file mode 100644 index 00000000..85e8bc48 --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e3c7df40169eed5d4f2c2adffb8ebba8e727ee8703592deb60022c6df0fd441 +size 1585043 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js.LICENSE.txt b/public/packs/js/application-59000072ac88ea7cfdf0.js.LICENSE.txt new file mode 100644 index 00000000..dfe27ce7 --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js.LICENSE.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7073b760337ff91f74933ece915ce12f8653f990f607a0925cc002dd610fa0f9 +size 1097 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js.br b/public/packs/js/application-59000072ac88ea7cfdf0.js.br new file mode 100644 index 00000000..976f61bb --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1c767c98f29763e57d44dead8ab2e447791805755e28a1f494a2c27058a67a6 +size 348307 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js.gz b/public/packs/js/application-59000072ac88ea7cfdf0.js.gz new file mode 100644 index 00000000..4cda8f05 --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bd21d85066920bc13ff25dd26d3a72cedbb7b70427597cdddcc0f993a8382a3 +size 459013 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js.map b/public/packs/js/application-59000072ac88ea7cfdf0.js.map new file mode 100644 index 00000000..677b00fd --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js.map @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dba672cc8f6249baae8699f7e86d20bfb7debf94a23603c7cddd5fce828f1240 +size 6214044 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js.map.br b/public/packs/js/application-59000072ac88ea7cfdf0.js.map.br new file mode 100644 index 00000000..f9d1486b --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js.map.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fab14fd46a3cf22aad2c5e357018077b0b74edd3a413a7623452d3fc72bdb6b +size 1330633 diff --git a/public/packs/js/application-59000072ac88ea7cfdf0.js.map.gz b/public/packs/js/application-59000072ac88ea7cfdf0.js.map.gz new file mode 100644 index 00000000..7e37de87 --- /dev/null +++ b/public/packs/js/application-59000072ac88ea7cfdf0.js.map.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea0ff80c7f27a28e2dacd239f5f93d6c79b5b3a4096105fbc8822db245ced82e +size 1643234 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js b/public/packs/js/application-8ce9779d857bfff53532.js deleted file mode 100644 index 134f014c..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:632234e427da97d723efe4061b3f432aade159b51949167abeca34826bcff5ea -size 1581325 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js.LICENSE.txt b/public/packs/js/application-8ce9779d857bfff53532.js.LICENSE.txt deleted file mode 100644 index 979d1ab9..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js.LICENSE.txt +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3b9ae1697c4b8a404afe77afe035de28b7f4880e9f52caac82620bb8d8ed495 -size 854 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js.br b/public/packs/js/application-8ce9779d857bfff53532.js.br deleted file mode 100644 index 610a9646..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ac34b76ab95f467a2ffb3c8689266f7706ca00172d130302386ee08b22dede2 -size 347614 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js.gz b/public/packs/js/application-8ce9779d857bfff53532.js.gz deleted file mode 100644 index 5886b434..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:73c9f3bd667a29d7026309e5d31ab91e45b9e10e186d9b8abfa3e3a12ff3bf0c -size 458426 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js.map b/public/packs/js/application-8ce9779d857bfff53532.js.map deleted file mode 100644 index e6c66405..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js.map +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2bb17fb9d66535cf55c84efb3c56242050c1e7bc168f44b3ff496df9fe0beb67 -size 6205529 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js.map.br b/public/packs/js/application-8ce9779d857bfff53532.js.map.br deleted file mode 100644 index 5eeaead6..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js.map.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0598c9fd4ddf8878e5ed6ee980ac35586b305eb9b359605d713283bfbeb19b68 -size 1328792 diff --git a/public/packs/js/application-8ce9779d857bfff53532.js.map.gz b/public/packs/js/application-8ce9779d857bfff53532.js.map.gz deleted file mode 100644 index 48ae8089..00000000 --- a/public/packs/js/application-8ce9779d857bfff53532.js.map.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b9a2ba478f9e5abf2712b9b68a9994f668acb52006aac34189a813b67f4be657 -size 1640525 diff --git a/public/packs/manifest.json b/public/packs/manifest.json index 189f4782..a4f31bf2 100644 --- a/public/packs/manifest.json +++ b/public/packs/manifest.json @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a206bab3fa22fb96428b3c46685fa61a059f9db62e3df47037537cd68782c1f +oid sha256:1539afb4cbd30b30ae94a220fd843b2d9cbdbc16acaaaa37728a65393179c3ca size 1426 diff --git a/public/packs/manifest.json.br b/public/packs/manifest.json.br index 7222d4cd..82a0f36c 100644 --- a/public/packs/manifest.json.br +++ b/public/packs/manifest.json.br @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:923d3edcf9cd76e822ca27c1eafcbdaa8b3f1ed47d25ace25e19b6c416d958f5 +oid sha256:81c0efe3055c75fe72e669f1adbacae976854a45ad775a95bb29b3bb6b1c91bf size 320 diff --git a/public/packs/manifest.json.gz b/public/packs/manifest.json.gz index bc4ea39d..e64e01ac 100644 --- a/public/packs/manifest.json.gz +++ b/public/packs/manifest.json.gz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a73c5c3f9d5bbecd9a63d4088c029ea835becbd0a6496b7a6f6ca6505d2095c5 +oid sha256:4c2b4208ae455ce6efe90a63864e2d3e62bbae515dd4b0073c10c97ca23a4bcf size 365 diff --git a/yarn.lock b/yarn.lock index 4619169e..73f34fce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2677,6 +2677,11 @@ browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" +bs-custom-file-input@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs-custom-file-input/-/bs-custom-file-input-1.3.4.tgz#c275cb8d4f1c02ba026324292509fa9a747dbda8" + integrity sha512-NBsQzTnef3OW1MvdKBbMHAYHssCd613MSeJV7z2McXznWtVMnJCy7Ckyc+PwxV6Pk16cu6YBcYWh/ZE0XWNKCA== + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"