From 7e0600779ed259f2bedc3603d5205d18bc21316b Mon Sep 17 00:00:00 2001 From: void Date: Sat, 22 May 2021 21:17:00 +0000 Subject: [PATCH 001/814] usar @suttyweb/editor --- app/javascript/editor/editor.ts | 15 ++- app/views/posts/attributes/_content.haml | 117 +---------------------- package.json | 1 + yarn.lock | 5 + 4 files changed, 20 insertions(+), 118 deletions(-) diff --git a/app/javascript/editor/editor.ts b/app/javascript/editor/editor.ts index 880547de..233cc3c0 100644 --- a/app/javascript/editor/editor.ts +++ b/app/javascript/editor/editor.ts @@ -19,6 +19,10 @@ import { } from "editor/types/multimedia"; import { setupAuxiliaryToolbar as setupMarkAuxiliaryToolbar } from "editor/types/mark"; +/// @ts-ignore +import SuttyEditor from "@suttyweb/editor"; +import "@suttyweb/editor/dist/style.css"; + // Esta funcion corrije errores que pueden haber como: // * que un nodo que no tiene 'text' permitido no tenga children (se les // inserta un allowedChildren[0]) @@ -330,10 +334,15 @@ document.addEventListener("turbolinks:load", () => { ".editor[data-editor]" )) { try { - setupEditor(editorEl); + new SuttyEditor({ + target: editorEl, + props: { + textareaEl: editorEl.parentElement!.querySelector("textarea"), + }, + }); } catch (error) { - // TODO: mostrar error - console.error("no se pudo iniciar el editor, error completo", error); + console.error(error); + alert(error); } } }); diff --git a/app/views/posts/attributes/_content.haml b/app/views/posts/attributes/_content.haml index 4ae70ba0..65462397 100644 --- a/app/views/posts/attributes/_content.haml +++ b/app/views/posts/attributes/_content.haml @@ -9,119 +9,6 @@ .alert.alert-info :markdown #{t('editor.alert')} - = text_area_tag "#{base}[#{attribute}]", '', + = text_area_tag "#{base}[#{attribute}]", metadata.value.html_safe, dir: dir, lang: locale, - **field_options(attribute, metadata), class: 'd-none' - - -# - el > se come el salto de línea y hace que los botones no tengan - espacio adicional - - TODO: Eliminar todo el espacio en blanco para minificar HTML - .editor-toolbar{ style: 'z-index: 1' } - .editor-primary-toolbar.scrollbar-black - %button.btn{ type: 'button', title: t('editor.multimedia'), data: { editor_button: 'multimedia' } }> - %i.fa.fa-fw.fa-upload> - %span.sr-only>= t('editor.multimedia') - %button.btn{ type: 'button', title: t('editor.bold'), data: { editor_button: 'mark-bold' } }> - %i.fa.fa-fw.fa-bold> - %span.sr-only>= t('editor.bold') - %button.btn{ type: 'button', title: t('editor.italic'), data: { editor_button: 'mark-italic' } }> - %i.fa.fa-fw.fa-italic> - %span.sr-only>= t('editor.italic') - %button.btn{ type: 'button', title: t('editor.mark'), data: { editor_button: 'mark-mark' } }> - %i.fa.fa-fw.fa-tint> - %span.sr-only>= t('editor.mark') - %button.btn{ type: 'button', title: t('editor.link'), data: { editor_button: 'mark-link' } }> - %i.fa.fa-fw.fa-link> - %span.sr-only>= t('editor.link') - %button.btn{ type: 'button', title: t('editor.deleted'), data: { editor_button: 'mark-deleted' } }> - %i.fa.fa-fw.fa-strikethrough> - %span.sr-only>= t('editor.deleted') - %button.btn{ type: 'button', title: t('editor.underline'), data: { editor_button: 'mark-underline' } }> - %i.fa.fa-fw.fa-underline> - %span.sr-only>= t('editor.underline') - %button.btn{ type: 'button', title: t('editor.super'), data: { editor_button: 'mark-super' } }> - %i.fa.fa-fw.fa-superscript> - %span.sr-only>= t('editor.super') - %button.btn{ type: 'button', title: t('editor.sub'), data: { editor_button: 'mark-sub' } }> - %i.fa.fa-fw.fa-subscript> - %span.sr-only>= t('editor.sub') - %button.btn{ type: 'button', title: t('editor.small'), data: { editor_button: 'mark-small' } }> - %i.fa.fa-fw.fa-subscript> - %span.sr-only>= t('editor.small') - %button.btn.mr-0{ type: 'button', title: t('editor.h1'), data: { editor_button: 'block-h1' } }> - %i.fa.fa-fw.fa-heading> - 1 - %span.sr-only>= t('editor.h1') - %details.d-inline> - %summary.d-inline> - %span.btn.ml-0{ role: 'button', title: t('editor.more') }> - %i.fa.fa-caret-right> - %span.sr-only= t('editor.more') - .d-inline> - %button.btn{ type: 'button', title: t('editor.h2'), data: { editor_button: 'block-h2' } }> - %i.fa.fa-fw.fa-heading> - 2 - %span.sr-only>= t('editor.h2') - %button.btn{ type: 'button', title: t('editor.h3'), data: { editor_button: 'block-h3' } }> - %i.fa.fa-fw.fa-heading> - 3 - %span.sr-only>= t('editor.h3') - %button.btn{ type: 'button', title: t('editor.h4'), data: { editor_button: 'block-h4' } }> - %i.fa.fa-fw.fa-heading> - 4 - %span.sr-only>= t('editor.h4') - %button.btn{ type: 'button', title: t('editor.h5'), data: { editor_button: 'block-h5' } }> - %i.fa.fa-fw.fa-heading> - 5 - %span.sr-only>= t('editor.h5') - %button.btn{ type: 'button', title: t('editor.h6'), data: { editor_button: 'block-h6' } }> - %i.fa.fa-fw.fa-heading> - 6 - %span.sr-only>= t('editor.h6') - %button.btn{ type: 'button', title: t('editor.ul'), data: { editor_button: 'block-unordered_list' } }> - %i.fa.fa-fw.fa-list-ul> - %span.sr-only>= t('editor.ul') - %button.btn{ type: 'button', title: t('editor.ol'), data: { editor_button: 'block-ordered_list' } }> - %i.fa.fa-fw.fa-list-ol> - %span.sr-only>= t('editor.ol') - %button.btn{ type: 'button', title: t('editor.left'), data: { editor_button: 'parentBlock-left' } }> - %i.fa.fa-fw.fa-align-left> - %span.sr-only>= t('editor.left') - %button.btn{ type: 'button', title: t('editor.center'), data: { editor_button: 'parentBlock-center' } }> - %i.fa.fa-fw.fa-align-center> - %span.sr-only>= t('editor.center') - %button.btn{ type: 'button', title: t('editor.right'), data: { editor_button: 'parentBlock-right' } }> - %i.fa.fa-fw.fa-align-right> - %span.sr-only>= t('editor.right') - - -# HAML cringe - .editor-auxiliary-toolbar.mt-1.scrollbar-black{ data: { editor_auxiliary_toolbar: '' } } - .form-group{ data: { editor_auxiliary: 'mark' } } - %label{ for: 'mark-color' }= t('editor.color') - %input.form-control{ type: 'color', name: 'mark-color' }/ - %label{ for: 'mark-text-color' }= t('editor.text-color') - %input.form-control{ type: 'color', name: 'mark-text-color' }/ - - %div{ data: { editor_auxiliary: 'multimedia' } } - .form-group - .custom-file - %input.custom-file-input{ type: 'file', id: 'multimedia-file', name: 'multimedia-file' }/ - %label.custom-file-label{ for: 'multimedia-file' }= t('editor.multimedia-select') - .form-group - %label{ for: 'multimedia-alt' }= t('editor.description') - %input.form-control{ type: 'text', id: 'multimedia-alt', name: 'multimedia-alt' }/ - .form-group - %button.btn{ type: 'button', id: 'multimedia-file-upload', name: 'multimedia-file-upload' }= t('editor.multimedia-upload') - %button.btn{ type: 'button', id: 'multimedia-remove', name: 'multimedia-remove' }= t('editor.multimedia-remove') - - .form-group{ data: { editor_auxiliary: 'link' } } - %label{ for: 'link-url' }= t('editor.url') - %input.form-control{ type: 'url', id: 'link-url', name: 'link-url' }/ - - .editor-aviso-word.alert.alert-info - %p= t('editor.word') - - .editor-content.form-control.h-auto.mt-1{ contenteditable: 'true' } - = metadata.value.html_safe + **field_options(attribute, metadata) diff --git a/package.json b/package.json index 0a2458a6..94fa93cc 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", + "@suttyweb/editor": "^0.0.3", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 11ff78cb..216c9342 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,6 +1171,11 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== +"@suttyweb/editor@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.3.tgz#6572b9d29fe1c3adf36c4cfc4ee152453ba15c0f" + integrity sha512-mFh3cWpA/9vNlqKHBLjPVjCOzDH8HaBL+CwAGtiQoFUhxx8gaUiAfBGZGOE/KK9IcD/xDVTkG6q6HYZ6iIQIFQ== + "@types/caseless@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" From a64f554f0e7b63ec36781096dc0e042c8f26d572 Mon Sep 17 00:00:00 2001 From: void Date: Sat, 22 May 2021 22:03:18 +0000 Subject: [PATCH 002/814] usar @suttyweb/editor@0.0.4 subida de archivos :) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 94fa93cc..773e9234 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.0.3", + "@suttyweb/editor": "^0.0.4", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 216c9342..342a616a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.3.tgz#6572b9d29fe1c3adf36c4cfc4ee152453ba15c0f" - integrity sha512-mFh3cWpA/9vNlqKHBLjPVjCOzDH8HaBL+CwAGtiQoFUhxx8gaUiAfBGZGOE/KK9IcD/xDVTkG6q6HYZ6iIQIFQ== +"@suttyweb/editor@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.4.tgz#5fc6a295ee44f25d4034137a777f8b9fdf721aaa" + integrity sha512-ZlFjV/I9q1lW1rgRWJHyisRQQodsZkcGiIAXFPPhRBJmvE92AhEpuzPDLTesyJ1WQ2EZojOxAeoGFczUnv3jCA== "@types/caseless@*": version "0.12.2" From 06a9b78eee53bba5a10fb0c1c74978bac9af39c8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Jun 2021 12:06:44 -0300 Subject: [PATCH 003/814] usar @suttyweb/editor@0.0.6 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 773e9234..b082128e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.0.4", + "@suttyweb/editor": "0.0.6", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 342a616a..e25e2357 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.0.4": - version "0.0.4" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.4.tgz#5fc6a295ee44f25d4034137a777f8b9fdf721aaa" - integrity sha512-ZlFjV/I9q1lW1rgRWJHyisRQQodsZkcGiIAXFPPhRBJmvE92AhEpuzPDLTesyJ1WQ2EZojOxAeoGFczUnv3jCA== +"@suttyweb/editor@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.6.tgz#5496762997c835262d0551a03eb919bdb9cc9dab" + integrity sha512-cLTM/xtEP2H4Vld2yF5Mnpqzke2pb43czVSDIAOnbDd9szG9o25ABAtQZVc7Iapf47mEen2rJpdoC0+Hfvruqw== "@types/caseless@*": version "0.12.2" From ffa2c80bf1dbab6b762c6961a9f576aadabd1054 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 28 Jun 2021 14:29:37 -0300 Subject: [PATCH 004/814] @suttyweb/editor@0.0.7 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b082128e..9560cdf3 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "0.0.6", + "@suttyweb/editor": "0.0.7", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index e25e2357..604ee871 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.6.tgz#5496762997c835262d0551a03eb919bdb9cc9dab" - integrity sha512-cLTM/xtEP2H4Vld2yF5Mnpqzke2pb43czVSDIAOnbDd9szG9o25ABAtQZVc7Iapf47mEen2rJpdoC0+Hfvruqw== +"@suttyweb/editor@0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.7.tgz#019c1ab2d43e6a6fb7d4ebf44c44f79ebd5a6896" + integrity sha512-fZepXH1pRTdDQWxKSF10lYVlYjoczkqGi00vTaSWDRTL/rnZrgOEakcdFyutcJzYnZWdWsWsF6AUidKvQvd1dw== "@types/caseless@*": version "0.12.2" From 6467a265d3fd2c1b77d576d2cd5412c6f189ac0d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 10 Aug 2021 18:36:55 -0300 Subject: [PATCH 005/814] Deprecar el editor --- app/javascript/editor/editor.ts | 313 -------------------------------- 1 file changed, 313 deletions(-) diff --git a/app/javascript/editor/editor.ts b/app/javascript/editor/editor.ts index 233cc3c0..c254a650 100644 --- a/app/javascript/editor/editor.ts +++ b/app/javascript/editor/editor.ts @@ -1,320 +1,7 @@ -import { storeContent, restoreContent, forgetContent } from "editor/storage"; -import { - isDirectChild, - moveChildren, - safeGetSelection, - safeGetRangeAt, - setAuxiliaryToolbar, - parentBlockNames, - clearSelected, -} from "editor/utils"; -import { types, getValidChildren, getType } from "editor/types"; -import { setupButtons as setupMarksButtons } from "editor/types/marks"; -import { setupButtons as setupBlocksButtons } from "editor/types/blocks"; -import { setupButtons as setupParentBlocksButtons } from "editor/types/parentBlocks"; -import { setupAuxiliaryToolbar as setupLinkAuxiliaryToolbar } from "editor/types/link"; -import { - setupAuxiliaryToolbar as setupMultimediaAuxiliaryToolbar, - setupButtons as setupMultimediaButtons, -} from "editor/types/multimedia"; -import { setupAuxiliaryToolbar as setupMarkAuxiliaryToolbar } from "editor/types/mark"; - /// @ts-ignore import SuttyEditor from "@suttyweb/editor"; import "@suttyweb/editor/dist/style.css"; -// Esta funcion corrije errores que pueden haber como: -// * que un nodo que no tiene 'text' permitido no tenga children (se les -// inserta un allowedChildren[0]) -// * TODO: que haya una imágen sin
o que no esté como bloque (se ponen -// después del bloque en el que están como bloque de por si) -// * convierte y en y -// Lo hace para que siga la estructura del documento y que no se borren por -// cleanContent luego. -function fixContent(editor: Editor, node: Element = editor.contentEl): void { - if (node.tagName === "SCRIPT" || node.tagName === "STYLE") { - node.parentElement?.removeChild(node); - return; - } - - if (node.tagName === "I") { - const el = document.createElement("em"); - moveChildren(node, el, null); - node.parentElement?.replaceChild(el, node); - node = el; - } - if (node.tagName === "B") { - const el = document.createElement("strong"); - moveChildren(node, el, null); - node.parentElement?.replaceChild(el, node); - node = el; - } - - if (node instanceof HTMLImageElement) { - node.dataset.multimediaInner = ""; - const figureEl = types.multimedia.create(editor); - - let targetEl = node.parentElement; - if (!targetEl) throw new Error("No encontré lx objetivo"); - while (true) { - const type = getType(targetEl); - if (!type) throw new Error("lx objetivo tiene tipo"); - if (type.type.allowedChildren.includes("multimedia")) break; - if (!targetEl.parentElement) throw new Error("No encontré lx objetivo"); - targetEl = targetEl.parentElement; - } - - let parentEl = [...targetEl.childNodes].find((el) => el.contains(node)); - if (!parentEl) throw new Error("no encontré lx pariente"); - targetEl.insertBefore(figureEl, parentEl); - - const innerEl = figureEl.querySelector("[data-multimedia-inner]"); - if (!innerEl) throw new Error("Raro."); - figureEl.replaceChild(node, innerEl); - - node = figureEl; - } - - const _type = getType(node); - if (!_type) return; - - const { typeName, type } = _type; - - if (type.allowedChildren !== "ignore-children") { - const sel = safeGetSelection(editor); - const range = sel && safeGetRangeAt(sel); - - if (getValidChildren(node, type).length == 0) { - if (typeof type.handleEmpty !== "string") { - const el = type.handleEmpty.create(editor); - // mover cosas que pueden haber - // por ejemplo: cuando convertís a un
    , queda texto fuera del li que - // creamos acá - moveChildren(node, el, null); - node.appendChild(el); - if (range?.intersectsNode(node)) sel?.collapse(el); - } - } - - for (const child of node.childNodes) { - if (!(child instanceof Element)) continue; - fixContent(editor, child); - } - } -} - -// Esta funcion hace que los elementos del editor sigan la estructura. -// TODO: nos falta borrar atributos (style, y básicamente cualquier otra cosa) -// Edge cases: -// * no borramos los
    por que se requieren para que los navegadores -// funcionen bien al escribir. no se deberían mostrar de todas maneras -function cleanContent(editor: Editor, node: Element = editor.contentEl): void { - const _type = getType(node); - if (!_type) { - node.parentElement?.removeChild(node); - return; - } - - const { type } = _type; - - if (type.allowedChildren !== "ignore-children") { - for (const child of node.childNodes) { - if ( - child.nodeType === Node.TEXT_NODE && - !type.allowedChildren.includes("text") - ) { - node.removeChild(child); - continue; - } - - if (!(child instanceof Element)) continue; - - const childType = getType(child); - if (childType?.typeName === "br") continue; - if (!childType || !type.allowedChildren.includes(childType.typeName)) { - // XXX: esto extrae las cosas de adentro para que no sea destructivo - moveChildren(child, node, child); - node.removeChild(child); - return; - } - - cleanContent(editor, child); - } - - // solo contar children válido para ese nodo - const validChildrenLength = getValidChildren(node, type).length; - - const sel = safeGetSelection(editor); - const range = sel && safeGetRangeAt(sel); - if ( - type.handleEmpty === "remove" && - validChildrenLength == 0 - //&& (!range || !range.intersectsNode(node)) - ) { - node.parentNode?.removeChild(node); - return; - } - } -} - -function routine(editor: Editor): void { - try { - fixContent(editor); - cleanContent(editor); - storeContent(editor); - - editor.htmlEl.value = editor.contentEl.innerHTML; - } catch (error) { - console.error("Hubo un problema corriendo la rutina", editor, error); - } -} - -export interface Editor { - editorEl: HTMLElement; - toolbarEl: HTMLElement; - toolbar: { - auxiliary: { - mark: { - parentEl: HTMLElement; - colorEl: HTMLInputElement; - textColorEl: HTMLInputElement; - }; - multimedia: { - parentEl: HTMLElement; - fileEl: HTMLInputElement; - uploadEl: HTMLButtonElement; - altEl: HTMLInputElement; - removeEl: HTMLButtonElement; - }; - link: { - parentEl: HTMLElement; - urlEl: HTMLInputElement; - }; - }; - }; - contentEl: HTMLElement; - wordAlertEl: HTMLElement; - htmlEl: HTMLTextAreaElement; -} - -function getSel(parentEl: HTMLElement, selector: string): T { - const el = parentEl.querySelector(selector); - if (!el) throw new Error(`No pude encontrar un componente \`${selector}\``); - return el; -} - -function setupEditor(editorEl: HTMLElement): void { - // XXX: ¡Esto afecta a todo el documento! ¿Quizás usar un iframe para el editor? - document.execCommand("defaultParagraphSeparator", false, "p"); - - const editor: Editor = { - editorEl, - toolbarEl: getSel(editorEl, ".editor-toolbar"), - toolbar: { - auxiliary: { - mark: { - parentEl: getSel(editorEl, "[data-editor-auxiliary=mark]"), - colorEl: getSel( - editorEl, - "[data-editor-auxiliary=mark] [name=mark-color]" - ), - textColorEl: getSel( - editorEl, - "[data-editor-auxiliary=mark] [name=mark-text-color]" - ), - }, - multimedia: { - parentEl: getSel(editorEl, "[data-editor-auxiliary=multimedia]"), - fileEl: getSel( - editorEl, - "[data-editor-auxiliary=multimedia] [name=multimedia-file]" - ), - uploadEl: getSel( - editorEl, - "[data-editor-auxiliary=multimedia] [name=multimedia-file-upload]" - ), - altEl: getSel( - editorEl, - "[data-editor-auxiliary=multimedia] [name=multimedia-alt]" - ), - removeEl: getSel( - editorEl, - "[data-editor-auxiliary=multimedia] [name=multimedia-remove]" - ), - }, - link: { - parentEl: getSel(editorEl, "[data-editor-auxiliary=link]"), - urlEl: getSel( - editorEl, - "[data-editor-auxiliary=link] [name=link-url]" - ), - }, - }, - }, - contentEl: getSel(editorEl, ".editor-content"), - wordAlertEl: getSel(editorEl, ".editor-aviso-word"), - htmlEl: getSel(editorEl, "textarea"), - }; - console.debug("iniciando editor", editor); - - // Recuperar el contenido si hay algo guardado, si tuviéramos un campo - // de última edición podríamos saber si el artículo fue editado - // después o la versión local es la última. - // - // TODO: Preguntar si se lo quiere recuperar. - restoreContent(editor); - - // Word alert - editor.contentEl.addEventListener("paste", () => { - editor.wordAlertEl.style.display = "block"; - }); - - // Setup routine listeners - const observer = new MutationObserver(() => routine(editor)); - observer.observe(editor.contentEl, { - childList: true, - attributes: true, - subtree: true, - characterData: true, - }); - - document.addEventListener("selectionchange", () => routine(editor)); - - // Capture onClick - editor.contentEl.addEventListener( - "click", - (event) => { - const target = event.target! as Element; - const type = getType(target); - if (!type || !type.type.onClick) { - setAuxiliaryToolbar(editor, null); - clearSelected(editor); - return true; - } - type.type.onClick(editor, target); - return false; - }, - true - ); - - // Clean seleted - const selectedEl = editor.contentEl.querySelector("[data-editor-selected]"); - if (selectedEl) delete (selectedEl as HTMLElement).dataset.editorSelected; - - // Setup botones - setupMarksButtons(editor); - setupBlocksButtons(editor); - setupParentBlocksButtons(editor); - setupMultimediaButtons(editor); - - setupLinkAuxiliaryToolbar(editor); - setupMultimediaAuxiliaryToolbar(editor); - setupMarkAuxiliaryToolbar(editor); - - // Finally... - routine(editor); -} - document.addEventListener("turbolinks:load", () => { const flash = document.querySelector(".js-flash"); From c0b5863573dbd174d3100c09aa7bc66c8078ffef Mon Sep 17 00:00:00 2001 From: f Date: Tue, 10 Aug 2021 18:38:33 -0300 Subject: [PATCH 006/814] Deprecar el editor incorporado --- app/javascript/editor/storage.ts | 38 ---- app/javascript/editor/types.ts | 140 ------------ app/javascript/editor/types/blocks.ts | 76 ------- app/javascript/editor/types/link.ts | 37 ---- app/javascript/editor/types/mark.ts | 66 ------ app/javascript/editor/types/marks.ts | 102 --------- app/javascript/editor/types/multimedia.ts | 230 -------------------- app/javascript/editor/types/parentBlocks.ts | 78 ------- app/javascript/editor/utils.ts | 101 --------- 9 files changed, 868 deletions(-) delete mode 100644 app/javascript/editor/storage.ts delete mode 100644 app/javascript/editor/types.ts delete mode 100644 app/javascript/editor/types/blocks.ts delete mode 100644 app/javascript/editor/types/link.ts delete mode 100644 app/javascript/editor/types/mark.ts delete mode 100644 app/javascript/editor/types/marks.ts delete mode 100644 app/javascript/editor/types/multimedia.ts delete mode 100644 app/javascript/editor/types/parentBlocks.ts delete mode 100644 app/javascript/editor/utils.ts diff --git a/app/javascript/editor/storage.ts b/app/javascript/editor/storage.ts deleted file mode 100644 index e914a242..00000000 --- a/app/javascript/editor/storage.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Editor } from "editor/editor"; - -/* - * Guarda una copia local de los cambios para poder recuperarlos - * después. - * - * Usamos la URL completa sin anchors. - */ -function getStorageKey(editor: Editor): string { - const keyEl = editor.editorEl.querySelector( - '[data-target="storage-key"]' - ); - if (!keyEl) - throw new Error("No encuentro la llave para guardar los artículos"); - return keyEl.value; -} - -export function forgetContent(storedKey: string): void { - window.localStorage.removeItem(storedKey); -} - -export function storeContent(editor: Editor): void { - if (editor.contentEl.innerText.trim().length === 0) return; - - window.localStorage.setItem( - getStorageKey(editor), - editor.contentEl.innerHTML - ); -} - -export function restoreContent(editor: Editor): void { - const content = window.localStorage.getItem(getStorageKey(editor)); - - if (!content) return; - if (content.trim().length === 0) return; - - editor.contentEl.innerHTML = content; -} diff --git a/app/javascript/editor/types.ts b/app/javascript/editor/types.ts deleted file mode 100644 index ac3030ce..00000000 --- a/app/javascript/editor/types.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { Editor } from "editor/editor"; -import { marks } from "editor/types/marks"; -import { blocks, li, EditorBlock } from "editor/types/blocks"; -import { parentBlocks } from "editor/types/parentBlocks"; -import { multimedia } from "editor/types/multimedia"; -import { - blockNames, - parentBlockNames, - safeGetRangeAt, - safeGetSelection, -} from "editor/utils"; - -export interface EditorNode { - selector: string; - // la string es el nombre en la gran lista de types O 'text' - // XXX: esto es un hack para no poner EditorNode dentro de EditorNode, - // quizás podemos hacer que esto sea una función que retorna bool - allowedChildren: string[] | "ignore-children"; - - // * si es 'do-nothing', no hace nada si está vacío (esto es para cuando - // permitís 'text' entonces se puede tipear adentro, ej: párrafo vacío) - // * si es 'remove', sacamos el coso si está vacío. - // ej: strong: { handleNothing: 'remove' } - // * si es un block, insertamos el bloque y movemos la selección ahí - // ej: ul: { handleNothing: li } - handleEmpty: "do-nothing" | "remove" | EditorBlock; - - // esta función puede ser llamada para cosas que no necesariamente sea la - // creación del nodo con el botón; por ejemplo, al intentar recuperar - // el formato. esto es importante por que, por ejemplo, no deberíamos - // cambiar la selección acá. - create: (editor: Editor) => HTMLElement; - - onClick?: (editor: Editor, target: Element) => void; -} - -export const types: { [propName: string]: EditorNode } = { - ...marks, - ...blocks, - li, - ...parentBlocks, - contentEl: { - selector: ".editor-content", - allowedChildren: [...blockNames, ...parentBlockNames, "multimedia"], - handleEmpty: blocks.paragraph, - create: () => { - throw new Error("se intentó crear contentEl"); - }, - }, - br: { - selector: "br", - allowedChildren: [], - handleEmpty: "do-nothing", - create: () => { - throw new Error("se intentó crear br"); - }, - }, - multimedia, -}; - -export function getType( - node: Element -): { typeName: string; type: EditorNode } | null { - for (let [typeName, type] of Object.entries(types)) { - if (node.matches(type.selector)) { - return { typeName, type }; - } - } - - return null; -} - -// encuentra el primer pariente que pueda tener al type, y retorna un array -// donde -// array[0] = elemento que matchea el type -// array[array.len - 1] = primer elemento seleccionado -export function getValidParentInSelection(args: { - editor: Editor; - type: string; -}): Element[] { - const sel = safeGetSelection(args.editor); - if (!sel) throw new Error("No se donde insertar esto"); - const range = safeGetRangeAt(sel); - if (!range) throw new Error("No se donde insertar esto"); - - let list: Element[] = []; - - if (!sel.anchorNode) { - throw new Error("No se donde insertar esto"); - } else if (sel.anchorNode instanceof Element) { - list = [sel.anchorNode]; - } else if (sel.anchorNode.parentElement) { - list = [sel.anchorNode.parentElement]; - } else { - throw new Error("No se donde insertar esto"); - } - - while (true) { - const el = list[0]; - if (!args.editor.contentEl.contains(el) && el != args.editor.contentEl) - throw new Error("No se donde insertar esto"); - const type = getType(el); - - if (type) { - //if (type.typeName === 'contentEl') break - //if (parentBlockNames.includes(type.typeName)) break - if ( - type.type.allowedChildren instanceof Array && - type.type.allowedChildren.includes(args.type) - ) - break; - } - if (el.parentElement) { - list = [el.parentElement, ...list]; - } else { - throw new Error("No se donde insertar esto"); - } - } - - return list; -} - -export function getValidChildren(node: Element, type: EditorNode): Node[] { - if (type.allowedChildren === "ignore-children") - throw new Error( - "se llamó a getValidChildren con un type que no lo permite!" - ); - return [...node.childNodes].filter((n) => { - // si permite texto y esto es un texto, es válido - if (n.nodeType === Node.TEXT_NODE) - return type.allowedChildren.includes("text") && n.textContent?.length; - - // si no es un elemento, no es válido - if (!(n instanceof Element)) return false; - - const t = getType(n); - if (!t) return false; - return type.allowedChildren.includes(t.typeName); - }); -} diff --git a/app/javascript/editor/types/blocks.ts b/app/javascript/editor/types/blocks.ts deleted file mode 100644 index 2e2dea7e..00000000 --- a/app/javascript/editor/types/blocks.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Editor } from "editor/editor"; -import { - safeGetSelection, - safeGetRangeAt, - moveChildren, - markNames, - blockNames, - parentBlockNames, -} from "editor/utils"; -import { EditorNode, getType, getValidParentInSelection } from "editor/types"; - -export interface EditorBlock extends EditorNode {} - -function makeBlock(tag: string): EditorBlock { - return { - selector: tag, - allowedChildren: [...markNames, "text"], - handleEmpty: "do-nothing", - create: () => document.createElement(tag), - }; -} - -export const li: EditorBlock = makeBlock("li"); - -// XXX: si agregás algo acá, agregalo a blockNames -// (y probablemente le quieras hacer un botón en app/views/posts/attributes/_content.haml) -export const blocks: { [propName: string]: EditorBlock } = { - paragraph: makeBlock("p"), - h1: makeBlock("h1"), - h2: makeBlock("h2"), - h3: makeBlock("h3"), - h4: makeBlock("h4"), - h5: makeBlock("h5"), - h6: makeBlock("h6"), - unordered_list: { - ...makeBlock("ul"), - allowedChildren: ["li"], - handleEmpty: li, - }, - ordered_list: { - ...makeBlock("ol"), - allowedChildren: ["li"], - handleEmpty: li, - }, -}; - -export function setupButtons(editor: Editor): void { - for (const [name, type] of Object.entries(blocks)) { - const buttonEl = editor.toolbarEl.querySelector( - `[data-editor-button="block-${name}"]` - ); - if (!buttonEl) continue; - buttonEl.addEventListener("click", (event) => { - event.preventDefault(); - - const list = getValidParentInSelection({ editor, type: name }); - - // No borrar cosas como multimedia - if (blockNames.indexOf(getType(list[1])!.typeName) === -1) { - return; - } - - let replacementType = list[1].matches(type.selector) - ? blocks.paragraph - : type; - - const el = replacementType.create(editor); - replacementType.onClick && replacementType.onClick(editor, el); - moveChildren(list[1], el, null); - list[0].replaceChild(el, list[1]); - window.getSelection()?.collapse(el); - - return false; - }); - } -} diff --git a/app/javascript/editor/types/link.ts b/app/javascript/editor/types/link.ts deleted file mode 100644 index eb85db90..00000000 --- a/app/javascript/editor/types/link.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Editor } from "editor/editor"; -import { EditorNode } from "editor/types"; -import { markNames, setAuxiliaryToolbar, clearSelected } from "editor/utils"; - -function select(editor: Editor, el: HTMLAnchorElement): void { - clearSelected(editor); - el.dataset.editorSelected = ""; - editor.toolbar.auxiliary.link.urlEl.value = el.href; - setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.link.parentEl); -} - -export const link: EditorNode = { - selector: "a", - allowedChildren: [...markNames.filter((n) => n !== "link"), "text"], - handleEmpty: "remove", - create: () => document.createElement("a"), - onClick(editor, el) { - if (!(el instanceof HTMLAnchorElement)) throw new Error("oh no"); - select(editor, el); - }, -}; - -export function setupAuxiliaryToolbar(editor: Editor): void { - editor.toolbar.auxiliary.link.urlEl.addEventListener("input", (event) => { - const url = editor.toolbar.auxiliary.link.urlEl.value; - const selectedEl = editor.contentEl.querySelector( - "a[data-editor-selected]" - ); - if (!selectedEl) - throw new Error("No pude encontrar el link para setear el enlace"); - - selectedEl.href = url; - }); - editor.toolbar.auxiliary.link.urlEl.addEventListener("keydown", (event) => { - if (event.keyCode == 13) event.preventDefault(); - }); -} diff --git a/app/javascript/editor/types/mark.ts b/app/javascript/editor/types/mark.ts deleted file mode 100644 index 4735c799..00000000 --- a/app/javascript/editor/types/mark.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Editor } from "editor/editor"; -import { EditorNode } from "editor/types"; -import { markNames, setAuxiliaryToolbar, clearSelected } from "editor/utils"; - -const hex = (x: string) => ("0" + parseInt(x).toString(16)).slice(-2); -// https://stackoverflow.com/a/3627747 -// TODO: cambiar por una solución más copada -function rgbToHex(rgb: string): string { - const matches = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); - if (!matches) throw new Error("no pude parsear el rgb()"); - return "#" + hex(matches[1]) + hex(matches[2]) + hex(matches[3]); -} - -function select(editor: Editor, el: HTMLElement): void { - clearSelected(editor); - el.dataset.editorSelected = ""; - editor.toolbar.auxiliary.mark.colorEl.value = el.style.backgroundColor - ? rgbToHex(el.style.backgroundColor) - : "#f206f9"; - editor.toolbar.auxiliary.mark.textColorEl.value = el.style.color - ? rgbToHex(el.style.color) - : "#000000"; - setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.mark.parentEl); -} - -export const mark: EditorNode = { - selector: "mark", - allowedChildren: [...markNames.filter((n) => n !== "mark"), "text"], - handleEmpty: "remove", - create: () => document.createElement("mark"), - onClick(editor, el) { - if (!(el instanceof HTMLElement)) throw new Error("oh no"); - select(editor, el); - }, -}; - -export function setupAuxiliaryToolbar(editor: Editor): void { - editor.toolbar.auxiliary.mark.colorEl.addEventListener("input", (event) => { - const color = editor.toolbar.auxiliary.mark.colorEl.value; - const selectedEl = editor.contentEl.querySelector( - "mark[data-editor-selected]" - ); - if (!selectedEl) - throw new Error("No pude encontrar el mark para setear el color"); - - selectedEl.style.backgroundColor = color; - }); - editor.toolbar.auxiliary.mark.textColorEl.addEventListener( - "input", - (event) => { - const color = editor.toolbar.auxiliary.mark.textColorEl.value; - const selectedEl = editor.contentEl.querySelector( - "mark[data-editor-selected]" - ); - if (!selectedEl) - throw new Error( - "No pude encontrar el mark para setear el color del text" - ); - - selectedEl.style.color = color; - } - ); - editor.toolbar.auxiliary.mark.colorEl.addEventListener("keydown", (event) => { - if (event.keyCode == 13) event.preventDefault(); - }); -} diff --git a/app/javascript/editor/types/marks.ts b/app/javascript/editor/types/marks.ts deleted file mode 100644 index 0ea5a5ad..00000000 --- a/app/javascript/editor/types/marks.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Editor } from "editor/editor"; -import { EditorNode } from "editor/types"; -import { - safeGetSelection, - safeGetRangeAt, - moveChildren, - markNames, -} from "editor/utils"; -import { link } from "editor/types/link"; -import { mark } from "editor/types/mark"; - -function makeMark(name: string, tag: string): EditorNode { - return { - selector: tag, - allowedChildren: [...markNames.filter((n) => n !== name), "text"], - handleEmpty: "remove", - create: () => document.createElement(tag), - }; -} - -// XXX: si agregás algo acá, agregalo a markNames -export const marks: { [propName: string]: EditorNode } = { - bold: makeMark("bold", "strong"), - italic: makeMark("italic", "em"), - deleted: makeMark("deleted", "del"), - underline: makeMark("underline", "u"), - sub: makeMark("sub", "sub"), - super: makeMark("super", "sup"), - mark, - link, - small: makeMark("small", "small"), -}; - -function recursiveFilterSelection( - node: Element, - selection: Selection, - selector: string -): Element[] { - let output: Element[] = []; - for (const child of [...node.children]) { - if (child.matches(selector) && selection.containsNode(child)) - output.push(child); - output = [ - ...output, - ...recursiveFilterSelection(child, selection, selector), - ]; - } - return output; -} - -export function setupButtons(editor: Editor): void { - for (const [name, type] of Object.entries(marks)) { - const buttonEl = editor.toolbarEl.querySelector( - `[data-editor-button="mark-${name}"]` - ); - if (!buttonEl) continue; - buttonEl.addEventListener("click", (event) => { - event.preventDefault(); - - const sel = safeGetSelection(editor); - if (!sel) return; - const range = safeGetRangeAt(sel); - if (!range) return; - - let parentEl = range.commonAncestorContainer; - while (!(parentEl instanceof Element)) { - if (!parentEl.parentElement) return; - parentEl = parentEl.parentElement; - } - - const existingMarks = recursiveFilterSelection( - parentEl, - sel, - type.selector - ); - console.debug("marks encontradas:", existingMarks); - - if (existingMarks.length > 0) { - const mark = existingMarks[0]; - if (!mark.parentElement) throw new Error(":/"); - moveChildren(mark, mark.parentElement, mark); - mark.parentElement.removeChild(mark); - } else { - if (range.commonAncestorContainer === editor.contentEl) - // TODO: mostrar error - return console.error( - "No puedo marcar cosas a través de distintos bloques!" - ); - - const tagEl = type.create(editor); - type.onClick && type.onClick(editor, tagEl); - - tagEl.appendChild(range.extractContents()); - - range.insertNode(tagEl); - range.selectNode(tagEl); - } - - return false; - }); - } -} diff --git a/app/javascript/editor/types/multimedia.ts b/app/javascript/editor/types/multimedia.ts deleted file mode 100644 index 2af9643a..00000000 --- a/app/javascript/editor/types/multimedia.ts +++ /dev/null @@ -1,230 +0,0 @@ -import * as ActiveStorage from "@rails/activestorage"; -import { Editor } from "editor/editor"; -import { EditorNode, getValidParentInSelection } from "editor/types"; -import { - safeGetSelection, - safeGetRangeAt, - markNames, - parentBlockNames, - setAuxiliaryToolbar, - clearSelected, -} from "editor/utils"; - -function uploadFile(file: File): Promise { - return new Promise((resolve, reject) => { - const upload = new ActiveStorage.DirectUpload( - file, - origin + "/rails/active_storage/direct_uploads" - ); - - upload.create((error: any, blob: any) => { - if (error) { - reject(error); - } else { - const url = `${origin}/rails/active_storage/blobs/${blob.signed_id}/${blob.filename}`; - resolve(url); - } - }); - }); -} - -function getAlt(multimediaInnerEl: HTMLElement): string | null { - switch (multimediaInnerEl.tagName) { - case "VIDEO": - case "AUDIO": - return multimediaInnerEl.getAttribute("aria-label"); - case "IMG": - return (multimediaInnerEl as HTMLImageElement).alt; - case "IFRAME": - return multimediaInnerEl.title; - default: - throw new Error("no pude conseguir el alt"); - } -} -function setAlt(multimediaInnerEl: HTMLElement, value: string): void { - switch (multimediaInnerEl.tagName) { - case "VIDEO": - case "AUDIO": - multimediaInnerEl.setAttribute("aria-label", value); - break; - case "IMG": - (multimediaInnerEl as HTMLImageElement).alt = value; - break; - case "IFRAME": - multimediaInnerEl.title = value; - break; - default: - throw new Error("no pude setear el alt"); - } -} - -function select(editor: Editor, el: HTMLElement): void { - clearSelected(editor); - el.dataset.editorSelected = ""; - - const innerEl = el.querySelector("[data-multimedia-inner]"); - if (!innerEl) throw new Error("No hay multimedia válida"); - if (innerEl.tagName === "P") { - editor.toolbar.auxiliary.multimedia.altEl.value = ""; - editor.toolbar.auxiliary.multimedia.altEl.disabled = true; - } else { - editor.toolbar.auxiliary.multimedia.altEl.value = getAlt(innerEl) || ""; - editor.toolbar.auxiliary.multimedia.altEl.disabled = false; - } - - setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.multimedia.parentEl); -} - -export const multimedia: EditorNode = { - selector: "figure[data-multimedia]", - allowedChildren: "ignore-children", - handleEmpty: "remove", - create: () => { - const figureEl = document.createElement("figure"); - figureEl.dataset.multimedia = ""; - figureEl.contentEditable = "false"; - - const placeholderEl = document.createElement("p"); - placeholderEl.dataset.multimediaInner = ""; - // TODO i18n - placeholderEl.append("¡Clickeame para subir un archivo!"); - figureEl.appendChild(placeholderEl); - - const descriptionEl = document.createElement("figcaption"); - descriptionEl.contentEditable = "true"; - // TODO i18n - descriptionEl.append("Escribí acá la descripción del archivo."); - figureEl.appendChild(descriptionEl); - - return figureEl; - }, - onClick(editor, el) { - if (!(el instanceof HTMLElement)) throw new Error("oh no"); - select(editor, el); - }, -}; -function createElementWithFile(url: string, type: string): HTMLElement { - if (type.match(/^image\/.+$/)) { - const el = document.createElement("img"); - el.dataset.multimediaInner = ""; - el.src = url; - return el; - } else if (type.match(/^video\/.+$/)) { - const el = document.createElement("video"); - el.controls = true; - el.dataset.multimediaInner = ""; - el.src = url; - return el; - } else if (type.match(/^audio\/.+$/)) { - const el = document.createElement("audio"); - el.controls = true; - el.dataset.multimediaInner = ""; - el.src = url; - return el; - } else if (type.match(/^application\/pdf$/)) { - const el = document.createElement("iframe"); - el.dataset.multimediaInner = ""; - el.src = url; - return el; - } else { - // TODO: chequear si el archivo es válido antes de subir - throw new Error("Tipo de archivo no reconocido"); - } -} - -export function setupAuxiliaryToolbar(editor: Editor): void { - editor.toolbar.auxiliary.multimedia.uploadEl.addEventListener( - "click", - (event) => { - const files = editor.toolbar.auxiliary.multimedia.fileEl.files; - if (!files || !files.length) - throw new Error("no hay archivos para subir"); - const file = files[0]; - - const selectedEl = editor.contentEl.querySelector( - "figure[data-editor-selected]" - ); - if (!selectedEl) - throw new Error("No pude encontrar el elemento para setear el archivo"); - - selectedEl.dataset.editorLoading = ""; - uploadFile(file) - .then((url) => { - const innerEl = selectedEl.querySelector("[data-multimedia-inner]"); - if (!innerEl) throw new Error("No hay multimedia a reemplazar"); - - const el = createElementWithFile(url, file.type); - setAlt(el, editor.toolbar.auxiliary.multimedia.altEl.value); - selectedEl.replaceChild(el, innerEl); - - select(editor, selectedEl); - - delete selectedEl.dataset.editorError; - }) - .catch((err) => { - console.error(err); - // TODO: mostrar error - selectedEl.dataset.editorError = ""; - }) - .finally(() => { - delete selectedEl.dataset.editorLoading; - }); - } - ); - - editor.toolbar.auxiliary.multimedia.removeEl.addEventListener( - "click", - (event) => { - const selectedEl = editor.contentEl.querySelector( - "figure[data-editor-selected]" - ); - if (!selectedEl) - throw new Error("No pude encontrar el elemento para borrar"); - - selectedEl.parentElement?.removeChild(selectedEl); - setAuxiliaryToolbar(editor, null); - } - ); - - editor.toolbar.auxiliary.multimedia.altEl.addEventListener( - "input", - (event) => { - const selectedEl = editor.contentEl.querySelector( - "figure[data-editor-selected]" - ); - if (!selectedEl) - throw new Error("No pude encontrar el multimedia para setear el alt"); - - const innerEl = selectedEl.querySelector( - "[data-multimedia-inner]" - ); - if (!innerEl) throw new Error("No hay multimedia a para setear el alt"); - - setAlt(innerEl, editor.toolbar.auxiliary.multimedia.altEl.value); - } - ); - editor.toolbar.auxiliary.multimedia.altEl.addEventListener( - "keydown", - (event) => { - if (event.keyCode == 13) event.preventDefault(); - } - ); -} - -export function setupButtons(editor: Editor): void { - const buttonEl = editor.toolbarEl.querySelector( - '[data-editor-button="multimedia"]' - ); - if (!buttonEl) throw new Error("No encontre el botón de multimedia"); - buttonEl.addEventListener("click", (event) => { - event.preventDefault(); - - const list = getValidParentInSelection({ editor, type: "multimedia" }); - - const el = multimedia.create(editor); - list[0].insertBefore(el, list[1].nextElementSibling); - select(editor, el); - - return false; - }); -} diff --git a/app/javascript/editor/types/parentBlocks.ts b/app/javascript/editor/types/parentBlocks.ts deleted file mode 100644 index ffe40bdf..00000000 --- a/app/javascript/editor/types/parentBlocks.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Editor } from "editor/editor"; -import { - safeGetSelection, - safeGetRangeAt, - moveChildren, - blockNames, - parentBlockNames, -} from "editor/utils"; -import { EditorNode, getType, getValidParentInSelection } from "editor/types"; - -function makeParentBlock( - tag: string, - create: EditorNode["create"] -): EditorNode { - return { - selector: tag, - allowedChildren: [...blockNames, "multimedia"], - handleEmpty: "remove", - create, - }; -} - -// TODO: añadir blockquote -// XXX: si agregás algo acá, probablemente le quieras hacer un botón -// en app/views/posts/attributes/_content.haml -export const parentBlocks: { [propName: string]: EditorNode } = { - left: makeParentBlock("div[data-align=left]", () => { - const el = document.createElement("div"); - el.dataset.align = "left"; - el.style.textAlign = "left"; - return el; - }), - center: makeParentBlock("div[data-align=center]", () => { - const el = document.createElement("div"); - el.dataset.align = "center"; - el.style.textAlign = "center"; - return el; - }), - right: makeParentBlock("div[data-align=right]", () => { - const el = document.createElement("div"); - el.dataset.align = "right"; - el.style.textAlign = "right"; - return el; - }), -}; - -export function setupButtons(editor: Editor): void { - for (const [name, type] of Object.entries(parentBlocks)) { - const buttonEl = editor.toolbarEl.querySelector( - `[data-editor-button="parentBlock-${name}"]` - ); - if (!buttonEl) continue; - buttonEl.addEventListener("click", (event) => { - event.preventDefault(); - - // TODO: Esto solo mueve el bloque en el que está el final de la selección - // (anchorNode). quizás lo podemos hacer al revés (iterar desde contentEl - // para encontrar los bloques que están seleccionados y moverlos/cambiarles - // el parentBlock) - - const list = getValidParentInSelection({ editor, type: name }); - - const replacementEl = type.create(editor); - if (list[0] == editor.contentEl) { - // no está en un parentBlock - editor.contentEl.insertBefore(replacementEl, list[1]); - replacementEl.appendChild(list[1]); - } else { - // está en un parentBlock - moveChildren(list[0], replacementEl, null); - editor.contentEl.replaceChild(replacementEl, list[0]); - } - window.getSelection()?.collapse(replacementEl); - - return false; - }); - } -} diff --git a/app/javascript/editor/utils.ts b/app/javascript/editor/utils.ts deleted file mode 100644 index 167c0a6d..00000000 --- a/app/javascript/editor/utils.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Editor } from "editor/editor"; - -export const blockNames = [ - "paragraph", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "unordered_list", - "ordered_list", -]; -export const markNames = [ - "bold", - "italic", - "deleted", - "underline", - "sub", - "super", - "mark", - "link", - "small", -]; -export const parentBlockNames = ["left", "center", "right"]; - -export function moveChildren(from: Element, to: Element, toRef: Node | null) { - while (from.firstChild) to.insertBefore(from.firstChild, toRef); -} - -export function isDirectChild(node: Node, supposedChild: Node): boolean { - for (const child of node.childNodes) { - if (child == supposedChild) return true; - } - return false; -} - -export function safeGetSelection(editor: Editor): Selection | null { - const sel = window.getSelection(); - if (!sel) return null; - // XXX: no damos la selección si esta fuera o _es_ el contentEl, ¿quizás - // deberíamos mostrar un error? - if ( - !editor.contentEl.contains(sel.anchorNode) || - !editor.contentEl.contains(sel.focusNode) || - sel.anchorNode == editor.contentEl || - sel.focusNode == editor.contentEl - ) - return null; - return sel; -} - -export function safeGetRangeAt(selection: Selection, num = 0): Range | null { - try { - return selection.getRangeAt(num); - } catch (error) { - return null; - } -} - -interface SplitNode { - range: Range; - node: Node; -} - -export function splitNode(node: Element, range: Range): [SplitNode, SplitNode] { - const [left, right] = [ - { range: document.createRange(), node: node.cloneNode(false) }, - { range: document.createRange(), node: node.cloneNode(false) }, - ]; - - if (node.firstChild) left.range.setStartBefore(node.firstChild); - left.range.setEnd(range.startContainer, range.startOffset); - left.range.surroundContents(left.node); - - right.range.setStart(range.endContainer, range.endOffset); - if (node.lastChild) right.range.setEndAfter(node.lastChild); - right.range.surroundContents(right.node); - - if (!node.parentElement) - throw new Error("No pude separar los nodos por que no tiene parentNode"); - - moveChildren(node, node.parentElement, node); - node.parentElement.removeChild(node); - - return [left, right]; -} - -export function setAuxiliaryToolbar( - editor: Editor, - bar: HTMLElement | null -): void { - for (const { parentEl } of Object.values(editor.toolbar.auxiliary)) { - delete parentEl.dataset.editorAuxiliaryActive; - } - if (bar) bar.dataset.editorAuxiliaryActive = "active"; -} -export function clearSelected(editor: Editor): void { - const selectedEl = editor.contentEl.querySelector("[data-editor-selected]"); - if (selectedEl) delete (selectedEl as HTMLElement).dataset.editorSelected; -} From a4ca89a36b382e88d3bd5451d33575df998ccabc Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Sep 2021 20:07:51 -0300 Subject: [PATCH 007/814] @suttyweb/editor@0.0.8 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9560cdf3..23ed3e5e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "0.0.7", + "@suttyweb/editor": "0.0.8", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 604ee871..86e54004 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@0.0.7": - version "0.0.7" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.7.tgz#019c1ab2d43e6a6fb7d4ebf44c44f79ebd5a6896" - integrity sha512-fZepXH1pRTdDQWxKSF10lYVlYjoczkqGi00vTaSWDRTL/rnZrgOEakcdFyutcJzYnZWdWsWsF6AUidKvQvd1dw== +"@suttyweb/editor@0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.8.tgz#5803b9bcbab69fc4bf40fb939d1ec2283d44d2fd" + integrity sha512-vBBfTaGwu8IH4Gd+Q8cFC+XjjeEZ/8gSqT830hCO0kHzEvHEPTSEokffVR5DffBkS7ZKCvwsNXKzz/QuvkfHuQ== "@types/caseless@*": version "0.12.2" From 6154b3667083dfca0a4b4b1b6268855f67e17adb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 21 Oct 2022 16:31:54 -0300 Subject: [PATCH 008/814] Revert "Deprecar el editor incorporado" This reverts commit c0b5863573dbd174d3100c09aa7bc66c8078ffef. --- app/javascript/editor/storage.ts | 38 ++++ app/javascript/editor/types.ts | 140 ++++++++++++ app/javascript/editor/types/blocks.ts | 76 +++++++ app/javascript/editor/types/link.ts | 37 ++++ app/javascript/editor/types/mark.ts | 66 ++++++ app/javascript/editor/types/marks.ts | 102 +++++++++ app/javascript/editor/types/multimedia.ts | 230 ++++++++++++++++++++ app/javascript/editor/types/parentBlocks.ts | 78 +++++++ app/javascript/editor/utils.ts | 101 +++++++++ 9 files changed, 868 insertions(+) create mode 100644 app/javascript/editor/storage.ts create mode 100644 app/javascript/editor/types.ts create mode 100644 app/javascript/editor/types/blocks.ts create mode 100644 app/javascript/editor/types/link.ts create mode 100644 app/javascript/editor/types/mark.ts create mode 100644 app/javascript/editor/types/marks.ts create mode 100644 app/javascript/editor/types/multimedia.ts create mode 100644 app/javascript/editor/types/parentBlocks.ts create mode 100644 app/javascript/editor/utils.ts diff --git a/app/javascript/editor/storage.ts b/app/javascript/editor/storage.ts new file mode 100644 index 00000000..e914a242 --- /dev/null +++ b/app/javascript/editor/storage.ts @@ -0,0 +1,38 @@ +import { Editor } from "editor/editor"; + +/* + * Guarda una copia local de los cambios para poder recuperarlos + * después. + * + * Usamos la URL completa sin anchors. + */ +function getStorageKey(editor: Editor): string { + const keyEl = editor.editorEl.querySelector( + '[data-target="storage-key"]' + ); + if (!keyEl) + throw new Error("No encuentro la llave para guardar los artículos"); + return keyEl.value; +} + +export function forgetContent(storedKey: string): void { + window.localStorage.removeItem(storedKey); +} + +export function storeContent(editor: Editor): void { + if (editor.contentEl.innerText.trim().length === 0) return; + + window.localStorage.setItem( + getStorageKey(editor), + editor.contentEl.innerHTML + ); +} + +export function restoreContent(editor: Editor): void { + const content = window.localStorage.getItem(getStorageKey(editor)); + + if (!content) return; + if (content.trim().length === 0) return; + + editor.contentEl.innerHTML = content; +} diff --git a/app/javascript/editor/types.ts b/app/javascript/editor/types.ts new file mode 100644 index 00000000..ac3030ce --- /dev/null +++ b/app/javascript/editor/types.ts @@ -0,0 +1,140 @@ +import { Editor } from "editor/editor"; +import { marks } from "editor/types/marks"; +import { blocks, li, EditorBlock } from "editor/types/blocks"; +import { parentBlocks } from "editor/types/parentBlocks"; +import { multimedia } from "editor/types/multimedia"; +import { + blockNames, + parentBlockNames, + safeGetRangeAt, + safeGetSelection, +} from "editor/utils"; + +export interface EditorNode { + selector: string; + // la string es el nombre en la gran lista de types O 'text' + // XXX: esto es un hack para no poner EditorNode dentro de EditorNode, + // quizás podemos hacer que esto sea una función que retorna bool + allowedChildren: string[] | "ignore-children"; + + // * si es 'do-nothing', no hace nada si está vacío (esto es para cuando + // permitís 'text' entonces se puede tipear adentro, ej: párrafo vacío) + // * si es 'remove', sacamos el coso si está vacío. + // ej: strong: { handleNothing: 'remove' } + // * si es un block, insertamos el bloque y movemos la selección ahí + // ej: ul: { handleNothing: li } + handleEmpty: "do-nothing" | "remove" | EditorBlock; + + // esta función puede ser llamada para cosas que no necesariamente sea la + // creación del nodo con el botón; por ejemplo, al intentar recuperar + // el formato. esto es importante por que, por ejemplo, no deberíamos + // cambiar la selección acá. + create: (editor: Editor) => HTMLElement; + + onClick?: (editor: Editor, target: Element) => void; +} + +export const types: { [propName: string]: EditorNode } = { + ...marks, + ...blocks, + li, + ...parentBlocks, + contentEl: { + selector: ".editor-content", + allowedChildren: [...blockNames, ...parentBlockNames, "multimedia"], + handleEmpty: blocks.paragraph, + create: () => { + throw new Error("se intentó crear contentEl"); + }, + }, + br: { + selector: "br", + allowedChildren: [], + handleEmpty: "do-nothing", + create: () => { + throw new Error("se intentó crear br"); + }, + }, + multimedia, +}; + +export function getType( + node: Element +): { typeName: string; type: EditorNode } | null { + for (let [typeName, type] of Object.entries(types)) { + if (node.matches(type.selector)) { + return { typeName, type }; + } + } + + return null; +} + +// encuentra el primer pariente que pueda tener al type, y retorna un array +// donde +// array[0] = elemento que matchea el type +// array[array.len - 1] = primer elemento seleccionado +export function getValidParentInSelection(args: { + editor: Editor; + type: string; +}): Element[] { + const sel = safeGetSelection(args.editor); + if (!sel) throw new Error("No se donde insertar esto"); + const range = safeGetRangeAt(sel); + if (!range) throw new Error("No se donde insertar esto"); + + let list: Element[] = []; + + if (!sel.anchorNode) { + throw new Error("No se donde insertar esto"); + } else if (sel.anchorNode instanceof Element) { + list = [sel.anchorNode]; + } else if (sel.anchorNode.parentElement) { + list = [sel.anchorNode.parentElement]; + } else { + throw new Error("No se donde insertar esto"); + } + + while (true) { + const el = list[0]; + if (!args.editor.contentEl.contains(el) && el != args.editor.contentEl) + throw new Error("No se donde insertar esto"); + const type = getType(el); + + if (type) { + //if (type.typeName === 'contentEl') break + //if (parentBlockNames.includes(type.typeName)) break + if ( + type.type.allowedChildren instanceof Array && + type.type.allowedChildren.includes(args.type) + ) + break; + } + if (el.parentElement) { + list = [el.parentElement, ...list]; + } else { + throw new Error("No se donde insertar esto"); + } + } + + return list; +} + +export function getValidChildren(node: Element, type: EditorNode): Node[] { + if (type.allowedChildren === "ignore-children") + throw new Error( + "se llamó a getValidChildren con un type que no lo permite!" + ); + return [...node.childNodes].filter((n) => { + // si permite texto y esto es un texto, es válido + if (n.nodeType === Node.TEXT_NODE) + return type.allowedChildren.includes("text") && n.textContent?.length; + + // si no es un elemento, no es válido + if (!(n instanceof Element)) return false; + + const t = getType(n); + if (!t) return false; + return type.allowedChildren.includes(t.typeName); + }); +} diff --git a/app/javascript/editor/types/blocks.ts b/app/javascript/editor/types/blocks.ts new file mode 100644 index 00000000..2e2dea7e --- /dev/null +++ b/app/javascript/editor/types/blocks.ts @@ -0,0 +1,76 @@ +import { Editor } from "editor/editor"; +import { + safeGetSelection, + safeGetRangeAt, + moveChildren, + markNames, + blockNames, + parentBlockNames, +} from "editor/utils"; +import { EditorNode, getType, getValidParentInSelection } from "editor/types"; + +export interface EditorBlock extends EditorNode {} + +function makeBlock(tag: string): EditorBlock { + return { + selector: tag, + allowedChildren: [...markNames, "text"], + handleEmpty: "do-nothing", + create: () => document.createElement(tag), + }; +} + +export const li: EditorBlock = makeBlock("li"); + +// XXX: si agregás algo acá, agregalo a blockNames +// (y probablemente le quieras hacer un botón en app/views/posts/attributes/_content.haml) +export const blocks: { [propName: string]: EditorBlock } = { + paragraph: makeBlock("p"), + h1: makeBlock("h1"), + h2: makeBlock("h2"), + h3: makeBlock("h3"), + h4: makeBlock("h4"), + h5: makeBlock("h5"), + h6: makeBlock("h6"), + unordered_list: { + ...makeBlock("ul"), + allowedChildren: ["li"], + handleEmpty: li, + }, + ordered_list: { + ...makeBlock("ol"), + allowedChildren: ["li"], + handleEmpty: li, + }, +}; + +export function setupButtons(editor: Editor): void { + for (const [name, type] of Object.entries(blocks)) { + const buttonEl = editor.toolbarEl.querySelector( + `[data-editor-button="block-${name}"]` + ); + if (!buttonEl) continue; + buttonEl.addEventListener("click", (event) => { + event.preventDefault(); + + const list = getValidParentInSelection({ editor, type: name }); + + // No borrar cosas como multimedia + if (blockNames.indexOf(getType(list[1])!.typeName) === -1) { + return; + } + + let replacementType = list[1].matches(type.selector) + ? blocks.paragraph + : type; + + const el = replacementType.create(editor); + replacementType.onClick && replacementType.onClick(editor, el); + moveChildren(list[1], el, null); + list[0].replaceChild(el, list[1]); + window.getSelection()?.collapse(el); + + return false; + }); + } +} diff --git a/app/javascript/editor/types/link.ts b/app/javascript/editor/types/link.ts new file mode 100644 index 00000000..eb85db90 --- /dev/null +++ b/app/javascript/editor/types/link.ts @@ -0,0 +1,37 @@ +import { Editor } from "editor/editor"; +import { EditorNode } from "editor/types"; +import { markNames, setAuxiliaryToolbar, clearSelected } from "editor/utils"; + +function select(editor: Editor, el: HTMLAnchorElement): void { + clearSelected(editor); + el.dataset.editorSelected = ""; + editor.toolbar.auxiliary.link.urlEl.value = el.href; + setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.link.parentEl); +} + +export const link: EditorNode = { + selector: "a", + allowedChildren: [...markNames.filter((n) => n !== "link"), "text"], + handleEmpty: "remove", + create: () => document.createElement("a"), + onClick(editor, el) { + if (!(el instanceof HTMLAnchorElement)) throw new Error("oh no"); + select(editor, el); + }, +}; + +export function setupAuxiliaryToolbar(editor: Editor): void { + editor.toolbar.auxiliary.link.urlEl.addEventListener("input", (event) => { + const url = editor.toolbar.auxiliary.link.urlEl.value; + const selectedEl = editor.contentEl.querySelector( + "a[data-editor-selected]" + ); + if (!selectedEl) + throw new Error("No pude encontrar el link para setear el enlace"); + + selectedEl.href = url; + }); + editor.toolbar.auxiliary.link.urlEl.addEventListener("keydown", (event) => { + if (event.keyCode == 13) event.preventDefault(); + }); +} diff --git a/app/javascript/editor/types/mark.ts b/app/javascript/editor/types/mark.ts new file mode 100644 index 00000000..4735c799 --- /dev/null +++ b/app/javascript/editor/types/mark.ts @@ -0,0 +1,66 @@ +import { Editor } from "editor/editor"; +import { EditorNode } from "editor/types"; +import { markNames, setAuxiliaryToolbar, clearSelected } from "editor/utils"; + +const hex = (x: string) => ("0" + parseInt(x).toString(16)).slice(-2); +// https://stackoverflow.com/a/3627747 +// TODO: cambiar por una solución más copada +function rgbToHex(rgb: string): string { + const matches = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); + if (!matches) throw new Error("no pude parsear el rgb()"); + return "#" + hex(matches[1]) + hex(matches[2]) + hex(matches[3]); +} + +function select(editor: Editor, el: HTMLElement): void { + clearSelected(editor); + el.dataset.editorSelected = ""; + editor.toolbar.auxiliary.mark.colorEl.value = el.style.backgroundColor + ? rgbToHex(el.style.backgroundColor) + : "#f206f9"; + editor.toolbar.auxiliary.mark.textColorEl.value = el.style.color + ? rgbToHex(el.style.color) + : "#000000"; + setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.mark.parentEl); +} + +export const mark: EditorNode = { + selector: "mark", + allowedChildren: [...markNames.filter((n) => n !== "mark"), "text"], + handleEmpty: "remove", + create: () => document.createElement("mark"), + onClick(editor, el) { + if (!(el instanceof HTMLElement)) throw new Error("oh no"); + select(editor, el); + }, +}; + +export function setupAuxiliaryToolbar(editor: Editor): void { + editor.toolbar.auxiliary.mark.colorEl.addEventListener("input", (event) => { + const color = editor.toolbar.auxiliary.mark.colorEl.value; + const selectedEl = editor.contentEl.querySelector( + "mark[data-editor-selected]" + ); + if (!selectedEl) + throw new Error("No pude encontrar el mark para setear el color"); + + selectedEl.style.backgroundColor = color; + }); + editor.toolbar.auxiliary.mark.textColorEl.addEventListener( + "input", + (event) => { + const color = editor.toolbar.auxiliary.mark.textColorEl.value; + const selectedEl = editor.contentEl.querySelector( + "mark[data-editor-selected]" + ); + if (!selectedEl) + throw new Error( + "No pude encontrar el mark para setear el color del text" + ); + + selectedEl.style.color = color; + } + ); + editor.toolbar.auxiliary.mark.colorEl.addEventListener("keydown", (event) => { + if (event.keyCode == 13) event.preventDefault(); + }); +} diff --git a/app/javascript/editor/types/marks.ts b/app/javascript/editor/types/marks.ts new file mode 100644 index 00000000..0ea5a5ad --- /dev/null +++ b/app/javascript/editor/types/marks.ts @@ -0,0 +1,102 @@ +import { Editor } from "editor/editor"; +import { EditorNode } from "editor/types"; +import { + safeGetSelection, + safeGetRangeAt, + moveChildren, + markNames, +} from "editor/utils"; +import { link } from "editor/types/link"; +import { mark } from "editor/types/mark"; + +function makeMark(name: string, tag: string): EditorNode { + return { + selector: tag, + allowedChildren: [...markNames.filter((n) => n !== name), "text"], + handleEmpty: "remove", + create: () => document.createElement(tag), + }; +} + +// XXX: si agregás algo acá, agregalo a markNames +export const marks: { [propName: string]: EditorNode } = { + bold: makeMark("bold", "strong"), + italic: makeMark("italic", "em"), + deleted: makeMark("deleted", "del"), + underline: makeMark("underline", "u"), + sub: makeMark("sub", "sub"), + super: makeMark("super", "sup"), + mark, + link, + small: makeMark("small", "small"), +}; + +function recursiveFilterSelection( + node: Element, + selection: Selection, + selector: string +): Element[] { + let output: Element[] = []; + for (const child of [...node.children]) { + if (child.matches(selector) && selection.containsNode(child)) + output.push(child); + output = [ + ...output, + ...recursiveFilterSelection(child, selection, selector), + ]; + } + return output; +} + +export function setupButtons(editor: Editor): void { + for (const [name, type] of Object.entries(marks)) { + const buttonEl = editor.toolbarEl.querySelector( + `[data-editor-button="mark-${name}"]` + ); + if (!buttonEl) continue; + buttonEl.addEventListener("click", (event) => { + event.preventDefault(); + + const sel = safeGetSelection(editor); + if (!sel) return; + const range = safeGetRangeAt(sel); + if (!range) return; + + let parentEl = range.commonAncestorContainer; + while (!(parentEl instanceof Element)) { + if (!parentEl.parentElement) return; + parentEl = parentEl.parentElement; + } + + const existingMarks = recursiveFilterSelection( + parentEl, + sel, + type.selector + ); + console.debug("marks encontradas:", existingMarks); + + if (existingMarks.length > 0) { + const mark = existingMarks[0]; + if (!mark.parentElement) throw new Error(":/"); + moveChildren(mark, mark.parentElement, mark); + mark.parentElement.removeChild(mark); + } else { + if (range.commonAncestorContainer === editor.contentEl) + // TODO: mostrar error + return console.error( + "No puedo marcar cosas a través de distintos bloques!" + ); + + const tagEl = type.create(editor); + type.onClick && type.onClick(editor, tagEl); + + tagEl.appendChild(range.extractContents()); + + range.insertNode(tagEl); + range.selectNode(tagEl); + } + + return false; + }); + } +} diff --git a/app/javascript/editor/types/multimedia.ts b/app/javascript/editor/types/multimedia.ts new file mode 100644 index 00000000..2af9643a --- /dev/null +++ b/app/javascript/editor/types/multimedia.ts @@ -0,0 +1,230 @@ +import * as ActiveStorage from "@rails/activestorage"; +import { Editor } from "editor/editor"; +import { EditorNode, getValidParentInSelection } from "editor/types"; +import { + safeGetSelection, + safeGetRangeAt, + markNames, + parentBlockNames, + setAuxiliaryToolbar, + clearSelected, +} from "editor/utils"; + +function uploadFile(file: File): Promise { + return new Promise((resolve, reject) => { + const upload = new ActiveStorage.DirectUpload( + file, + origin + "/rails/active_storage/direct_uploads" + ); + + upload.create((error: any, blob: any) => { + if (error) { + reject(error); + } else { + const url = `${origin}/rails/active_storage/blobs/${blob.signed_id}/${blob.filename}`; + resolve(url); + } + }); + }); +} + +function getAlt(multimediaInnerEl: HTMLElement): string | null { + switch (multimediaInnerEl.tagName) { + case "VIDEO": + case "AUDIO": + return multimediaInnerEl.getAttribute("aria-label"); + case "IMG": + return (multimediaInnerEl as HTMLImageElement).alt; + case "IFRAME": + return multimediaInnerEl.title; + default: + throw new Error("no pude conseguir el alt"); + } +} +function setAlt(multimediaInnerEl: HTMLElement, value: string): void { + switch (multimediaInnerEl.tagName) { + case "VIDEO": + case "AUDIO": + multimediaInnerEl.setAttribute("aria-label", value); + break; + case "IMG": + (multimediaInnerEl as HTMLImageElement).alt = value; + break; + case "IFRAME": + multimediaInnerEl.title = value; + break; + default: + throw new Error("no pude setear el alt"); + } +} + +function select(editor: Editor, el: HTMLElement): void { + clearSelected(editor); + el.dataset.editorSelected = ""; + + const innerEl = el.querySelector("[data-multimedia-inner]"); + if (!innerEl) throw new Error("No hay multimedia válida"); + if (innerEl.tagName === "P") { + editor.toolbar.auxiliary.multimedia.altEl.value = ""; + editor.toolbar.auxiliary.multimedia.altEl.disabled = true; + } else { + editor.toolbar.auxiliary.multimedia.altEl.value = getAlt(innerEl) || ""; + editor.toolbar.auxiliary.multimedia.altEl.disabled = false; + } + + setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.multimedia.parentEl); +} + +export const multimedia: EditorNode = { + selector: "figure[data-multimedia]", + allowedChildren: "ignore-children", + handleEmpty: "remove", + create: () => { + const figureEl = document.createElement("figure"); + figureEl.dataset.multimedia = ""; + figureEl.contentEditable = "false"; + + const placeholderEl = document.createElement("p"); + placeholderEl.dataset.multimediaInner = ""; + // TODO i18n + placeholderEl.append("¡Clickeame para subir un archivo!"); + figureEl.appendChild(placeholderEl); + + const descriptionEl = document.createElement("figcaption"); + descriptionEl.contentEditable = "true"; + // TODO i18n + descriptionEl.append("Escribí acá la descripción del archivo."); + figureEl.appendChild(descriptionEl); + + return figureEl; + }, + onClick(editor, el) { + if (!(el instanceof HTMLElement)) throw new Error("oh no"); + select(editor, el); + }, +}; +function createElementWithFile(url: string, type: string): HTMLElement { + if (type.match(/^image\/.+$/)) { + const el = document.createElement("img"); + el.dataset.multimediaInner = ""; + el.src = url; + return el; + } else if (type.match(/^video\/.+$/)) { + const el = document.createElement("video"); + el.controls = true; + el.dataset.multimediaInner = ""; + el.src = url; + return el; + } else if (type.match(/^audio\/.+$/)) { + const el = document.createElement("audio"); + el.controls = true; + el.dataset.multimediaInner = ""; + el.src = url; + return el; + } else if (type.match(/^application\/pdf$/)) { + const el = document.createElement("iframe"); + el.dataset.multimediaInner = ""; + el.src = url; + return el; + } else { + // TODO: chequear si el archivo es válido antes de subir + throw new Error("Tipo de archivo no reconocido"); + } +} + +export function setupAuxiliaryToolbar(editor: Editor): void { + editor.toolbar.auxiliary.multimedia.uploadEl.addEventListener( + "click", + (event) => { + const files = editor.toolbar.auxiliary.multimedia.fileEl.files; + if (!files || !files.length) + throw new Error("no hay archivos para subir"); + const file = files[0]; + + const selectedEl = editor.contentEl.querySelector( + "figure[data-editor-selected]" + ); + if (!selectedEl) + throw new Error("No pude encontrar el elemento para setear el archivo"); + + selectedEl.dataset.editorLoading = ""; + uploadFile(file) + .then((url) => { + const innerEl = selectedEl.querySelector("[data-multimedia-inner]"); + if (!innerEl) throw new Error("No hay multimedia a reemplazar"); + + const el = createElementWithFile(url, file.type); + setAlt(el, editor.toolbar.auxiliary.multimedia.altEl.value); + selectedEl.replaceChild(el, innerEl); + + select(editor, selectedEl); + + delete selectedEl.dataset.editorError; + }) + .catch((err) => { + console.error(err); + // TODO: mostrar error + selectedEl.dataset.editorError = ""; + }) + .finally(() => { + delete selectedEl.dataset.editorLoading; + }); + } + ); + + editor.toolbar.auxiliary.multimedia.removeEl.addEventListener( + "click", + (event) => { + const selectedEl = editor.contentEl.querySelector( + "figure[data-editor-selected]" + ); + if (!selectedEl) + throw new Error("No pude encontrar el elemento para borrar"); + + selectedEl.parentElement?.removeChild(selectedEl); + setAuxiliaryToolbar(editor, null); + } + ); + + editor.toolbar.auxiliary.multimedia.altEl.addEventListener( + "input", + (event) => { + const selectedEl = editor.contentEl.querySelector( + "figure[data-editor-selected]" + ); + if (!selectedEl) + throw new Error("No pude encontrar el multimedia para setear el alt"); + + const innerEl = selectedEl.querySelector( + "[data-multimedia-inner]" + ); + if (!innerEl) throw new Error("No hay multimedia a para setear el alt"); + + setAlt(innerEl, editor.toolbar.auxiliary.multimedia.altEl.value); + } + ); + editor.toolbar.auxiliary.multimedia.altEl.addEventListener( + "keydown", + (event) => { + if (event.keyCode == 13) event.preventDefault(); + } + ); +} + +export function setupButtons(editor: Editor): void { + const buttonEl = editor.toolbarEl.querySelector( + '[data-editor-button="multimedia"]' + ); + if (!buttonEl) throw new Error("No encontre el botón de multimedia"); + buttonEl.addEventListener("click", (event) => { + event.preventDefault(); + + const list = getValidParentInSelection({ editor, type: "multimedia" }); + + const el = multimedia.create(editor); + list[0].insertBefore(el, list[1].nextElementSibling); + select(editor, el); + + return false; + }); +} diff --git a/app/javascript/editor/types/parentBlocks.ts b/app/javascript/editor/types/parentBlocks.ts new file mode 100644 index 00000000..ffe40bdf --- /dev/null +++ b/app/javascript/editor/types/parentBlocks.ts @@ -0,0 +1,78 @@ +import { Editor } from "editor/editor"; +import { + safeGetSelection, + safeGetRangeAt, + moveChildren, + blockNames, + parentBlockNames, +} from "editor/utils"; +import { EditorNode, getType, getValidParentInSelection } from "editor/types"; + +function makeParentBlock( + tag: string, + create: EditorNode["create"] +): EditorNode { + return { + selector: tag, + allowedChildren: [...blockNames, "multimedia"], + handleEmpty: "remove", + create, + }; +} + +// TODO: añadir blockquote +// XXX: si agregás algo acá, probablemente le quieras hacer un botón +// en app/views/posts/attributes/_content.haml +export const parentBlocks: { [propName: string]: EditorNode } = { + left: makeParentBlock("div[data-align=left]", () => { + const el = document.createElement("div"); + el.dataset.align = "left"; + el.style.textAlign = "left"; + return el; + }), + center: makeParentBlock("div[data-align=center]", () => { + const el = document.createElement("div"); + el.dataset.align = "center"; + el.style.textAlign = "center"; + return el; + }), + right: makeParentBlock("div[data-align=right]", () => { + const el = document.createElement("div"); + el.dataset.align = "right"; + el.style.textAlign = "right"; + return el; + }), +}; + +export function setupButtons(editor: Editor): void { + for (const [name, type] of Object.entries(parentBlocks)) { + const buttonEl = editor.toolbarEl.querySelector( + `[data-editor-button="parentBlock-${name}"]` + ); + if (!buttonEl) continue; + buttonEl.addEventListener("click", (event) => { + event.preventDefault(); + + // TODO: Esto solo mueve el bloque en el que está el final de la selección + // (anchorNode). quizás lo podemos hacer al revés (iterar desde contentEl + // para encontrar los bloques que están seleccionados y moverlos/cambiarles + // el parentBlock) + + const list = getValidParentInSelection({ editor, type: name }); + + const replacementEl = type.create(editor); + if (list[0] == editor.contentEl) { + // no está en un parentBlock + editor.contentEl.insertBefore(replacementEl, list[1]); + replacementEl.appendChild(list[1]); + } else { + // está en un parentBlock + moveChildren(list[0], replacementEl, null); + editor.contentEl.replaceChild(replacementEl, list[0]); + } + window.getSelection()?.collapse(replacementEl); + + return false; + }); + } +} diff --git a/app/javascript/editor/utils.ts b/app/javascript/editor/utils.ts new file mode 100644 index 00000000..167c0a6d --- /dev/null +++ b/app/javascript/editor/utils.ts @@ -0,0 +1,101 @@ +import { Editor } from "editor/editor"; + +export const blockNames = [ + "paragraph", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "unordered_list", + "ordered_list", +]; +export const markNames = [ + "bold", + "italic", + "deleted", + "underline", + "sub", + "super", + "mark", + "link", + "small", +]; +export const parentBlockNames = ["left", "center", "right"]; + +export function moveChildren(from: Element, to: Element, toRef: Node | null) { + while (from.firstChild) to.insertBefore(from.firstChild, toRef); +} + +export function isDirectChild(node: Node, supposedChild: Node): boolean { + for (const child of node.childNodes) { + if (child == supposedChild) return true; + } + return false; +} + +export function safeGetSelection(editor: Editor): Selection | null { + const sel = window.getSelection(); + if (!sel) return null; + // XXX: no damos la selección si esta fuera o _es_ el contentEl, ¿quizás + // deberíamos mostrar un error? + if ( + !editor.contentEl.contains(sel.anchorNode) || + !editor.contentEl.contains(sel.focusNode) || + sel.anchorNode == editor.contentEl || + sel.focusNode == editor.contentEl + ) + return null; + return sel; +} + +export function safeGetRangeAt(selection: Selection, num = 0): Range | null { + try { + return selection.getRangeAt(num); + } catch (error) { + return null; + } +} + +interface SplitNode { + range: Range; + node: Node; +} + +export function splitNode(node: Element, range: Range): [SplitNode, SplitNode] { + const [left, right] = [ + { range: document.createRange(), node: node.cloneNode(false) }, + { range: document.createRange(), node: node.cloneNode(false) }, + ]; + + if (node.firstChild) left.range.setStartBefore(node.firstChild); + left.range.setEnd(range.startContainer, range.startOffset); + left.range.surroundContents(left.node); + + right.range.setStart(range.endContainer, range.endOffset); + if (node.lastChild) right.range.setEndAfter(node.lastChild); + right.range.surroundContents(right.node); + + if (!node.parentElement) + throw new Error("No pude separar los nodos por que no tiene parentNode"); + + moveChildren(node, node.parentElement, node); + node.parentElement.removeChild(node); + + return [left, right]; +} + +export function setAuxiliaryToolbar( + editor: Editor, + bar: HTMLElement | null +): void { + for (const { parentEl } of Object.values(editor.toolbar.auxiliary)) { + delete parentEl.dataset.editorAuxiliaryActive; + } + if (bar) bar.dataset.editorAuxiliaryActive = "active"; +} +export function clearSelected(editor: Editor): void { + const selectedEl = editor.contentEl.querySelector("[data-editor-selected]"); + if (selectedEl) delete (selectedEl as HTMLElement).dataset.editorSelected; +} From 5f4b589f4fbb46a648a1c9df50ce68cc2c368b9f Mon Sep 17 00:00:00 2001 From: f Date: Fri, 21 Oct 2022 16:32:09 -0300 Subject: [PATCH 009/814] Revert "Deprecar el editor" This reverts commit 6467a265d3fd2c1b77d576d2cd5412c6f189ac0d. --- app/javascript/editor/editor.ts | 313 ++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) diff --git a/app/javascript/editor/editor.ts b/app/javascript/editor/editor.ts index c254a650..233cc3c0 100644 --- a/app/javascript/editor/editor.ts +++ b/app/javascript/editor/editor.ts @@ -1,7 +1,320 @@ +import { storeContent, restoreContent, forgetContent } from "editor/storage"; +import { + isDirectChild, + moveChildren, + safeGetSelection, + safeGetRangeAt, + setAuxiliaryToolbar, + parentBlockNames, + clearSelected, +} from "editor/utils"; +import { types, getValidChildren, getType } from "editor/types"; +import { setupButtons as setupMarksButtons } from "editor/types/marks"; +import { setupButtons as setupBlocksButtons } from "editor/types/blocks"; +import { setupButtons as setupParentBlocksButtons } from "editor/types/parentBlocks"; +import { setupAuxiliaryToolbar as setupLinkAuxiliaryToolbar } from "editor/types/link"; +import { + setupAuxiliaryToolbar as setupMultimediaAuxiliaryToolbar, + setupButtons as setupMultimediaButtons, +} from "editor/types/multimedia"; +import { setupAuxiliaryToolbar as setupMarkAuxiliaryToolbar } from "editor/types/mark"; + /// @ts-ignore import SuttyEditor from "@suttyweb/editor"; import "@suttyweb/editor/dist/style.css"; +// Esta funcion corrije errores que pueden haber como: +// * que un nodo que no tiene 'text' permitido no tenga children (se les +// inserta un allowedChildren[0]) +// * TODO: que haya una imágen sin
    o que no esté como bloque (se ponen +// después del bloque en el que están como bloque de por si) +// * convierte y en y +// Lo hace para que siga la estructura del documento y que no se borren por +// cleanContent luego. +function fixContent(editor: Editor, node: Element = editor.contentEl): void { + if (node.tagName === "SCRIPT" || node.tagName === "STYLE") { + node.parentElement?.removeChild(node); + return; + } + + if (node.tagName === "I") { + const el = document.createElement("em"); + moveChildren(node, el, null); + node.parentElement?.replaceChild(el, node); + node = el; + } + if (node.tagName === "B") { + const el = document.createElement("strong"); + moveChildren(node, el, null); + node.parentElement?.replaceChild(el, node); + node = el; + } + + if (node instanceof HTMLImageElement) { + node.dataset.multimediaInner = ""; + const figureEl = types.multimedia.create(editor); + + let targetEl = node.parentElement; + if (!targetEl) throw new Error("No encontré lx objetivo"); + while (true) { + const type = getType(targetEl); + if (!type) throw new Error("lx objetivo tiene tipo"); + if (type.type.allowedChildren.includes("multimedia")) break; + if (!targetEl.parentElement) throw new Error("No encontré lx objetivo"); + targetEl = targetEl.parentElement; + } + + let parentEl = [...targetEl.childNodes].find((el) => el.contains(node)); + if (!parentEl) throw new Error("no encontré lx pariente"); + targetEl.insertBefore(figureEl, parentEl); + + const innerEl = figureEl.querySelector("[data-multimedia-inner]"); + if (!innerEl) throw new Error("Raro."); + figureEl.replaceChild(node, innerEl); + + node = figureEl; + } + + const _type = getType(node); + if (!_type) return; + + const { typeName, type } = _type; + + if (type.allowedChildren !== "ignore-children") { + const sel = safeGetSelection(editor); + const range = sel && safeGetRangeAt(sel); + + if (getValidChildren(node, type).length == 0) { + if (typeof type.handleEmpty !== "string") { + const el = type.handleEmpty.create(editor); + // mover cosas que pueden haber + // por ejemplo: cuando convertís a un
      , queda texto fuera del li que + // creamos acá + moveChildren(node, el, null); + node.appendChild(el); + if (range?.intersectsNode(node)) sel?.collapse(el); + } + } + + for (const child of node.childNodes) { + if (!(child instanceof Element)) continue; + fixContent(editor, child); + } + } +} + +// Esta funcion hace que los elementos del editor sigan la estructura. +// TODO: nos falta borrar atributos (style, y básicamente cualquier otra cosa) +// Edge cases: +// * no borramos los
      por que se requieren para que los navegadores +// funcionen bien al escribir. no se deberían mostrar de todas maneras +function cleanContent(editor: Editor, node: Element = editor.contentEl): void { + const _type = getType(node); + if (!_type) { + node.parentElement?.removeChild(node); + return; + } + + const { type } = _type; + + if (type.allowedChildren !== "ignore-children") { + for (const child of node.childNodes) { + if ( + child.nodeType === Node.TEXT_NODE && + !type.allowedChildren.includes("text") + ) { + node.removeChild(child); + continue; + } + + if (!(child instanceof Element)) continue; + + const childType = getType(child); + if (childType?.typeName === "br") continue; + if (!childType || !type.allowedChildren.includes(childType.typeName)) { + // XXX: esto extrae las cosas de adentro para que no sea destructivo + moveChildren(child, node, child); + node.removeChild(child); + return; + } + + cleanContent(editor, child); + } + + // solo contar children válido para ese nodo + const validChildrenLength = getValidChildren(node, type).length; + + const sel = safeGetSelection(editor); + const range = sel && safeGetRangeAt(sel); + if ( + type.handleEmpty === "remove" && + validChildrenLength == 0 + //&& (!range || !range.intersectsNode(node)) + ) { + node.parentNode?.removeChild(node); + return; + } + } +} + +function routine(editor: Editor): void { + try { + fixContent(editor); + cleanContent(editor); + storeContent(editor); + + editor.htmlEl.value = editor.contentEl.innerHTML; + } catch (error) { + console.error("Hubo un problema corriendo la rutina", editor, error); + } +} + +export interface Editor { + editorEl: HTMLElement; + toolbarEl: HTMLElement; + toolbar: { + auxiliary: { + mark: { + parentEl: HTMLElement; + colorEl: HTMLInputElement; + textColorEl: HTMLInputElement; + }; + multimedia: { + parentEl: HTMLElement; + fileEl: HTMLInputElement; + uploadEl: HTMLButtonElement; + altEl: HTMLInputElement; + removeEl: HTMLButtonElement; + }; + link: { + parentEl: HTMLElement; + urlEl: HTMLInputElement; + }; + }; + }; + contentEl: HTMLElement; + wordAlertEl: HTMLElement; + htmlEl: HTMLTextAreaElement; +} + +function getSel(parentEl: HTMLElement, selector: string): T { + const el = parentEl.querySelector(selector); + if (!el) throw new Error(`No pude encontrar un componente \`${selector}\``); + return el; +} + +function setupEditor(editorEl: HTMLElement): void { + // XXX: ¡Esto afecta a todo el documento! ¿Quizás usar un iframe para el editor? + document.execCommand("defaultParagraphSeparator", false, "p"); + + const editor: Editor = { + editorEl, + toolbarEl: getSel(editorEl, ".editor-toolbar"), + toolbar: { + auxiliary: { + mark: { + parentEl: getSel(editorEl, "[data-editor-auxiliary=mark]"), + colorEl: getSel( + editorEl, + "[data-editor-auxiliary=mark] [name=mark-color]" + ), + textColorEl: getSel( + editorEl, + "[data-editor-auxiliary=mark] [name=mark-text-color]" + ), + }, + multimedia: { + parentEl: getSel(editorEl, "[data-editor-auxiliary=multimedia]"), + fileEl: getSel( + editorEl, + "[data-editor-auxiliary=multimedia] [name=multimedia-file]" + ), + uploadEl: getSel( + editorEl, + "[data-editor-auxiliary=multimedia] [name=multimedia-file-upload]" + ), + altEl: getSel( + editorEl, + "[data-editor-auxiliary=multimedia] [name=multimedia-alt]" + ), + removeEl: getSel( + editorEl, + "[data-editor-auxiliary=multimedia] [name=multimedia-remove]" + ), + }, + link: { + parentEl: getSel(editorEl, "[data-editor-auxiliary=link]"), + urlEl: getSel( + editorEl, + "[data-editor-auxiliary=link] [name=link-url]" + ), + }, + }, + }, + contentEl: getSel(editorEl, ".editor-content"), + wordAlertEl: getSel(editorEl, ".editor-aviso-word"), + htmlEl: getSel(editorEl, "textarea"), + }; + console.debug("iniciando editor", editor); + + // Recuperar el contenido si hay algo guardado, si tuviéramos un campo + // de última edición podríamos saber si el artículo fue editado + // después o la versión local es la última. + // + // TODO: Preguntar si se lo quiere recuperar. + restoreContent(editor); + + // Word alert + editor.contentEl.addEventListener("paste", () => { + editor.wordAlertEl.style.display = "block"; + }); + + // Setup routine listeners + const observer = new MutationObserver(() => routine(editor)); + observer.observe(editor.contentEl, { + childList: true, + attributes: true, + subtree: true, + characterData: true, + }); + + document.addEventListener("selectionchange", () => routine(editor)); + + // Capture onClick + editor.contentEl.addEventListener( + "click", + (event) => { + const target = event.target! as Element; + const type = getType(target); + if (!type || !type.type.onClick) { + setAuxiliaryToolbar(editor, null); + clearSelected(editor); + return true; + } + type.type.onClick(editor, target); + return false; + }, + true + ); + + // Clean seleted + const selectedEl = editor.contentEl.querySelector("[data-editor-selected]"); + if (selectedEl) delete (selectedEl as HTMLElement).dataset.editorSelected; + + // Setup botones + setupMarksButtons(editor); + setupBlocksButtons(editor); + setupParentBlocksButtons(editor); + setupMultimediaButtons(editor); + + setupLinkAuxiliaryToolbar(editor); + setupMultimediaAuxiliaryToolbar(editor); + setupMarkAuxiliaryToolbar(editor); + + // Finally... + routine(editor); +} + document.addEventListener("turbolinks:load", () => { const flash = document.querySelector(".js-flash"); From 8221ae63c860946066996f2c1c1a1e53ecdfaf1f Mon Sep 17 00:00:00 2001 From: f Date: Fri, 21 Oct 2022 16:33:10 -0300 Subject: [PATCH 010/814] Revert "usar @suttyweb/editor" This reverts commit 7e0600779ed259f2bedc3603d5205d18bc21316b. --- app/javascript/editor/editor.ts | 15 +-- app/views/posts/attributes/_content.haml | 117 ++++++++++++++++++++++- package.json | 1 - yarn.lock | 5 - 4 files changed, 118 insertions(+), 20 deletions(-) diff --git a/app/javascript/editor/editor.ts b/app/javascript/editor/editor.ts index 233cc3c0..880547de 100644 --- a/app/javascript/editor/editor.ts +++ b/app/javascript/editor/editor.ts @@ -19,10 +19,6 @@ import { } from "editor/types/multimedia"; import { setupAuxiliaryToolbar as setupMarkAuxiliaryToolbar } from "editor/types/mark"; -/// @ts-ignore -import SuttyEditor from "@suttyweb/editor"; -import "@suttyweb/editor/dist/style.css"; - // Esta funcion corrije errores que pueden haber como: // * que un nodo que no tiene 'text' permitido no tenga children (se les // inserta un allowedChildren[0]) @@ -334,15 +330,10 @@ document.addEventListener("turbolinks:load", () => { ".editor[data-editor]" )) { try { - new SuttyEditor({ - target: editorEl, - props: { - textareaEl: editorEl.parentElement!.querySelector("textarea"), - }, - }); + setupEditor(editorEl); } catch (error) { - console.error(error); - alert(error); + // TODO: mostrar error + console.error("no se pudo iniciar el editor, error completo", error); } } }); diff --git a/app/views/posts/attributes/_content.haml b/app/views/posts/attributes/_content.haml index 65462397..4ae70ba0 100644 --- a/app/views/posts/attributes/_content.haml +++ b/app/views/posts/attributes/_content.haml @@ -9,6 +9,119 @@ .alert.alert-info :markdown #{t('editor.alert')} - = text_area_tag "#{base}[#{attribute}]", metadata.value.html_safe, + = text_area_tag "#{base}[#{attribute}]", '', dir: dir, lang: locale, - **field_options(attribute, metadata) + **field_options(attribute, metadata), class: 'd-none' + + -# + el > se come el salto de línea y hace que los botones no tengan + espacio adicional + + TODO: Eliminar todo el espacio en blanco para minificar HTML + .editor-toolbar{ style: 'z-index: 1' } + .editor-primary-toolbar.scrollbar-black + %button.btn{ type: 'button', title: t('editor.multimedia'), data: { editor_button: 'multimedia' } }> + %i.fa.fa-fw.fa-upload> + %span.sr-only>= t('editor.multimedia') + %button.btn{ type: 'button', title: t('editor.bold'), data: { editor_button: 'mark-bold' } }> + %i.fa.fa-fw.fa-bold> + %span.sr-only>= t('editor.bold') + %button.btn{ type: 'button', title: t('editor.italic'), data: { editor_button: 'mark-italic' } }> + %i.fa.fa-fw.fa-italic> + %span.sr-only>= t('editor.italic') + %button.btn{ type: 'button', title: t('editor.mark'), data: { editor_button: 'mark-mark' } }> + %i.fa.fa-fw.fa-tint> + %span.sr-only>= t('editor.mark') + %button.btn{ type: 'button', title: t('editor.link'), data: { editor_button: 'mark-link' } }> + %i.fa.fa-fw.fa-link> + %span.sr-only>= t('editor.link') + %button.btn{ type: 'button', title: t('editor.deleted'), data: { editor_button: 'mark-deleted' } }> + %i.fa.fa-fw.fa-strikethrough> + %span.sr-only>= t('editor.deleted') + %button.btn{ type: 'button', title: t('editor.underline'), data: { editor_button: 'mark-underline' } }> + %i.fa.fa-fw.fa-underline> + %span.sr-only>= t('editor.underline') + %button.btn{ type: 'button', title: t('editor.super'), data: { editor_button: 'mark-super' } }> + %i.fa.fa-fw.fa-superscript> + %span.sr-only>= t('editor.super') + %button.btn{ type: 'button', title: t('editor.sub'), data: { editor_button: 'mark-sub' } }> + %i.fa.fa-fw.fa-subscript> + %span.sr-only>= t('editor.sub') + %button.btn{ type: 'button', title: t('editor.small'), data: { editor_button: 'mark-small' } }> + %i.fa.fa-fw.fa-subscript> + %span.sr-only>= t('editor.small') + %button.btn.mr-0{ type: 'button', title: t('editor.h1'), data: { editor_button: 'block-h1' } }> + %i.fa.fa-fw.fa-heading> + 1 + %span.sr-only>= t('editor.h1') + %details.d-inline> + %summary.d-inline> + %span.btn.ml-0{ role: 'button', title: t('editor.more') }> + %i.fa.fa-caret-right> + %span.sr-only= t('editor.more') + .d-inline> + %button.btn{ type: 'button', title: t('editor.h2'), data: { editor_button: 'block-h2' } }> + %i.fa.fa-fw.fa-heading> + 2 + %span.sr-only>= t('editor.h2') + %button.btn{ type: 'button', title: t('editor.h3'), data: { editor_button: 'block-h3' } }> + %i.fa.fa-fw.fa-heading> + 3 + %span.sr-only>= t('editor.h3') + %button.btn{ type: 'button', title: t('editor.h4'), data: { editor_button: 'block-h4' } }> + %i.fa.fa-fw.fa-heading> + 4 + %span.sr-only>= t('editor.h4') + %button.btn{ type: 'button', title: t('editor.h5'), data: { editor_button: 'block-h5' } }> + %i.fa.fa-fw.fa-heading> + 5 + %span.sr-only>= t('editor.h5') + %button.btn{ type: 'button', title: t('editor.h6'), data: { editor_button: 'block-h6' } }> + %i.fa.fa-fw.fa-heading> + 6 + %span.sr-only>= t('editor.h6') + %button.btn{ type: 'button', title: t('editor.ul'), data: { editor_button: 'block-unordered_list' } }> + %i.fa.fa-fw.fa-list-ul> + %span.sr-only>= t('editor.ul') + %button.btn{ type: 'button', title: t('editor.ol'), data: { editor_button: 'block-ordered_list' } }> + %i.fa.fa-fw.fa-list-ol> + %span.sr-only>= t('editor.ol') + %button.btn{ type: 'button', title: t('editor.left'), data: { editor_button: 'parentBlock-left' } }> + %i.fa.fa-fw.fa-align-left> + %span.sr-only>= t('editor.left') + %button.btn{ type: 'button', title: t('editor.center'), data: { editor_button: 'parentBlock-center' } }> + %i.fa.fa-fw.fa-align-center> + %span.sr-only>= t('editor.center') + %button.btn{ type: 'button', title: t('editor.right'), data: { editor_button: 'parentBlock-right' } }> + %i.fa.fa-fw.fa-align-right> + %span.sr-only>= t('editor.right') + + -# HAML cringe + .editor-auxiliary-toolbar.mt-1.scrollbar-black{ data: { editor_auxiliary_toolbar: '' } } + .form-group{ data: { editor_auxiliary: 'mark' } } + %label{ for: 'mark-color' }= t('editor.color') + %input.form-control{ type: 'color', name: 'mark-color' }/ + %label{ for: 'mark-text-color' }= t('editor.text-color') + %input.form-control{ type: 'color', name: 'mark-text-color' }/ + + %div{ data: { editor_auxiliary: 'multimedia' } } + .form-group + .custom-file + %input.custom-file-input{ type: 'file', id: 'multimedia-file', name: 'multimedia-file' }/ + %label.custom-file-label{ for: 'multimedia-file' }= t('editor.multimedia-select') + .form-group + %label{ for: 'multimedia-alt' }= t('editor.description') + %input.form-control{ type: 'text', id: 'multimedia-alt', name: 'multimedia-alt' }/ + .form-group + %button.btn{ type: 'button', id: 'multimedia-file-upload', name: 'multimedia-file-upload' }= t('editor.multimedia-upload') + %button.btn{ type: 'button', id: 'multimedia-remove', name: 'multimedia-remove' }= t('editor.multimedia-remove') + + .form-group{ data: { editor_auxiliary: 'link' } } + %label{ for: 'link-url' }= t('editor.url') + %input.form-control{ type: 'url', id: 'link-url', name: 'link-url' }/ + + .editor-aviso-word.alert.alert-info + %p= t('editor.word') + + .editor-content.form-control.h-auto.mt-1{ contenteditable: 'true' } + = metadata.value.html_safe diff --git a/package.json b/package.json index 23ed3e5e..0a2458a6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "0.0.8", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 86e54004..11ff78cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,11 +1171,6 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.0.8.tgz#5803b9bcbab69fc4bf40fb939d1ec2283d44d2fd" - integrity sha512-vBBfTaGwu8IH4Gd+Q8cFC+XjjeEZ/8gSqT830hCO0kHzEvHEPTSEokffVR5DffBkS7ZKCvwsNXKzz/QuvkfHuQ== - "@types/caseless@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" From bed39ab4cfcdfded1f643213a0942eebc61e515d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 21 Oct 2022 16:33:40 -0300 Subject: [PATCH 011/814] usar @suttyweb/editor 0.1.0 --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 0a2458a6..1ead57ee 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", + "@suttyweb/editor": "^0.1.0", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 11ff78cb..97f4941c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,6 +1171,11 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== +"@suttyweb/editor@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.0.tgz#2dc451ceb7df39aaf2ab4c0372db177c4586014b" + integrity sha512-4P/lD3acOJM9iVo+c+OIf3yjA6NHuIVSNh782XfyDLGz8ZrJj7MEvpmJqiNHsqz7MT0gz5WHakM8GnU/C3bzXg== + "@types/caseless@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" From 87f638355db928437040fc1ef1d4f0eba69b10d4 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 22 Oct 2022 12:15:06 -0300 Subject: [PATCH 012/814] permitir atributos de cuidados en links sutty/editor#32 --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 5baa7a4a..d96b4b04 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -195,7 +195,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name].freeze + name rel target referrerpolicy].freeze end def allowed_tags From f448b4c7eed27575668ca728d5060067d9375ab7 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 24 Oct 2022 14:41:07 -0300 Subject: [PATCH 013/814] feat: marcar el editor actual como el antiguo --- app/assets/stylesheets/editor.scss | 2 +- app/views/posts/attributes/_content.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/editor.scss b/app/assets/stylesheets/editor.scss index 5d218c7e..ec90f920 100644 --- a/app/assets/stylesheets/editor.scss +++ b/app/assets/stylesheets/editor.scss @@ -1,4 +1,4 @@ -.editor { +.old.editor { box-sizing: border-box; *, *::before, *::after { box-sizing: inherit; } diff --git a/app/views/posts/attributes/_content.haml b/app/views/posts/attributes/_content.haml index 4ae70ba0..0b0a8310 100644 --- a/app/views/posts/attributes/_content.haml +++ b/app/views/posts/attributes/_content.haml @@ -3,7 +3,7 @@ = render 'posts/attribute_feedback', post: post, attribute: attribute, metadata: metadata - .editor{ id: attribute, data: { editor: '' } } + .old.editor{ id: attribute, data: { editor: '' } } -# Esto es para luego decirle al navegador que se olvide estas cosas. = hidden_field_tag 'storage_keys[]', "#{request.original_url}##{attribute}", data: { target: 'storage-key' } .alert.alert-info From e15191e242c722cd03a931ffc0771039e3babbd8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 24 Oct 2022 14:42:24 -0300 Subject: [PATCH 014/814] feat: soportar editor prosemirror con ui actual --- app/assets/stylesheets/application.scss | 2 ++ app/assets/stylesheets/new_editor.scss | 16 ++++++++++++++++ app/javascript/etc/index.js | 1 + app/javascript/etc/new_editor.js | 12 ++++++++++++ app/models/metadata_new_content.rb | 4 ++++ app/views/posts/attribute_ro/_new_content.haml | 3 +++ app/views/posts/attributes/_new_content.haml | 9 +++++++++ package.json | 2 +- yarn.lock | 8 ++++---- 9 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 app/assets/stylesheets/new_editor.scss create mode 100644 app/javascript/etc/new_editor.js create mode 100644 app/models/metadata_new_content.rb create mode 100644 app/views/posts/attribute_ro/_new_content.haml create mode 100644 app/views/posts/attributes/_new_content.haml diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index e806a032..6c94c194 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -504,3 +504,5 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } + +@import "new_editor"; diff --git a/app/assets/stylesheets/new_editor.scss b/app/assets/stylesheets/new_editor.scss new file mode 100644 index 00000000..73211303 --- /dev/null +++ b/app/assets/stylesheets/new_editor.scss @@ -0,0 +1,16 @@ +.new-editor { + .editor { + .menubar { + + label.btn { + margin-bottom: 0.3rem !important; + } + + .btn-group { + .btn { + margin-right: 0; + } + } + } + } +} diff --git a/app/javascript/etc/index.js b/app/javascript/etc/index.js index 482b78f6..d4b9f7a3 100644 --- a/app/javascript/etc/index.js +++ b/app/javascript/etc/index.js @@ -6,3 +6,4 @@ import './prosemirror' import './timezone' import './turbolinks-anchors' import './validation' +import './new_editor' diff --git a/app/javascript/etc/new_editor.js b/app/javascript/etc/new_editor.js new file mode 100644 index 00000000..d4b47ce8 --- /dev/null +++ b/app/javascript/etc/new_editor.js @@ -0,0 +1,12 @@ +import SuttyEditor from "@suttyweb/editor"; + +document.addEventListener("turbolinks:load", () => { + document.querySelectorAll(".new-editor").forEach((editorContainer) => { + new SuttyEditor({ + target: editorContainer, + props: { + textareaEl: editorContainer.querySelector("textarea"), + }, + }); + }); +}); diff --git a/app/models/metadata_new_content.rb b/app/models/metadata_new_content.rb new file mode 100644 index 00000000..da5ee7ab --- /dev/null +++ b/app/models/metadata_new_content.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +# Testear el nuevo editor +class MetadataNewContent < MetadataContent; end diff --git a/app/views/posts/attribute_ro/_new_content.haml b/app/views/posts/attribute_ro/_new_content.haml new file mode 100644 index 00000000..e6d9a274 --- /dev/null +++ b/app/views/posts/attribute_ro/_new_content.haml @@ -0,0 +1,3 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ lang: locale, dir: dir }= metadata.value diff --git a/app/views/posts/attributes/_new_content.haml b/app/views/posts/attributes/_new_content.haml new file mode 100644 index 00000000..34fc4e60 --- /dev/null +++ b/app/views/posts/attributes/_new_content.haml @@ -0,0 +1,9 @@ +.form-group + = label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post) + = render 'posts/attribute_feedback', + post: post, attribute: attribute, metadata: metadata + + .new-editor{ id: attribute } + = text_area_tag "#{base}[#{attribute}]", metadata.value.html_safe, + dir: dir, lang: locale, + **field_options(attribute, metadata), class: 'd-none' diff --git a/package.json b/package.json index 1ead57ee..0f043f0e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.0", + "@suttyweb/editor": "^0.1.2", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index 97f4941c..bc27c8c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.0.tgz#2dc451ceb7df39aaf2ab4c0372db177c4586014b" - integrity sha512-4P/lD3acOJM9iVo+c+OIf3yjA6NHuIVSNh782XfyDLGz8ZrJj7MEvpmJqiNHsqz7MT0gz5WHakM8GnU/C3bzXg== +"@suttyweb/editor@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.2.tgz#ff2798e993a78a55d334d7927d1e7c558203b483" + integrity sha512-OeMIB5KaqNo8XD2gJi5oDBlhkjWcPsSwxz3Ae2YaLp+cBuAZV2hWp7MoQpGGeWHjcgsE01fXR8TqL8B3KqBSig== "@types/caseless@*": version "0.12.2" From 937e41df9ff2632f1cfdbd60e1de1ff48242904a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 24 Oct 2022 15:16:18 -0300 Subject: [PATCH 015/814] fix: colocar el menu sobre el editor --- app/assets/stylesheets/new_editor.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/new_editor.scss b/app/assets/stylesheets/new_editor.scss index 73211303..e3f785b7 100644 --- a/app/assets/stylesheets/new_editor.scss +++ b/app/assets/stylesheets/new_editor.scss @@ -1,6 +1,7 @@ .new-editor { .editor { .menubar { + z-index: 1; label.btn { margin-bottom: 0.3rem !important; From e517ad9f36bc0782ba3b7cdbf6bb76c55d53f8e6 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 25 Oct 2022 20:13:18 -0300 Subject: [PATCH 016/814] fix: @sutty/editor 1.0.3 resuelve errores de usabilidad --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0f043f0e..bc53bfc9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.2", + "@suttyweb/editor": "^0.1.3", "babel-loader": "^8.2.2", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", diff --git a/yarn.lock b/yarn.lock index bc27c8c9..b46f5b9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.2.tgz#ff2798e993a78a55d334d7927d1e7c558203b483" - integrity sha512-OeMIB5KaqNo8XD2gJi5oDBlhkjWcPsSwxz3Ae2YaLp+cBuAZV2hWp7MoQpGGeWHjcgsE01fXR8TqL8B3KqBSig== +"@suttyweb/editor@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.3.tgz#59d4933b7aede145f8954676f6899b8f390990a3" + integrity sha512-C1XFb4Egn4EH4C1y8o2/9PvWq5DMe3q3e5FHbqNq5vtYLgYLF9hVIh2ApLsAl1kZvWQl/AEPheRyHzJypkK+3w== "@types/caseless@*": version "0.12.2" From ea392f21ce511c66f06c8d7dca2d50fc53ec881d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Oct 2022 17:25:58 -0300 Subject: [PATCH 017/814] fix: eliminar x-frame-options de disk controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit relacionado con sutty/editor#59 relacionado con sutty/editor#51 la razón por la que no se pueden incrustar pdfs es que rails agregar x-frame-options: sameorigin a todas las urls, aunque no es necesario para los archivos, porque les usuaries no interactuan con ellos para enviar información de vuelta al panel. --- .../active_storage/disk_controller_decorator.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/controllers/active_storage/disk_controller_decorator.rb b/app/controllers/active_storage/disk_controller_decorator.rb index 14366a15..0634a2ec 100644 --- a/app/controllers/active_storage/disk_controller_decorator.rb +++ b/app/controllers/active_storage/disk_controller_decorator.rb @@ -6,6 +6,16 @@ module ActiveStorage extend ActiveSupport::Concern included do + alias_method :original_show, :show + + # Permitir incrustar archivos subidos (especialmente PDFs) desde + # otros sitios. + def show + original_show.tap do |s| + response.headers.delete 'X-Frame-Options' + end + end + # Asociar el archivo subido al sitio correspondiente. Cada sitio # tiene su propio servicio de subida de archivos. def update From 7dd9061f3447ccdfc8c0066df0da1133cd4e6a41 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Oct 2022 17:42:56 -0300 Subject: [PATCH 018/814] fix: no limpiar las clases de css MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit relacionado con sutty/editor#51 las imágenes sobrepasan el contenedor porque el sanitizador elimina el atributo class. --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index e210fd2c..97a631c1 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -198,7 +198,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy].freeze + name rel target referrerpolicy class].freeze end def allowed_tags From 93dd2e096ebe5990bd1e7a159b048839ff54cbd2 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Oct 2022 18:15:41 -0300 Subject: [PATCH 019/814] @sutty/editor 1.0.4 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 075e9eb8..4b09f27d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.3", + "@suttyweb/editor": "^0.1.4", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 9eb018ab..7cbb0855 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.3.tgz#59d4933b7aede145f8954676f6899b8f390990a3" - integrity sha512-C1XFb4Egn4EH4C1y8o2/9PvWq5DMe3q3e5FHbqNq5vtYLgYLF9hVIh2ApLsAl1kZvWQl/AEPheRyHzJypkK+3w== +"@suttyweb/editor@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.4.tgz#ba755a84f4a406216b6acf0f7fa98f7f54ed42ce" + integrity sha512-opPgi1pGPNuXjDeiV2Pka618GVx3MeejUD8bh+l/DgKsQ5MifnbAg0eGcziECXhxQnNz68fZ2z9aiFzcr0LmUw== "@types/caseless@*": version "0.12.2" From b3a0ae3284b4743d3b8a14eedd73d061cd8dc548 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Oct 2022 19:13:47 -0300 Subject: [PATCH 020/814] @sutty/editor 0.1.5 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4b09f27d..48b4445d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.4", + "@suttyweb/editor": "^0.1.5", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 7cbb0855..30e725f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.4.tgz#ba755a84f4a406216b6acf0f7fa98f7f54ed42ce" - integrity sha512-opPgi1pGPNuXjDeiV2Pka618GVx3MeejUD8bh+l/DgKsQ5MifnbAg0eGcziECXhxQnNz68fZ2z9aiFzcr0LmUw== +"@suttyweb/editor@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.5.tgz#39beeb0fcf9b02719c66b54e12639d04ab571b6c" + integrity sha512-0OdqtdFz87/qdVObIuDqUEBPWHDUJj160RCcN/1vcehfvtyhWwH9uwcr5x3BU7fJ7OUBhJKKvT/01gvC0nbuRg== "@types/caseless@*": version "0.12.2" From 3fd2e1edfca414b38606d05a95204850a2a8fcca Mon Sep 17 00:00:00 2001 From: f Date: Fri, 4 Nov 2022 15:40:43 -0300 Subject: [PATCH 021/814] @sutty/editor 1.0.6 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 48b4445d..c3e625c7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.5", + "@suttyweb/editor": "^0.1.6", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 30e725f4..86064a59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.5.tgz#39beeb0fcf9b02719c66b54e12639d04ab571b6c" - integrity sha512-0OdqtdFz87/qdVObIuDqUEBPWHDUJj160RCcN/1vcehfvtyhWwH9uwcr5x3BU7fJ7OUBhJKKvT/01gvC0nbuRg== +"@suttyweb/editor@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.6.tgz#863359c35aae6be808860ef899d05fce52898876" + integrity sha512-W9N61/73z5j3pFasaBagHB92PBATG1e8Jy2OkDk4TmsGmXwI5EecYH/WwwzhzMeWm4Nndm/En7x/4f4Izf7JeQ== "@types/caseless@*": version "0.12.2" From f6ea00ed30822cb59bbf84574aff20f5cb2743d0 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 4 Nov 2022 16:47:55 -0300 Subject: [PATCH 022/814] feat: no sanitizar tablas sutty/editor#7 --- app/models/metadata_template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 97a631c1..6a86d45a 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -198,12 +198,12 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy class].freeze + name rel target referrerpolicy class colspan rowspan].freeze end def allowed_tags @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small].freeze + figcaption a sub sup small table thead tbody tfoot tr th td].freeze end # Decifra el valor From 395e5fa83ac47e2f405b2e42de3a9570e625b360 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 4 Nov 2022 16:49:37 -0300 Subject: [PATCH 023/814] feat: distinguir los elementos de una tabla sutty/editor#7 --- app/assets/stylesheets/new_editor.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/assets/stylesheets/new_editor.scss b/app/assets/stylesheets/new_editor.scss index e3f785b7..35c383f3 100644 --- a/app/assets/stylesheets/new_editor.scss +++ b/app/assets/stylesheets/new_editor.scss @@ -1,5 +1,10 @@ .new-editor { .editor { + table { + @extend .table; + @extend .table-responsive; + } + .menubar { z-index: 1; From ba39233739da91fd3892441b07a245011815e626 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 4 Nov 2022 16:58:56 -0300 Subject: [PATCH 024/814] fix: extender clases de bootstrap --- app/assets/stylesheets/application.scss | 9 +++++++++ app/assets/stylesheets/new_editor.scss | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 6c94c194..649c272d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -506,3 +506,12 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } @import "new_editor"; + +.new-editor { + .editor { + table { + @extend .table; + @extend .table-responsive; + } + } +} diff --git a/app/assets/stylesheets/new_editor.scss b/app/assets/stylesheets/new_editor.scss index 35c383f3..e3f785b7 100644 --- a/app/assets/stylesheets/new_editor.scss +++ b/app/assets/stylesheets/new_editor.scss @@ -1,10 +1,5 @@ .new-editor { .editor { - table { - @extend .table; - @extend .table-responsive; - } - .menubar { z-index: 1; From b42fa9f7364d99aeea4d98ef3300537292489002 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 8 Nov 2022 20:19:24 -0300 Subject: [PATCH 025/814] fix: permitir guardar br sutty/editor#61 --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 6a86d45a..709c87c3 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -203,7 +203,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_tags @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td].freeze + figcaption a sub sup small table thead tbody tfoot tr th td br].freeze end # Decifra el valor From fd855a1e93be4d39220cebdaf8a4612ffef2293a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 8 Nov 2022 20:19:53 -0300 Subject: [PATCH 026/814] fix: ajustes para el contenido #8395 --- app/assets/stylesheets/application.scss | 29 +++++++++++++++++++++++++ app/views/posts/show.haml | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 649c272d..818ebbd5 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -515,3 +515,32 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } + +.content { + p { min-height: $font-size-base * $line-height-base; } + h1 { min-height: $h1-font-size * $headings-line-height; } + h2 { min-height: $h2-font-size * $headings-line-height; } + h3 { min-height: $h3-font-size * $headings-line-height; } + h4 { min-height: $h4-font-size * $headings-line-height; } + h5 { min-height: $h5-font-size * $headings-line-height; } + h6 { min-height: $h6-font-size * $headings-line-height; } + + iframe { border: 0; } + + audio { width: 100%; } + + img, + video, + iframe { + @extend .img-fluid; + height: auto; + } + + & > * { + margin-bottom: 1rem; + + &:last-child { + margin-bottom: 0; + } + } +} diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index e46114af..da3dd16a 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -37,5 +37,5 @@ - next if metadata.front_matter? - cache [metadata, I18n.locale] do - %section.editor{ id: attr, dir: dir } + %section.content.pb-3{ id: attr, dir: dir } = @post.public_send(attr).value.html_safe From d8a20be0b6a9d7283242962ebca2db048b9ef512 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 9 Nov 2022 13:01:12 -0300 Subject: [PATCH 027/814] fix: dar el mismo estilo al editor nuevo --- app/views/posts/attributes/_new_content.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/attributes/_new_content.haml b/app/views/posts/attributes/_new_content.haml index 34fc4e60..520daff8 100644 --- a/app/views/posts/attributes/_new_content.haml +++ b/app/views/posts/attributes/_new_content.haml @@ -3,7 +3,7 @@ = render 'posts/attribute_feedback', post: post, attribute: attribute, metadata: metadata - .new-editor{ id: attribute } + .new-editor.content{ id: attribute } = text_area_tag "#{base}[#{attribute}]", metadata.value.html_safe, dir: dir, lang: locale, **field_options(attribute, metadata), class: 'd-none' From 48b65c5cb1b8dabced07afa860cf42694c9c620f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 28 Nov 2022 13:58:50 -0300 Subject: [PATCH 028/814] feat: campos enriquecidos con el nuevo editor --- app/models/metadata_new_html.rb | 4 ++++ app/views/posts/attribute_ro/_new_html.haml | 3 +++ app/views/posts/attributes/_new_html.haml | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100644 app/models/metadata_new_html.rb create mode 100644 app/views/posts/attribute_ro/_new_html.haml create mode 100644 app/views/posts/attributes/_new_html.haml diff --git a/app/models/metadata_new_html.rb b/app/models/metadata_new_html.rb new file mode 100644 index 00000000..546d0686 --- /dev/null +++ b/app/models/metadata_new_html.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +# Campos en HTML con el nuevo editor +class MetadataNewHtml < MetadataContent; end diff --git a/app/views/posts/attribute_ro/_new_html.haml b/app/views/posts/attribute_ro/_new_html.haml new file mode 100644 index 00000000..97931960 --- /dev/null +++ b/app/views/posts/attribute_ro/_new_html.haml @@ -0,0 +1,3 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ lang: locale, dir: dir }= metadata.value.html_safe diff --git a/app/views/posts/attributes/_new_html.haml b/app/views/posts/attributes/_new_html.haml new file mode 100644 index 00000000..629342b3 --- /dev/null +++ b/app/views/posts/attributes/_new_html.haml @@ -0,0 +1,6 @@ +-# Editor de contenido += render 'posts/attributes/new_content', + base: 'post', post: post, attribute: attribute, + metadata: metadata, site: site, + dir: dir, locale: locale, + autofocus: (post.attributes.first == attribute) From f3936681338ef882ab78bc9cb77edf07d6ca4bbf Mon Sep 17 00:00:00 2001 From: f Date: Mon, 28 Nov 2022 14:52:25 -0300 Subject: [PATCH 029/814] fixup! feat: campos enriquecidos con el nuevo editor --- app/models/metadata_new_html.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_new_html.rb b/app/models/metadata_new_html.rb index 546d0686..e6163499 100644 --- a/app/models/metadata_new_html.rb +++ b/app/models/metadata_new_html.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true # Campos en HTML con el nuevo editor -class MetadataNewHtml < MetadataContent; end +class MetadataNewHtml < MetadataHtml; end From d71309b30954141e9e60f31062d4c6bd76f57b01 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 12:38:18 -0300 Subject: [PATCH 030/814] feat: editor con notas al pie --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c3e625c7..3574d5dc 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.6", + "@suttyweb/editor": "^0.1.8", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 86064a59..b6fb26ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.6": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.6.tgz#863359c35aae6be808860ef899d05fce52898876" - integrity sha512-W9N61/73z5j3pFasaBagHB92PBATG1e8Jy2OkDk4TmsGmXwI5EecYH/WwwzhzMeWm4Nndm/En7x/4f4Izf7JeQ== +"@suttyweb/editor@^0.1.8": + version "0.1.8" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.8.tgz#7ad265ba14e5d4021766233d4e98873dd3999f0d" + integrity sha512-IpvBp7wAMnS6YYSQJzSVaSj24UFXM6vZKaCVVpI6GFN3YET/+4dIXvE/YZF5hphvnE8BLzMWDgVqNhPYOdCFdg== "@types/caseless@*": version "0.12.2" From c9bcf9258cc1dc1a95c7780b58d63931a6363568 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 12:56:01 -0300 Subject: [PATCH 031/814] fix: yarn --- yarn.lock | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 71b2093e..b6fb26ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2262,7 +2262,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -5034,11 +5034,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -moment@^2.10.2: - version "2.29.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" - integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== - move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" From e260582c262e21d8b978a91e9d4947cc582ac7d8 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 13:16:37 -0300 Subject: [PATCH 032/814] fix: import --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 3574d5dc..9668098e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.8", + "@suttyweb/editor": "^0.1.9", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index b6fb26ce..d9e8d59f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.8.tgz#7ad265ba14e5d4021766233d4e98873dd3999f0d" - integrity sha512-IpvBp7wAMnS6YYSQJzSVaSj24UFXM6vZKaCVVpI6GFN3YET/+4dIXvE/YZF5hphvnE8BLzMWDgVqNhPYOdCFdg== +"@suttyweb/editor@^0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.9.tgz#723ad00eb46aa94657c405d50e8849b0143a3ebc" + integrity sha512-aUOJnYyQ+g5fqNtjabuM3TvO7hAxKgbOJKLO44RQ/PtBidYu4/FS4gDHMb/HwenjKALpQD3PFnU+yb/IUdgNKQ== "@types/caseless@*": version "0.12.2" From 3bccc3ad3bdf257b54c9ca7d3b025fa5597f2da0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 15:32:11 -0300 Subject: [PATCH 033/814] fix: editor importable --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9668098e..78e839d9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.9", + "@suttyweb/editor": "^0.1.11", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index d9e8d59f..d9e93c5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.9": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.9.tgz#723ad00eb46aa94657c405d50e8849b0143a3ebc" - integrity sha512-aUOJnYyQ+g5fqNtjabuM3TvO7hAxKgbOJKLO44RQ/PtBidYu4/FS4gDHMb/HwenjKALpQD3PFnU+yb/IUdgNKQ== +"@suttyweb/editor@^0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.11.tgz#9f69fa0b66457a63419e744216d24e44d17a77a2" + integrity sha512-kYZYFf3aAhUdDoWuLZg5BsKXvwuttMmpM31dRg+SyeslUsZLetLGaeXqsWVeh8G13VS+t4s5OrncTOkAHlOlBw== "@types/caseless@*": version "0.12.2" From 33db365597a448408b1b6c1c9e3fe93481b84536 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 15:55:08 -0300 Subject: [PATCH 034/814] fix: scrollear las notas al pie al medio --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 78e839d9..42643ad4 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.11", + "@suttyweb/editor": "^0.1.12", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index d9e93c5f..5350bb6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.11": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.11.tgz#9f69fa0b66457a63419e744216d24e44d17a77a2" - integrity sha512-kYZYFf3aAhUdDoWuLZg5BsKXvwuttMmpM31dRg+SyeslUsZLetLGaeXqsWVeh8G13VS+t4s5OrncTOkAHlOlBw== +"@suttyweb/editor@^0.1.12": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.12.tgz#afcd2497d632b508f405fb484b3bb0a3ea1dd5f7" + integrity sha512-UjQcAuGJQpaOoN5U0cBYh0MLmSfakThVr2gkdInxx47/ApYlj5GoZ5BkbQ6lDSLeFzlyGOuiuj334VzKdxSB5A== "@types/caseless@*": version "0.12.2" From 4ce0eed173399e5524daf486d7ed9e5cca30ae83 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 15:55:36 -0300 Subject: [PATCH 035/814] fix: css del editor --- app/assets/stylesheets/new_editor.scss | 5 +++++ app/javascript/etc/new_editor.js | 2 ++ 2 files changed, 7 insertions(+) diff --git a/app/assets/stylesheets/new_editor.scss b/app/assets/stylesheets/new_editor.scss index e3f785b7..9acf4941 100644 --- a/app/assets/stylesheets/new_editor.scss +++ b/app/assets/stylesheets/new_editor.scss @@ -13,5 +13,10 @@ } } } + + .ProseMirror, + & > ol li { + @extend .mb-3; + } } } diff --git a/app/javascript/etc/new_editor.js b/app/javascript/etc/new_editor.js index d4b47ce8..0a7842ae 100644 --- a/app/javascript/etc/new_editor.js +++ b/app/javascript/etc/new_editor.js @@ -1,5 +1,7 @@ import SuttyEditor from "@suttyweb/editor"; +import "@suttyweb/editor/dist/editor.css"; + document.addEventListener("turbolinks:load", () => { document.querySelectorAll(".new-editor").forEach((editorContainer) => { new SuttyEditor({ From ba4fca13f4471f606f24978c7bf9803ab4196c40 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 16:39:34 -0300 Subject: [PATCH 036/814] fix: evitar error de scss --- app/assets/stylesheets/new_editor.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/new_editor.scss b/app/assets/stylesheets/new_editor.scss index 9acf4941..10e0dd48 100644 --- a/app/assets/stylesheets/new_editor.scss +++ b/app/assets/stylesheets/new_editor.scss @@ -16,7 +16,7 @@ .ProseMirror, & > ol li { - @extend .mb-3; + margin-bottom: 1rem; } } } From 7407e1c06dc115bce706e55292c07d8b9ce98275 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Dec 2022 16:39:45 -0300 Subject: [PATCH 037/814] fix: scrollear al centro vertical --- package.json | 2 +- yarn.lock | 2209 +++++++++++++++++++++++++------------------------- 2 files changed, 1108 insertions(+), 1103 deletions(-) diff --git a/package.json b/package.json index 42643ad4..ecbdf0ba 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.12", + "@suttyweb/editor": "^0.1.13", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 5350bb6c..7c634e9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,7 +4,7 @@ "@airbrake/browser@^1.4.1": version "1.4.2" - resolved "https://registry.yarnpkg.com/@airbrake/browser/-/browser-1.4.2.tgz#c7aa1b6b0db664011c71e733d364d03b393e9774" + resolved "https://registry.npmjs.org/@airbrake/browser/-/browser-1.4.2.tgz" integrity sha512-hlP+IMDcJXpoIaXTeKl8W+p18hKRJ9SKgLQTVh45GA9/qFXsLgu0V4tn0jDT5NQQXJG1+IKBv/RLRVgyswJy+w== dependencies: "@types/promise-polyfill" "^6.0.3" @@ -16,19 +16,19 @@ "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.8.3": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz" integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: "@babel/highlight" "^7.12.13" "@babel/compat-data@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.13.tgz#27e19e0ed3726ccf54067ced4109501765e7e2e8" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.13.tgz" integrity sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg== "@babel/core@^7.11.1": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.16.tgz#8c6ba456b23b680a6493ddcfcd9d3c3ad51cab7c" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.12.16.tgz" integrity sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw== dependencies: "@babel/code-frame" "^7.12.13" @@ -49,7 +49,7 @@ "@babel/core@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.17.tgz#993c5e893333107a2815d8e0d73a2c3755e280b2" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.12.17.tgz" integrity sha512-V3CuX1aBywbJvV2yzJScRxeiiw0v2KZZYYE3giywxzFJL13RiyPjaaDwhDnxmgFTTS7FgvM2ijr4QmKNIu0AtQ== dependencies: "@babel/code-frame" "^7.12.13" @@ -70,7 +70,7 @@ "@babel/generator@^7.12.13", "@babel/generator@^7.12.15": version "7.12.15" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.15.tgz#4617b5d0b25cc572474cc1aafee1edeaf9b5368f" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz" integrity sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ== dependencies: "@babel/types" "^7.12.13" @@ -79,7 +79,7 @@ "@babel/generator@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.17.tgz#9ef1dd792d778b32284411df63f4f668a9957287" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz" integrity sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg== dependencies: "@babel/types" "^7.12.17" @@ -88,14 +88,14 @@ "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz" integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== dependencies: "@babel/types" "^7.12.13" "@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz" integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== dependencies: "@babel/helper-explode-assignable-expression" "^7.12.13" @@ -103,7 +103,7 @@ "@babel/helper-compilation-targets@^7.12.16": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.16.tgz#6905238b4a5e02ba2d032c1a49dd1820fe8ce61b" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.16.tgz" integrity sha512-dBHNEEaZx7F3KoUYqagIhRIeqyyuI65xMndMZ3WwGwEBI609I4TleYQHcrS627vbKyNTXqShoN+fvYD9HuQxAg== dependencies: "@babel/compat-data" "^7.12.13" @@ -113,7 +113,7 @@ "@babel/helper-compilation-targets@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.17.tgz#91d83fae61ef390d39c3f0507cb83979bab837c7" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.17.tgz" integrity sha512-5EkibqLVYOuZ89BSg2lv+GG8feywLuvMXNYgf0Im4MssE0mFWPztSpJbildNnUgw0bLI2EsIN4MpSHC2iUJkQA== dependencies: "@babel/compat-data" "^7.12.13" @@ -123,7 +123,7 @@ "@babel/helper-create-class-features-plugin@^7.12.13": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz#955d5099fd093e5afb05542190f8022105082c61" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz" integrity sha512-KbSEj8l9zYkMVHpQqM3wJNxS1d9h3U9vm/uE5tpjMbaj3lTp+0noe3KPsV5dSD9jxKnf9jO9Ip9FX5PKNZCKow== dependencies: "@babel/helper-function-name" "^7.12.13" @@ -134,7 +134,7 @@ "@babel/helper-create-class-features-plugin@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.17.tgz#704b69c8a78d03fb1c5fcc2e7b593f8a65628944" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.17.tgz" integrity sha512-I/nurmTxIxHV0M+rIpfQBF1oN342+yvl2kwZUrQuOClMamHF1w5tknfZubgNOLRoA73SzBFAdFcpb4M9HwOeWQ== dependencies: "@babel/helper-function-name" "^7.12.13" @@ -145,7 +145,7 @@ "@babel/helper-create-regexp-features-plugin@^7.12.13": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.16.tgz#3b31d13f39f930fad975e151163b7df7d4ffe9d3" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.16.tgz" integrity sha512-jAcQ1biDYZBdaAxB4yg46/XirgX7jBDiMHDbwYQOgtViLBXGxJpZQ24jutmBqAIB/q+AwB6j+NbBXjKxEY8vqg== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" @@ -153,14 +153,14 @@ "@babel/helper-explode-assignable-expression@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz#0e46990da9e271502f77507efa4c9918d3d8634a" + resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz" integrity sha512-5loeRNvMo9mx1dA/d6yNi+YiKziJZFylZnCo1nmFF4qPU4yJ14abhWESuSMQSlQxWdxdOFzxXjk/PpfudTtYyw== dependencies: "@babel/types" "^7.12.13" "@babel/helper-function-name@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz" integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== dependencies: "@babel/helper-get-function-arity" "^7.12.13" @@ -169,42 +169,42 @@ "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz" integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== dependencies: "@babel/types" "^7.12.13" "@babel/helper-hoist-variables@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.12.13.tgz#13aba58b7480b502362316ea02f52cca0e9796cd" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.12.13.tgz" integrity sha512-KSC5XSj5HreRhYQtZ3cnSnQwDzgnbdUDEFsxkN0m6Q3WrCRt72xrnZ8+h+pX7YxM7hr87zIO3a/v5p/H3TrnVw== dependencies: "@babel/types" "^7.12.13" "@babel/helper-member-expression-to-functions@^7.12.13", "@babel/helper-member-expression-to-functions@^7.12.16": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz#41e0916b99f8d5f43da4f05d85f4930fa3d62b22" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz" integrity sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ== dependencies: "@babel/types" "^7.12.13" "@babel/helper-member-expression-to-functions@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz#f82838eb06e1235307b6d71457b6670ff71ee5ac" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz" integrity sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg== dependencies: "@babel/types" "^7.12.17" "@babel/helper-module-imports@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz" integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g== dependencies: "@babel/types" "^7.12.13" "@babel/helper-module-transforms@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz#01afb052dcad2044289b7b20beb3fa8bd0265bea" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz" integrity sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA== dependencies: "@babel/helper-module-imports" "^7.12.13" @@ -219,7 +219,7 @@ "@babel/helper-module-transforms@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.17.tgz#7c75b987d6dfd5b48e575648f81eaac891539509" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.17.tgz" integrity sha512-sFL+p6zOCQMm9vilo06M4VHuTxUAwa6IxgL56Tq1DVtA0ziAGTH1ThmJq7xwPqdQlgAbKX3fb0oZNbtRIyA5KQ== dependencies: "@babel/helper-module-imports" "^7.12.13" @@ -234,19 +234,19 @@ "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz" integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== dependencies: "@babel/types" "^7.12.13" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz#174254d0f2424d8aefb4dd48057511247b0a9eeb" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz" integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA== "@babel/helper-remap-async-to-generator@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz#170365f4140e2d20e5c88f8ba23c24468c296878" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz" integrity sha512-Qa6PU9vNcj1NZacZZI1Mvwt+gXDH6CTfgAkSjeRMLE8HxtDK76+YDId6NQR+z7Rgd5arhD2cIbS74r0SxD6PDA== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" @@ -255,7 +255,7 @@ "@babel/helper-replace-supers@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz" integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg== dependencies: "@babel/helper-member-expression-to-functions" "^7.12.13" @@ -265,43 +265,43 @@ "@babel/helper-simple-access@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz#8478bcc5cacf6aa1672b251c1d2dde5ccd61a6c4" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz" integrity sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA== dependencies: "@babel/types" "^7.12.13" "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz" integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== dependencies: "@babel/types" "^7.12.1" "@babel/helper-split-export-declaration@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz" integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== dependencies: "@babel/types" "^7.12.13" "@babel/helper-validator-identifier@^7.12.11": version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== "@babel/helper-validator-option@^7.12.16": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz#f73cbd3bbba51915216c5dea908e9b206bb10051" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz" integrity sha512-uCgsDBPUQDvzr11ePPo4TVEocxj8RXjUVSC/Y8N1YpVAI/XDdUwGJu78xmlGhTxj2ntaWM7n9LQdRtyhOzT2YQ== "@babel/helper-validator-option@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== "@babel/helper-wrap-function@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz#e3ea8cb3ee0a16911f9c1b50d9e99fe8fe30f9ff" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz" integrity sha512-t0aZFEmBJ1LojdtJnhOaQEVejnzYhyjWHSsNSNo8vOYRbAJNh6r6GQF7pd36SqG7OKGbn+AewVQ/0IfYfIuGdw== dependencies: "@babel/helper-function-name" "^7.12.13" @@ -311,7 +311,7 @@ "@babel/helpers@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.13.tgz#3c75e993632e4dadc0274eae219c73eb7645ba47" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.13.tgz" integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ== dependencies: "@babel/template" "^7.12.13" @@ -320,7 +320,7 @@ "@babel/helpers@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.17.tgz#71e03d2981a6b5ee16899964f4101dc8471d60bc" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.17.tgz" integrity sha512-tEpjqSBGt/SFEsFikKds1sLNChKKGGR17flIgQKXH4fG6m9gTgl3gnOC1giHNyaBCSKuTfxaSzHi7UnvqiVKxg== dependencies: "@babel/template" "^7.12.13" @@ -329,7 +329,7 @@ "@babel/highlight@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz" integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== dependencies: "@babel/helper-validator-identifier" "^7.12.11" @@ -338,17 +338,17 @@ "@babel/parser@^7.12.13", "@babel/parser@^7.12.16": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.16.tgz#cc31257419d2c3189d394081635703f549fc1ed4" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz" integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw== "@babel/parser@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.17.tgz#bc85d2d47db38094e5bb268fc761716e7d693848" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz" integrity sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg== "@babel/plugin-proposal-async-generator-functions@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz#d1c6d841802ffb88c64a2413e311f7345b9e66b5" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz" integrity sha512-1KH46Hx4WqP77f978+5Ye/VUbuwQld2hph70yaw2hXS2v7ER2f3nlpNMu909HO2rbvP0NKLlMVDPh9KXklVMhA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -357,7 +357,7 @@ "@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz#3d2ce350367058033c93c098e348161d6dc0d8c8" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz" integrity sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA== dependencies: "@babel/helper-create-class-features-plugin" "^7.12.13" @@ -365,7 +365,7 @@ "@babel/plugin-proposal-dynamic-import@^7.12.16": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.16.tgz#b9f33b252e3406d492a15a799c9d45a9a9613473" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.16.tgz" integrity sha512-yiDkYFapVxNOCcBfLnsb/qdsliroM+vc3LHiZwS4gh7pFjo5Xq3BDhYBNn3H3ao+hWPvqeeTdU+s+FIvokov+w== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -373,7 +373,7 @@ "@babel/plugin-proposal-dynamic-import@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.17.tgz#e0ebd8db65acc37eac518fa17bead2174e224512" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.17.tgz" integrity sha512-ZNGoFZqrnuy9H2izB2jLlnNDAfVPlGl5NhFEiFe4D84ix9GQGygF+CWMGHKuE+bpyS/AOuDQCnkiRNqW2IzS1Q== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -381,7 +381,7 @@ "@babel/plugin-proposal-export-namespace-from@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz" integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -389,7 +389,7 @@ "@babel/plugin-proposal-json-strings@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz#ced7888a2db92a3d520a2e35eb421fdb7fcc9b5d" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz" integrity sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -397,7 +397,7 @@ "@babel/plugin-proposal-logical-assignment-operators@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz#575b5d9a08d8299eeb4db6430da6e16e5cf14350" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz" integrity sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -405,7 +405,7 @@ "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.13.tgz#24867307285cee4e1031170efd8a7ac807deefde" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.13.tgz" integrity sha512-Qoxpy+OxhDBI5kRqliJFAl4uWXk3Bn24WeFstPH0iLymFehSAUR8MHpqU7njyXv/qbo7oN6yTy5bfCmXdKpo1Q== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -413,7 +413,7 @@ "@babel/plugin-proposal-numeric-separator@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz" integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -421,7 +421,7 @@ "@babel/plugin-proposal-object-rest-spread@^7.10.1", "@babel/plugin-proposal-object-rest-spread@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz#f93f3116381ff94bc676fdcb29d71045cd1ec011" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz" integrity sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -430,7 +430,7 @@ "@babel/plugin-proposal-optional-catch-binding@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz#4640520afe57728af14b4d1574ba844f263bcae5" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz" integrity sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -438,7 +438,7 @@ "@babel/plugin-proposal-optional-chaining@^7.12.16": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.16.tgz#600c7531f754186b0f2096e495a92da7d88aa139" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.16.tgz" integrity sha512-O3ohPwOhkwji5Mckb7F/PJpJVJY3DpPsrt/F0Bk40+QMk9QpAIqeGusHWqu/mYqsM8oBa6TziL/2mbERWsUZjg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -447,7 +447,7 @@ "@babel/plugin-proposal-optional-chaining@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.17.tgz#e382becadc2cb16b7913b6c672d92e4b33385b5c" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.17.tgz" integrity sha512-TvxwI80pWftrGPKHNfkvX/HnoeSTR7gC4ezWnAL39PuktYUe6r8kEpOLTYnkBTsaoeazXm2jHJ22EQ81sdgfcA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -456,7 +456,7 @@ "@babel/plugin-proposal-private-methods@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.13.tgz#ea78a12554d784ecf7fc55950b752d469d9c4a71" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.13.tgz" integrity sha512-sV0V57uUwpauixvR7s2o75LmwJI6JECwm5oPUY5beZB1nBl2i37hc7CJGqB5G+58fur5Y6ugvl3LRONk5x34rg== dependencies: "@babel/helper-create-class-features-plugin" "^7.12.13" @@ -464,7 +464,7 @@ "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz" integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" @@ -472,105 +472,105 @@ "@babel/plugin-syntax-async-generators@^7.8.0": version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== dependencies: "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-json-strings@^7.8.0": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.0": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.0": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.0": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-top-level-await@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz" integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-typescript@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz" integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-arrow-functions@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz#eda5670b282952100c229f8a3bd49e0f6a72e9fe" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz" integrity sha512-tBtuN6qtCTd+iHzVZVOMNp+L04iIJBpqkdY42tWbmjIT5wvR2kx7gxMBsyhQtFzHwBbyGi9h8J8r9HgnOpQHxg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-async-to-generator@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.13.tgz#fed8c69eebf187a535bfa4ee97a614009b24f7ae" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.13.tgz" integrity sha512-psM9QHcHaDr+HZpRuJcE1PXESuGWSCcbiGFFhhwfzdbTxaGDVzuVtdNYliAwcRo3GFg0Bc8MmI+AvIGYIJG04A== dependencies: "@babel/helper-module-imports" "^7.12.13" @@ -579,21 +579,21 @@ "@babel/plugin-transform-block-scoped-functions@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz" integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-block-scoping@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz" integrity sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-classes@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz#9728edc1838b5d62fc93ad830bd523b1fcb0e1f6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz" integrity sha512-cqZlMlhCC1rVnxE5ZGMtIb896ijL90xppMiuWXcwcOAuFczynpd3KYemb91XFFPi3wJSe/OcrX9lXoowatkkxA== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" @@ -606,21 +606,21 @@ "@babel/plugin-transform-computed-properties@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz#6a210647a3d67f21f699cfd2a01333803b27339d" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz" integrity sha512-dDfuROUPGK1mTtLKyDPUavmj2b6kFu82SmgpztBFEO974KMjJT+Ytj3/oWsTUMBmgPcp9J5Pc1SlcAYRpJ2hRA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-destructuring@^7.10.1", "@babel/plugin-transform-destructuring@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz#fc56c5176940c5b41735c677124d1d20cecc9aeb" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz" integrity sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz" integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" @@ -628,14 +628,14 @@ "@babel/plugin-transform-duplicate-keys@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz" integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-exponentiation-operator@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz" integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" @@ -643,14 +643,14 @@ "@babel/plugin-transform-for-of@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz#561ff6d74d9e1c8879cb12dbaf4a14cd29d15cf6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz" integrity sha512-xCbdgSzXYmHGyVX3+BsQjcd4hv4vA/FDy7Kc8eOpzKmBBPEOTurt0w5fCRQaGl+GSBORKgJdstQ1rHl4jbNseQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-function-name@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz" integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== dependencies: "@babel/helper-function-name" "^7.12.13" @@ -658,21 +658,21 @@ "@babel/plugin-transform-literals@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz" integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-member-expression-literals@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz" integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-modules-amd@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz#43db16249b274ee2e551e2422090aa1c47692d56" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz" integrity sha512-JHLOU0o81m5UqG0Ulz/fPC68/v+UTuGTWaZBUwpEk1fYQ1D9LfKV6MPn4ttJKqRo5Lm460fkzjLTL4EHvCprvA== dependencies: "@babel/helper-module-transforms" "^7.12.13" @@ -681,7 +681,7 @@ "@babel/plugin-transform-modules-commonjs@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz#5043b870a784a8421fa1fd9136a24f294da13e50" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz" integrity sha512-OGQoeVXVi1259HjuoDnsQMlMkT9UkZT9TpXAsqWplS/M0N1g3TJAn/ByOCeQu7mfjc5WpSsRU+jV1Hd89ts0kQ== dependencies: "@babel/helper-module-transforms" "^7.12.13" @@ -691,7 +691,7 @@ "@babel/plugin-transform-modules-systemjs@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz#351937f392c7f07493fc79b2118201d50404a3c5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz" integrity sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA== dependencies: "@babel/helper-hoist-variables" "^7.12.13" @@ -702,7 +702,7 @@ "@babel/plugin-transform-modules-umd@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz#26c66f161d3456674e344b4b1255de4d530cfb37" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz" integrity sha512-BgZndyABRML4z6ibpi7Z98m4EVLFI9tVsZDADC14AElFaNHHBcJIovflJ6wtCqFxwy2YJ1tJhGRsr0yLPKoN+w== dependencies: "@babel/helper-module-transforms" "^7.12.13" @@ -710,21 +710,21 @@ "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz" integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/plugin-transform-new-target@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz" integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-object-super@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz" integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -732,35 +732,35 @@ "@babel/plugin-transform-parameters@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz#461e76dfb63c2dfd327b8a008a9e802818ce9853" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz" integrity sha512-e7QqwZalNiBRHCpJg/P8s/VJeSRYgmtWySs1JwvfwPqhBbiWfOcHDKdeAi6oAyIimoKWBlwc8oTgbZHdhCoVZA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-property-literals@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz" integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-regenerator@^7.10.1", "@babel/plugin-transform-regenerator@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz#b628bcc9c85260ac1aeb05b45bde25210194a2f5" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz" integrity sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA== dependencies: regenerator-transform "^0.14.2" "@babel/plugin-transform-reserved-words@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz" integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-runtime@^7.11.0": version "7.12.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.15.tgz#4337b2507288007c2b197059301aa0af8d90c085" + resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.15.tgz" integrity sha512-OwptMSRnRWJo+tJ9v9wgAf72ydXWfYSXWhnQjZing8nGZSDFqU1MBleKM3+DriKkcbv7RagA8gVeB0A1PNlNow== dependencies: "@babel/helper-module-imports" "^7.12.13" @@ -769,7 +769,7 @@ "@babel/plugin-transform-runtime@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.17.tgz#329cb61d293b7e60a7685b91dda7c300668cee18" + resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.17.tgz" integrity sha512-s+kIJxnaTj+E9Q3XxQZ5jOo+xcogSe3V78/iFQ5RmoT0jROdpcdxhfGdq/VLqW1hFSzw6VjqN8aQqTaAMixWsw== dependencies: "@babel/helper-module-imports" "^7.12.13" @@ -778,14 +778,14 @@ "@babel/plugin-transform-shorthand-properties@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz" integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-spread@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz#ca0d5645abbd560719c354451b849f14df4a7949" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz" integrity sha512-dUCrqPIowjqk5pXsx1zPftSq4sT0aCeZVAxhdgs3AMgyaDmoUT0G+5h3Dzja27t76aUEIJWlFgPJqJ/d4dbTtg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -793,28 +793,28 @@ "@babel/plugin-transform-sticky-regex@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz" integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-template-literals@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz#655037b07ebbddaf3b7752f55d15c2fd6f5aa865" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz" integrity sha512-arIKlWYUgmNsF28EyfmiQHJLJFlAJNYkuQO10jL46ggjBpeb2re1P9K9YGxNJB45BqTbaslVysXDYm/g3sN/Qg== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-typeof-symbol@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz" integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-typescript@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.17.tgz#4aa6a5041888dd2e5d316ec39212b0cf855211bb" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.17.tgz" integrity sha512-1bIYwnhRoetxkFonuZRtDZPFEjl1l5r+3ITkxLC3mlMaFja+GQFo94b/WHEPjqWLU9Bc+W4oFZbvCGe9eYMu1g== dependencies: "@babel/helper-create-class-features-plugin" "^7.12.17" @@ -823,14 +823,14 @@ "@babel/plugin-transform-unicode-escapes@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz" integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-unicode-regex@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz" integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" @@ -838,7 +838,7 @@ "@babel/preset-env@^7.11.0": version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.16.tgz#16710e3490e37764b2f41886de0a33bc4ae91082" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.16.tgz" integrity sha512-BXCAXy8RE/TzX416pD2hsVdkWo0G+tYd16pwnRV4Sc0fRwTLRS/Ssv8G5RLXUGQv7g4FG7TXkdDJxCjQ5I+Zjg== dependencies: "@babel/compat-data" "^7.12.13" @@ -910,7 +910,7 @@ "@babel/preset-env@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.17.tgz#94a3793ff089c32ee74d76a3c03a7597693ebaaa" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.17.tgz" integrity sha512-9PMijx8zFbCwTHrd2P4PJR5nWGH3zWebx2OcpTjqQrHhCiL2ssSR2Sc9ko2BsI2VmVBfoaQmPrlMTCui4LmXQg== dependencies: "@babel/compat-data" "^7.12.13" @@ -982,7 +982,7 @@ "@babel/preset-modules@^0.1.3": version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz" integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -993,7 +993,7 @@ "@babel/preset-typescript@~7.12": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.17.tgz#8ecf04618956c268359dd9feab775dc14a666eb5" + resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.12.17.tgz" integrity sha512-T513uT4VSThRcmWeqcLkITKJ1oGQho9wfWuhQm10paClQkp1qyd0Wf8mvC8Se7UYssMyRSj4tZYpVTkCmAK/mA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -1002,14 +1002,14 @@ "@babel/runtime@^7.11.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.13.tgz" integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== dependencies: regenerator-runtime "^0.13.4" "@babel/template@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz" integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== dependencies: "@babel/code-frame" "^7.12.13" @@ -1018,7 +1018,7 @@ "@babel/traverse@^7.12.13": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz" integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA== dependencies: "@babel/code-frame" "^7.12.13" @@ -1033,7 +1033,7 @@ "@babel/traverse@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.17.tgz#40ec8c7ffb502c4e54c7f95492dc11b88d718619" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz" integrity sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ== dependencies: "@babel/code-frame" "^7.12.13" @@ -1048,7 +1048,7 @@ "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.4.4": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz" integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ== dependencies: "@babel/helper-validator-identifier" "^7.12.11" @@ -1057,7 +1057,7 @@ "@babel/types@^7.12.17": version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.17.tgz#9d711eb807e0934c90b8b1ca0eb1f7230d150963" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz" integrity sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ== dependencies: "@babel/helper-validator-identifier" "^7.12.11" @@ -1066,12 +1066,12 @@ "@csstools/convert-colors@^1.4.0": version "1.4.0" - resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + resolved "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz" integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== "@npmcli/move-file@^1.0.1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz" integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== dependencies: mkdirp "^1.0.4" @@ -1079,33 +1079,33 @@ "@rails/actiontext@^6.0.0": version "6.1.2" - resolved "https://registry.yarnpkg.com/@rails/actiontext/-/actiontext-6.1.2.tgz#a58b008c604a8b221bc1c41a7cc806a373625863" + resolved "https://registry.npmjs.org/@rails/actiontext/-/actiontext-6.1.2.tgz" integrity sha512-6CK7E0mpsARpy2khor6bNUhziI5qAwJeKh5P/sYL3vN1kJ4Ma6+WC+jvsZI+uQ8hecbpFTGR9fuhV9OHCnLe6Q== dependencies: "@rails/activestorage" "^6.0.0-alpha" "@rails/activestorage@^6.0.0-alpha": version "6.1.2" - resolved "https://registry.yarnpkg.com/@rails/activestorage/-/activestorage-6.1.2.tgz#e56c01314a85cacb53e5911ddc957578ac720c9c" + resolved "https://registry.npmjs.org/@rails/activestorage/-/activestorage-6.1.2.tgz" integrity sha512-7rwFGtUBDrwDAjXs2jl7MG20Z5Pd9+42RpH1N3xDF4PaqC9wfBzvPfT31hd5JTgXJH+/DtYepgrZK2e5Zps4Bg== dependencies: spark-md5 "^3.0.0" "@rails/activestorage@^6.1.3-1": version "6.1.3-1" - resolved "https://registry.yarnpkg.com/@rails/activestorage/-/activestorage-6.1.3-1.tgz#3304eaf597279c5943f793068b0147cb639239ed" + resolved "https://registry.npmjs.org/@rails/activestorage/-/activestorage-6.1.3-1.tgz" integrity sha512-BCrnyrRWIZX3eQieMHrmWuMCEZgwSifmSVFg46tGjdbDa6wjK3jitFDQ+gYXhyN3Cs4Hb+kAJb+0oMiprkzY0A== dependencies: spark-md5 "^3.0.0" "@rails/ujs@^6.1.3-1": version "6.1.3-1" - resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.1.3-1.tgz#c25ca8473a40298ecab7b0020214e77c0e6f5188" + resolved "https://registry.npmjs.org/@rails/ujs/-/ujs-6.1.3-1.tgz" integrity sha512-mygePdimLMOQ2nr9YclG1UIyKgaNfb2dMhsjhTs18j6DvlKR9VRz1j/Mbd2E7VL7HX7hlMBD1cltDrQsTZPjEw== "@rails/webpacker@5.2.1": version "5.2.1" - resolved "https://registry.yarnpkg.com/@rails/webpacker/-/webpacker-5.2.1.tgz#87cdbd4af2090ae2d74bdc51f6f04717d907c5b3" + resolved "https://registry.npmjs.org/@rails/webpacker/-/webpacker-5.2.1.tgz" integrity sha512-rO0kOv0o4ESB8ZnKX+b54ZKogNJGWSMULGmsJacREfm9SahKEQwXBeHNsqSGtS9NAPsU6YUFhGKRd4i/kbMNrQ== dependencies: "@babel/core" "^7.11.1" @@ -1149,41 +1149,41 @@ "@stimulus/core@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@stimulus/core/-/core-1.1.1.tgz#42b0cfe5b73ca492f41de64b77a03980bae92c82" + resolved "https://registry.npmjs.org/@stimulus/core/-/core-1.1.1.tgz" integrity sha512-PVJv7IpuQx0MVPCBblXc6O2zbCmU8dlxXNH4bC9KK6LsvGaE+PCXXrXQfXUwAsse1/CmRu/iQG7Ov58himjiGg== dependencies: "@stimulus/mutation-observers" "^1.1.1" "@stimulus/multimap@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@stimulus/multimap/-/multimap-1.1.1.tgz#b95e3fd607345ab36e5d5b55486ee1a12d56b331" + resolved "https://registry.npmjs.org/@stimulus/multimap/-/multimap-1.1.1.tgz" integrity sha512-26R1fI3a8uUj0WlMmta4qcfIQGlagegdP4PTz6lz852q/dXlG6r+uPS/bx+H8GtfyS+OOXVr3SkZ0Zg0iRqRfQ== "@stimulus/mutation-observers@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@stimulus/mutation-observers/-/mutation-observers-1.1.1.tgz#0f6c6f081308427fed2a26360dda0c173b79cfc0" + resolved "https://registry.npmjs.org/@stimulus/mutation-observers/-/mutation-observers-1.1.1.tgz" integrity sha512-/zCnnw1KJlWO2mrx0yxYaRFZWMGnDMdOgSnI4hxDLxdWVuL2HMROU8FpHWVBLjKY3T9A+lGkcrmPGDHF3pfS9w== dependencies: "@stimulus/multimap" "^1.1.1" "@stimulus/webpack-helpers@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2" + resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.12": - version "0.1.12" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.12.tgz#afcd2497d632b508f405fb484b3bb0a3ea1dd5f7" - integrity sha512-UjQcAuGJQpaOoN5U0cBYh0MLmSfakThVr2gkdInxx47/ApYlj5GoZ5BkbQ6lDSLeFzlyGOuiuj334VzKdxSB5A== +"@suttyweb/editor@^0.1.13": + version "0.1.13" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.13.tgz#376b87bb7ef92d459c63177fcc590aaf7f04c1c3" + integrity sha512-HBjz7Z/yCIoVrc73ZrmTmhZlJgM7c0mfPAHgL1R9PC0Y8uwaoyfaYKfpBLfes8GOLcUhax+K6CxQORqEq8cv7w== "@types/caseless@*": version "0.12.2" - resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" + resolved "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz" integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== "@types/glob@^7.1.1": version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz" integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== dependencies: "@types/minimatch" "*" @@ -1191,42 +1191,42 @@ "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== "@types/minimatch@*": version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": version "14.14.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.27.tgz#c7127f8da0498993e13b1a42faf1303d3110d2f2" + resolved "https://registry.npmjs.org/@types/node/-/node-14.14.27.tgz" integrity sha512-Ecfmo4YDQPwuqTCl1yBxLV5ihKfRlkBmzUEDcfIRvDxOTGQEeikr317Ln7Gcv0tjA8dVgKI3rniqW2G1OyKDng== "@types/parse-json@^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/promise-polyfill@^6.0.3": version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/promise-polyfill/-/promise-polyfill-6.0.3.tgz#e2f38fcd244a9e0df2cc7528e0711abcbc707b5e" + resolved "https://registry.npmjs.org/@types/promise-polyfill/-/promise-polyfill-6.0.3.tgz" integrity sha512-f/BFgF9a+cgsMseC7rpv9+9TAE3YNjhfYrtwCo/pIeCDDfQtE6PY0b5bao2eIIEpZCBUy8Y5ToXd4ObjPSJuFw== "@types/q@^1.5.1": version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" + resolved "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== "@types/rails__activestorage@^6.0.0": version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/rails__activestorage/-/rails__activestorage-6.0.0.tgz#e633f2a430993f754792dfdbe2b64fc1f2d33869" + resolved "https://registry.npmjs.org/@types/rails__activestorage/-/rails__activestorage-6.0.0.tgz" integrity sha512-Qk6dASfYYHym/95KQbPmUECuaveB5+sYEQdHDwKHvmwtrEbqjMH4t56MMCyzarweFDrA6ysULoCoa1f2nydwLg== "@types/request@2.48.5": version "2.48.5" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" + resolved "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz" integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== dependencies: "@types/caseless" "*" @@ -1236,12 +1236,12 @@ "@types/tough-cookie@*": version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" + resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz" integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== "@webassemblyjs/ast@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz" integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== dependencies: "@webassemblyjs/helper-module-context" "1.9.0" @@ -1250,46 +1250,46 @@ "@webassemblyjs/floating-point-hex-parser@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz" integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== "@webassemblyjs/helper-api-error@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz" integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== "@webassemblyjs/helper-buffer@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz" integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== "@webassemblyjs/helper-code-frame@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz" integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== dependencies: "@webassemblyjs/wast-printer" "1.9.0" "@webassemblyjs/helper-fsm@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz" integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== "@webassemblyjs/helper-module-context@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz" integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== dependencies: "@webassemblyjs/ast" "1.9.0" "@webassemblyjs/helper-wasm-bytecode@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz" integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== "@webassemblyjs/helper-wasm-section@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz" integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1299,26 +1299,26 @@ "@webassemblyjs/ieee754@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz" integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" "@webassemblyjs/leb128@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz" integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" "@webassemblyjs/utf8@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz" integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== "@webassemblyjs/wasm-edit@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz" integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1332,7 +1332,7 @@ "@webassemblyjs/wasm-gen@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz" integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1343,7 +1343,7 @@ "@webassemblyjs/wasm-opt@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz" integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1353,7 +1353,7 @@ "@webassemblyjs/wasm-parser@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz" integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1365,7 +1365,7 @@ "@webassemblyjs/wast-parser@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz" integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1377,7 +1377,7 @@ "@webassemblyjs/wast-printer@1.9.0": version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz" integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -1386,22 +1386,22 @@ "@xtuc/ieee754@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== "@xtuc/long@4.2.2": version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== abbrev@1: version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== dependencies: mime-types "~2.1.24" @@ -1409,12 +1409,12 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: acorn@^6.4.1: version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -1422,17 +1422,17 @@ aggregate-error@^3.0.0: ajv-errors@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + resolved "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -1442,61 +1442,61 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: alphanum-sort@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= amdefine@>=0.0.4: version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz" integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= ansi-colors@^3.0.0: version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== ansi-html@0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + resolved "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz" integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-regex@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== ansi-styles@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" anymatch@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz" integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" @@ -1504,7 +1504,7 @@ anymatch@^2.0.0: anymatch@~3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz" integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== dependencies: normalize-path "^3.0.0" @@ -1512,12 +1512,12 @@ anymatch@~3.1.1: aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz" integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" @@ -1525,61 +1525,61 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" arr-diff@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-find-index@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz" integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-flatten@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-flatten@^2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== array-union@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= dependencies: array-uniq "^1.0.1" array-uniq@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= asn1.js@^5.2.0: version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz" integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== dependencies: bn.js "^4.0.0" @@ -1589,19 +1589,19 @@ asn1.js@^5.2.0: asn1@~0.2.3: version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz" integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== dependencies: safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= assert@^1.1.1: version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: object-assign "^4.1.1" @@ -1609,49 +1609,49 @@ assert@^1.1.1: assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= async-each@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== async-foreach@^0.1.3: version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + resolved "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz" integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= async-limiter@~1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== async@^2.6.2: version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz" integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== dependencies: lodash "^4.17.14" asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= at-least-node@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== atob@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.6.1: version "9.8.6" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz" integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== dependencies: browserslist "^4.12.0" @@ -1664,17 +1664,17 @@ autoprefixer@^9.6.1: aws-sign2@~0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== babel-loader@^8.1.0, babel-loader@^8.2.2: version "8.2.2" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" + resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz" integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== dependencies: find-cache-dir "^3.3.1" @@ -1684,14 +1684,14 @@ babel-loader@^8.1.0, babel-loader@^8.2.2: babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + resolved "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz" integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" babel-plugin-macros@^2.8.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz" integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== dependencies: "@babel/runtime" "^7.7.2" @@ -1700,17 +1700,17 @@ babel-plugin-macros@^2.8.0: balanced-match@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base@^0.11.1: version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" @@ -1723,29 +1723,29 @@ base@^0.11.1: batch@0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= bcrypt-pbkdf@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= dependencies: tweetnacl "^0.14.3" big.js@^5.2.2: version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^1.0.0: version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bindings@^1.5.0: @@ -1757,34 +1757,34 @@ bindings@^1.5.0: bintrees@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.1.tgz#0e655c9b9c2435eaab68bf4027226d2b55a34524" + resolved "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz" integrity sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ= block-stream@*: version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + resolved "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz" integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= dependencies: inherits "~2.0.0" bluebird@^3.5.5: version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== bn.js@^5.0.0, bn.js@^5.1.1: version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== body-parser@1.19.0: version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz" integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== dependencies: bytes "3.1.0" @@ -1800,7 +1800,7 @@ body-parser@1.19.0: bonjour@^3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + resolved "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz" integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= dependencies: array-flatten "^2.1.0" @@ -1812,12 +1812,12 @@ bonjour@^3.5.0: boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -1825,7 +1825,7 @@ brace-expansion@^1.1.7: braces@^2.3.1, braces@^2.3.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" @@ -1841,19 +1841,19 @@ braces@^2.3.1, braces@^2.3.2: braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" @@ -1865,7 +1865,7 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: browserify-cipher@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz" integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" @@ -1874,7 +1874,7 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz" integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" @@ -1884,7 +1884,7 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: bn.js "^5.0.0" @@ -1892,7 +1892,7 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: browserify-sign@^4.0.0: version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz" integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== dependencies: bn.js "^5.1.1" @@ -1907,14 +1907,14 @@ browserify-sign@^4.0.0: browserify-zlib@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz" integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: pako "~1.0.5" browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1, browserslist@^4.6.4: version "4.16.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz" integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== dependencies: caniuse-lite "^1.0.30001181" @@ -1925,22 +1925,22 @@ browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4 buffer-from@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer-indexof@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + resolved "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz" integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== buffer-xor@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^4.3.0: version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz" integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" @@ -1949,22 +1949,22 @@ buffer@^4.3.0: builtin-status-codes@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= bytes@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= bytes@3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== cacache@^12.0.2: version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + resolved "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz" integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== dependencies: bluebird "^3.5.5" @@ -1985,7 +1985,7 @@ cacache@^12.0.2: cacache@^15.0.5: version "15.0.5" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" + resolved "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz" integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== dependencies: "@npmcli/move-file" "^1.0.1" @@ -2008,7 +2008,7 @@ cacache@^15.0.5: cache-base@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" @@ -2023,7 +2023,7 @@ cache-base@^1.0.1: call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" @@ -2031,31 +2031,31 @@ call-bind@^1.0.0, call-bind@^1.0.2: caller-callsite@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + resolved "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz" integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= dependencies: callsites "^2.0.0" caller-path@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + resolved "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz" integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= dependencies: caller-callsite "^2.0.0" callsites@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + resolved "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz" integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= dependencies: camelcase "^2.0.0" @@ -2063,17 +2063,17 @@ camelcase-keys@^2.0.0: camelcase@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-api@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz" integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== dependencies: browserslist "^4.0.0" @@ -2083,22 +2083,22 @@ caniuse-api@^3.0.0: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001181: version "1.0.30001187" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz#5706942631f83baa5a0218b7dfa6ced29f845438" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz" integrity sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA== case-sensitive-paths-webpack-plugin@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" + resolved "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz" integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== caseless@~0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= chalk@^1.1.1: version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" @@ -2109,7 +2109,7 @@ chalk@^1.1.1: chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -2118,7 +2118,7 @@ chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: chalk@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz" integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== dependencies: ansi-styles "^4.1.0" @@ -2126,17 +2126,17 @@ chalk@^4.1.0: chart.js@>=3.0.2, chart.js@^3.5.1: version "3.5.1" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.5.1.tgz#73e24d23a4134a70ccdb5e79a917f156b6f3644a" + resolved "https://registry.npmjs.org/chart.js/-/chart.js-3.5.1.tgz" integrity sha512-m5kzt72I1WQ9LILwQC4syla/LD/N413RYv2Dx2nnTkRS9iv/ey1xLTt0DnPc/eWV4zI+BgEgDYBIzbQhZHc/PQ== chartjs-adapter-date-fns@>=2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-2.0.0.tgz#5e53b2f660b993698f936f509c86dddf9ed44c6b" + resolved "https://registry.npmjs.org/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-2.0.0.tgz" integrity sha512-rmZINGLe+9IiiEB0kb57vH3UugAtYw33anRiw5kS2Tu87agpetDDoouquycWc9pRsKtQo5j+vLsYHyr8etAvFw== chartkick@^4.0.5: version "4.0.5" - resolved "https://registry.yarnpkg.com/chartkick/-/chartkick-4.0.5.tgz#310a60c931e8ceedc39adee2ef8e9d1e474cb0e6" + resolved "https://registry.npmjs.org/chartkick/-/chartkick-4.0.5.tgz" integrity sha512-xKak4Fsgfvp1hj/LykRKkniDMaZASx2A4TdVc/sfsiNFFNf1m+D7PGwP1vgj1UsbsCjOCSfGWWyJpOYxkUCBug== optionalDependencies: chart.js ">=3.0.2" @@ -2145,7 +2145,7 @@ chartkick@^4.0.5: chokidar@^2.1.8: version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" @@ -2164,7 +2164,7 @@ chokidar@^2.1.8: chokidar@^3.4.1, chokidar@^3.4.2: version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: anymatch "~3.1.1" @@ -2179,24 +2179,24 @@ chokidar@^3.4.1, chokidar@^3.4.2: chownr@^1.1.1: version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== chownr@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== chrome-trace-event@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz" integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== dependencies: tslib "^1.9.0" cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" @@ -2204,12 +2204,12 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: circular-dependency-plugin@^5.2.2: version "5.2.2" - resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600" + resolved "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz" integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ== class-utils@^0.3.5: version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" @@ -2219,12 +2219,12 @@ class-utils@^0.3.5: clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cliui@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz" integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== dependencies: string-width "^3.1.0" @@ -2233,7 +2233,7 @@ cliui@^5.0.0: clone-deep@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== dependencies: is-plain-object "^2.0.4" @@ -2242,7 +2242,7 @@ clone-deep@^4.0.1: coa@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + resolved "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz" integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== dependencies: "@types/q" "^1.5.1" @@ -2251,12 +2251,12 @@ coa@^2.0.2: code-point-at@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collection-visit@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" @@ -2264,31 +2264,31 @@ collection-visit@^1.0.0: color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== color-string@^1.5.4: version "1.5.4" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" + resolved "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz" integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== dependencies: color-name "^1.0.0" @@ -2296,7 +2296,7 @@ color-string@^1.5.4: color@^3.0.0: version "3.1.3" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + resolved "https://registry.npmjs.org/color/-/color-3.1.3.tgz" integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== dependencies: color-convert "^1.9.1" @@ -2304,29 +2304,29 @@ color@^3.0.0: colorette@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" commander@^2.20.0: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commondir@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= commonmark@^0.29.0: version "0.29.3" - resolved "https://registry.yarnpkg.com/commonmark/-/commonmark-0.29.3.tgz#bb1d5733bfe3ea213b412f33f16439cc12999c2c" + resolved "https://registry.npmjs.org/commonmark/-/commonmark-0.29.3.tgz" integrity sha512-fvt/NdOFKaL2gyhltSy6BC4LxbbxbnPxBMl923ittqO/JBM0wQHaoYZliE4tp26cRxX/ZZtRsJlZzQrVdUkXAA== dependencies: entities "~2.0" @@ -2336,19 +2336,19 @@ commonmark@^0.29.0: component-emitter@^1.2.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== compressible@~2.0.16: version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== dependencies: mime-db ">= 1.43.0 < 2" compression-webpack-plugin@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-4.0.1.tgz#33eda97f1170dd38c5556771de10f34245aa0274" + resolved "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-4.0.1.tgz" integrity sha512-0mg6PgwTsUe5LEcUrOu3ob32vraDx2VdbMGAT1PARcOV+UJWDYZFdkSo6RbHoGQ061mmmkC7XpRKOlvwm/gzJQ== dependencies: cacache "^15.0.5" @@ -2359,7 +2359,7 @@ compression-webpack-plugin@^4.0.0: compression@^1.7.4: version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== dependencies: accepts "~1.3.5" @@ -2372,12 +2372,12 @@ compression@^1.7.4: concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= concat-stream@^1.5.0: version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== dependencies: buffer-from "^1.0.0" @@ -2387,56 +2387,56 @@ concat-stream@^1.5.0: connect-history-api-fallback@^1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz" integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== console-browserify@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= constants-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= content-disposition@0.5.3: version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz" integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== dependencies: safe-buffer "5.1.2" content-type@~1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== copy-concurrently@^1.0.0: version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + resolved "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz" integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== dependencies: aproba "^1.1.1" @@ -2448,12 +2448,12 @@ copy-concurrently@^1.0.0: copy-descriptor@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.8.0: version "3.8.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.3.tgz#9123fb6b9cad30f0651332dc77deba48ef9b0b3f" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz" integrity sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog== dependencies: browserslist "^4.16.1" @@ -2461,17 +2461,17 @@ core-js-compat@^3.8.0: core-js@^3.6.5: version "3.8.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz" integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cosmiconfig@^5.0.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz" integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== dependencies: import-fresh "^2.0.0" @@ -2481,7 +2481,7 @@ cosmiconfig@^5.0.0: cosmiconfig@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== dependencies: "@types/parse-json" "^4.0.0" @@ -2492,7 +2492,7 @@ cosmiconfig@^6.0.0: create-ecdh@^4.0.0: version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz" integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" @@ -2500,7 +2500,7 @@ create-ecdh@^4.0.0: create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" @@ -2511,7 +2511,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" @@ -2523,19 +2523,19 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: crelt@^1.0.0: version "1.0.5" - resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.5.tgz#57c0d52af8c859e354bace1883eb2e1eb182bb94" + resolved "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz" integrity sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA== cross-fetch@^3.0.4: version "3.0.6" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" + resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz" integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== dependencies: node-fetch "2.6.1" cross-spawn@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz" integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= dependencies: lru-cache "^4.0.1" @@ -2543,7 +2543,7 @@ cross-spawn@^3.0.0: cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" @@ -2554,7 +2554,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: crypto-browserify@^3.11.0: version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz" integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" @@ -2571,19 +2571,19 @@ crypto-browserify@^3.11.0: css-blank-pseudo@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + resolved "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz" integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== dependencies: postcss "^7.0.5" css-color-names@0.0.4, css-color-names@^0.0.4: version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + resolved "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz" integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= css-declaration-sorter@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz" integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== dependencies: postcss "^7.0.1" @@ -2591,7 +2591,7 @@ css-declaration-sorter@^4.0.1: css-has-pseudo@^0.10.0: version "0.10.0" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + resolved "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz" integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== dependencies: postcss "^7.0.6" @@ -2599,7 +2599,7 @@ css-has-pseudo@^0.10.0: css-loader@^3.5.3: version "3.6.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + resolved "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz" integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== dependencies: camelcase "^5.3.1" @@ -2618,19 +2618,19 @@ css-loader@^3.5.3: css-prefers-color-scheme@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + resolved "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz" integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== dependencies: postcss "^7.0.5" css-select-base-adapter@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + resolved "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== css-select@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + resolved "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz" integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== dependencies: boolbase "^1.0.0" @@ -2640,7 +2640,7 @@ css-select@^2.0.0: css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz" integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== dependencies: mdn-data "2.0.4" @@ -2648,7 +2648,7 @@ css-tree@1.0.0-alpha.37: css-tree@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz" integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ== dependencies: mdn-data "2.0.14" @@ -2656,27 +2656,27 @@ css-tree@^1.1.2: css-what@^3.2.1: version "3.4.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + resolved "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== cssdb@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + resolved "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz" integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== cssesc@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz" integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== cssesc@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== cssnano-preset-default@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + resolved "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz" integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== dependencies: css-declaration-sorter "^4.0.1" @@ -2712,29 +2712,29 @@ cssnano-preset-default@^4.0.7: cssnano-util-get-arguments@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + resolved "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz" integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= cssnano-util-get-match@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + resolved "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz" integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= cssnano-util-raw-cache@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + resolved "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz" integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== dependencies: postcss "^7.0.0" cssnano-util-same-parent@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + resolved "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz" integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== cssnano@^4.1.10: version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + resolved "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz" integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== dependencies: cosmiconfig "^5.0.0" @@ -2744,69 +2744,69 @@ cssnano@^4.1.10: csso@^4.0.2: version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + resolved "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz" integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: css-tree "^1.1.2" currently-unhandled@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz" integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= dependencies: array-find-index "^1.0.1" cyclist@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= dashdash@^1.12.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= dependencies: assert-plus "^1.0.0" date-fns@>=2.0.0: version "2.24.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.24.0.tgz#7d86dc0d93c87b76b63d213b4413337cfd1c105d" + resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.24.0.tgz" integrity sha512-6ujwvwgPID6zbI0o7UbURi2vlLDR9uP26+tW6Lg+Ji3w7dd0i3DOcjcClLjLPranT60SSEFBwdSyYwn/ZkPIuw== debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.1.1, debug@^3.2.6: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.1.0, debug@^4.1.1: version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decode-uri-component@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= deep-equal@^1.0.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz" integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== dependencies: is-arguments "^1.0.4" @@ -2818,12 +2818,12 @@ deep-equal@^1.0.1: deepmerge@^4.2.2: version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== default-gateway@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz" integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== dependencies: execa "^1.0.0" @@ -2831,28 +2831,28 @@ default-gateway@^4.2.0: define-properties@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" @@ -2860,7 +2860,7 @@ define-property@^2.0.2: del@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + resolved "https://registry.npmjs.org/del/-/del-4.1.1.tgz" integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== dependencies: "@types/glob" "^7.1.1" @@ -2873,22 +2873,22 @@ del@^4.1.1: delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= delegates@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= depd@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz" integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" @@ -2896,22 +2896,22 @@ des.js@^1.0.0: destroy@~1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-file@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= detect-node@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz" integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== diffie-hellman@^5.0.0: version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz" integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" @@ -2920,12 +2920,12 @@ diffie-hellman@^5.0.0: dns-equal@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= dns-packet@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz" integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== dependencies: ip "^1.1.0" @@ -2933,14 +2933,14 @@ dns-packet@^1.3.1: dns-txt@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + resolved "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz" integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= dependencies: buffer-indexof "^1.0.0" dom-serializer@0: version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz" integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== dependencies: domelementtype "^2.0.1" @@ -2948,22 +2948,22 @@ dom-serializer@0: domain-browser@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== domelementtype@1: version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== domelementtype@^2.0.1: version "2.1.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz" integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== domutils@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz" integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== dependencies: dom-serializer "0" @@ -2971,14 +2971,14 @@ domutils@^1.7.0: dot-prop@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz" integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: is-obj "^2.0.0" duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz" integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== dependencies: end-of-stream "^1.0.0" @@ -2988,7 +2988,7 @@ duplexify@^3.4.2, duplexify@^3.6.0: ecc-jsbn@~0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= dependencies: jsbn "~0.1.0" @@ -2996,17 +2996,17 @@ ecc-jsbn@~0.1.1: ee-first@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.649: version "1.3.663" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.663.tgz#dd54adfd8d7f0e01b80d236c6e232efbaa0c686c" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.663.tgz" integrity sha512-xkVkzHj6k3oRRGlmdgUCCLSLhtFYHDCTH7SeK+LJdJjnsLcrdbpr8EYmfMQhez3V/KPO5UScSpzQ0feYX6Qoyw== elliptic@^6.5.3: version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== dependencies: bn.js "^4.11.9" @@ -3019,29 +3019,29 @@ elliptic@^6.5.3: emoji-regex@^7.0.1: version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== emojis-list@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== encodeurl@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enhanced-resolve@^4.1.1, enhanced-resolve@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz" integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" @@ -3050,38 +3050,38 @@ enhanced-resolve@^4.1.1, enhanced-resolve@^4.5.0: entities@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== entities@~2.0, entities@~2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + resolved "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz" integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== errno@^0.1.3, errno@~0.1.7: version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" error-stack-parser@^2.0.4: version "2.0.6" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + resolved "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz" integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== dependencies: stackframe "^1.1.1" es-abstract@^1.17.2: version "1.17.7" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz" integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== dependencies: es-to-primitive "^1.2.1" @@ -3098,7 +3098,7 @@ es-abstract@^1.17.2: es-abstract@^1.18.0-next.1: version "1.18.0-next.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz" integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== dependencies: call-bind "^1.0.2" @@ -3118,7 +3118,7 @@ es-abstract@^1.18.0-next.1: es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -3127,22 +3127,22 @@ es-to-primitive@^1.2.1: escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= eslint-scope@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== dependencies: esrecurse "^4.1.0" @@ -3150,56 +3150,56 @@ eslint-scope@^4.0.3: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esrecurse@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eventemitter3@^4.0.0: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" + resolved "https://registry.npmjs.org/events/-/events-3.2.0.tgz" integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== eventsource@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + resolved "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz" integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== dependencies: original "^1.0.0" evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" @@ -3207,7 +3207,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: execa@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz" integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: cross-spawn "^6.0.0" @@ -3220,7 +3220,7 @@ execa@^1.0.0: expand-brackets@^2.1.4: version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" @@ -3233,14 +3233,14 @@ expand-brackets@^2.1.4: expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz" integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= dependencies: homedir-polyfill "^1.0.1" express@^4.17.1: version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + resolved "https://registry.npmjs.org/express/-/express-4.17.1.tgz" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== dependencies: accepts "~1.3.7" @@ -3276,14 +3276,14 @@ express@^4.17.1: extend-shallow@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" @@ -3291,12 +3291,12 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: extend@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== extglob@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" @@ -3310,39 +3310,39 @@ extglob@^2.0.4: extsprintf@1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= extsprintf@^1.2.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= fast-deep-equal@^3.1.1: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== faye-websocket@^0.11.3: version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz" integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== dependencies: websocket-driver ">=0.5.1" figgy-pudding@^3.5.1: version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== file-loader@^6.0.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: loader-utils "^2.0.0" @@ -3355,7 +3355,7 @@ file-uri-to-path@1.0.0: fill-range@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" @@ -3365,14 +3365,14 @@ fill-range@^4.0.0: fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" finalhandler@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== dependencies: debug "2.6.9" @@ -3385,7 +3385,7 @@ finalhandler@~1.1.2: find-cache-dir@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== dependencies: commondir "^1.0.1" @@ -3394,7 +3394,7 @@ find-cache-dir@^2.1.0: find-cache-dir@^3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== dependencies: commondir "^1.0.1" @@ -3403,7 +3403,7 @@ find-cache-dir@^3.3.1: find-up@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz" integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= dependencies: path-exists "^2.0.0" @@ -3411,14 +3411,14 @@ find-up@^1.0.0: find-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: locate-path "^3.0.0" find-up@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -3426,7 +3426,7 @@ find-up@^4.0.0: findup-sync@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz" integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== dependencies: detect-file "^1.0.0" @@ -3436,17 +3436,17 @@ findup-sync@^3.0.0: flatted@^3.0.4: version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== flatten@^1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + resolved "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== flush-write-stream@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz" integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== dependencies: inherits "^2.0.3" @@ -3454,27 +3454,27 @@ flush-write-stream@^1.0.0: follow-redirects@^1.0.0: version "1.13.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz" integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA== for-in@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= forever-agent@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= fork-awesome@^1.1.7: version "1.1.7" - resolved "https://registry.yarnpkg.com/fork-awesome/-/fork-awesome-1.1.7.tgz#1427da1cac3d1713046ee88427e5fcecb9501d21" + resolved "https://registry.npmjs.org/fork-awesome/-/fork-awesome-1.1.7.tgz" integrity sha512-IHI7XCSXrKfUIWslse8c/PaaVDT1oBaYge+ju40ihL2ooiQeBpTr4wvIXhgTd2NuhntlvX+M5jYHAPTzNlmv0g== fork-ts-checker-webpack-plugin@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.1.0.tgz#7581a6ccd7cbbed9ecce3de64fb1f599d7a2990b" + resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.1.0.tgz" integrity sha512-xLNufWQ1dfQUdZe48TGQlER/0OkcMnUB6lfbN9Tt13wsYyo+2DwcCbnOaPBo1PoFow/WL8pJPktGIdbJaHxAnw== dependencies: "@babel/code-frame" "^7.8.3" @@ -3492,7 +3492,7 @@ fork-ts-checker-webpack-plugin@^6.1.0: form-data@^2.5.0: version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== dependencies: asynckit "^0.4.0" @@ -3501,7 +3501,7 @@ form-data@^2.5.0: form-data@~2.3.2: version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== dependencies: asynckit "^0.4.0" @@ -3510,24 +3510,24 @@ form-data@~2.3.2: forwarded@~0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= from2@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + resolved "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz" integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= dependencies: inherits "^2.0.1" @@ -3535,7 +3535,7 @@ from2@^2.1.0: fs-extra@^9.0.0: version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" @@ -3545,19 +3545,19 @@ fs-extra@^9.0.0: fs-minipass@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== dependencies: minipass "^3.0.0" fs-monkey@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.1.tgz#4a82f36944365e619f4454d9fff106553067b781" + resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.1.tgz" integrity sha512-fcSa+wyTqZa46iWweI7/ZiUfegOZl0SG8+dltIwFXo7+zYU9J9kpS3NB6pZcSlJdhvIwp81Adx2XhZorncxiaA== fs-write-stream-atomic@^1.0.8: version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + resolved "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz" integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= dependencies: graceful-fs "^4.1.2" @@ -3567,7 +3567,7 @@ fs-write-stream-atomic@^1.0.8: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: @@ -3585,7 +3585,7 @@ fsevents@~2.3.1: fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz" integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" @@ -3595,12 +3595,12 @@ fstream@^1.0.0, fstream@^1.0.12: function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== gauge@~2.7.3: version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" @@ -3614,24 +3614,24 @@ gauge@~2.7.3: gaze@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + resolved "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz" integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== dependencies: globule "^1.0.0" gensync@^1.0.0-beta.1: version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.1: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-intrinsic@^1.0.2: version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" @@ -3640,31 +3640,31 @@ get-intrinsic@^1.0.2: get-stdin@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= get-stream@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= getpass@^0.1.1: version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= dependencies: assert-plus "^1.0.0" glob-parent@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: is-glob "^3.1.0" @@ -3672,14 +3672,14 @@ glob-parent@^3.1.0: glob-parent@~5.1.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz" integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== dependencies: is-glob "^4.0.1" glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.1.1: version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" @@ -3691,7 +3691,7 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, gl global-modules@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz" integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== dependencies: global-prefix "^1.0.1" @@ -3700,14 +3700,14 @@ global-modules@^1.0.0: global-modules@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz" integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== dependencies: global-prefix "^3.0.0" global-prefix@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz" integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= dependencies: expand-tilde "^2.0.2" @@ -3718,7 +3718,7 @@ global-prefix@^1.0.1: global-prefix@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz" integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== dependencies: ini "^1.3.5" @@ -3727,12 +3727,12 @@ global-prefix@^3.0.0: globals@^11.1.0: version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globby@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + resolved "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz" integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= dependencies: array-union "^1.0.1" @@ -3743,7 +3743,7 @@ globby@^6.1.0: globule@^1.0.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4" + resolved "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz" integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== dependencies: glob "~7.1.1" @@ -3752,22 +3752,22 @@ globule@^1.0.0: graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== handle-thing@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== har-schema@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~5.1.3: version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: ajv "^6.12.3" @@ -3775,34 +3775,34 @@ har-validator@~5.1.3: has-ansi@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-symbols@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== has-unicode@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" @@ -3811,7 +3811,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" @@ -3820,12 +3820,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" @@ -3833,14 +3833,14 @@ has-values@^1.0.0: has@^1.0.0, has@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hash-base@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz" integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: inherits "^2.0.4" @@ -3849,7 +3849,7 @@ hash-base@^3.0.0: hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" @@ -3857,12 +3857,12 @@ hash.js@^1.0.0, hash.js@^1.0.3: hex-color-regex@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" @@ -3871,19 +3871,19 @@ hmac-drbg@^1.0.1: homedir-polyfill@^1.0.1: version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz" integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== dependencies: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== hpack.js@^2.1.6: version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= dependencies: inherits "^2.0.1" @@ -3893,32 +3893,32 @@ hpack.js@^2.1.6: hsl-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + resolved "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz" integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= hsla-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + resolved "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= html-comment-regex@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + resolved "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz" integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== html-entities@^1.3.1: version "1.4.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + resolved "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz" integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== http-deceiver@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= http-errors@1.7.2: version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz" integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== dependencies: depd "~1.1.2" @@ -3929,7 +3929,7 @@ http-errors@1.7.2: http-errors@~1.6.2: version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= dependencies: depd "~1.1.2" @@ -3939,7 +3939,7 @@ http-errors@~1.6.2: http-errors@~1.7.2: version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== dependencies: depd "~1.1.2" @@ -3950,12 +3950,12 @@ http-errors@~1.7.2: http-parser-js@>=0.5.1: version "0.5.3" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== http-proxy-middleware@0.19.1: version "0.19.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz" integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== dependencies: http-proxy "^1.17.0" @@ -3965,7 +3965,7 @@ http-proxy-middleware@0.19.1: http-proxy@^1.17.0: version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== dependencies: eventemitter3 "^4.0.0" @@ -3974,7 +3974,7 @@ http-proxy@^1.17.0: http-signature@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= dependencies: assert-plus "^1.0.0" @@ -3983,43 +3983,43 @@ http-signature@~1.2.0: https-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= iconv-lite@0.4.24: version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" icss-utils@^4.0.0, icss-utils@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz" integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== dependencies: postcss "^7.0.14" ieee754@^1.1.4: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + resolved "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= import-cwd@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + resolved "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz" integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= dependencies: import-from "^2.1.0" import-fresh@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz" integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= dependencies: caller-path "^2.0.0" @@ -4027,7 +4027,7 @@ import-fresh@^2.0.0: import-fresh@^3.1.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -4035,14 +4035,14 @@ import-fresh@^3.1.0: import-from@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + resolved "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz" integrity sha1-M1238qev/VOqpHHUuAId7ja387E= dependencies: resolve-from "^3.0.0" import-local@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + resolved "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz" integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== dependencies: pkg-dir "^3.0.0" @@ -4050,39 +4050,39 @@ import-local@^2.0.0: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= in-publish@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + resolved "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz" integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== indent-string@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz" integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= dependencies: repeating "^2.0.0" indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== indexes-of@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + resolved "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" @@ -4090,22 +4090,22 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inherits@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= inherits@2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@^1.3.5: version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== "input-map@git+https://0xacab.org/sutty/input-map.git": @@ -4118,7 +4118,7 @@ ini@^1.3.4, ini@^1.3.5: internal-ip@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + resolved "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz" integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== dependencies: default-gateway "^4.2.0" @@ -4126,92 +4126,92 @@ internal-ip@^4.3.0: interpret@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== ip-regex@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= ip@^1.1.0, ip@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= ipaddr.js@1.9.1, ipaddr.js@^1.9.0: version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-absolute-url@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= is-absolute-url@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz" integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== is-accessor-descriptor@^0.1.6: version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arguments@^1.0.4: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz" integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== dependencies: call-bind "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-arrayish@^0.3.1: version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== is-binary-path@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-buffer@^1.1.5: version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-callable@^1.1.4, is-callable@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-color-stop@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + resolved "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz" integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= dependencies: css-color-names "^0.0.4" @@ -4223,33 +4223,33 @@ is-color-stop@^1.0.0: is-core-module@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz" integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== dependencies: has "^1.0.3" is-data-descriptor@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== is-descriptor@^0.1.0: version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" @@ -4258,7 +4258,7 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" @@ -4267,113 +4267,113 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-directory@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== is-fullwidth-code-point@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-glob@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz" integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: is-extglob "^2.1.0" is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" is-negative-zero@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-path-cwd@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz" integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== is-path-in-cwd@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + resolved "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz" integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== dependencies: is-path-inside "^2.1.0" is-path-inside@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz" integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== dependencies: path-is-inside "^1.0.2" is-plain-obj@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-regex@^1.0.4, is-regex@^1.1.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz" integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== dependencies: call-bind "^1.0.2" @@ -4381,78 +4381,78 @@ is-regex@^1.0.4, is-regex@^1.1.1: is-resolvable@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== is-stream@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-svg@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + resolved "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz" integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== dependencies: html-comment-regex "^1.1.0" is-symbol@^1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz" integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== dependencies: has-symbols "^1.0.1" is-typedarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-utf8@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== is-wsl@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= isstream@~0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= jest-worker@^26.5.0: version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== dependencies: "@types/node" "*" @@ -4461,17 +4461,17 @@ jest-worker@^26.5.0: js-base64@^2.1.8: version "2.6.4" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" + resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz" integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1, js-yaml@^3.14.0: version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -4479,66 +4479,66 @@ js-yaml@^3.13.1, js-yaml@^3.14.0: jsbn@~0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsesc@^2.5.1: version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== jsesc@~0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= json-stringify-safe@~5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json3@^3.3.3: version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + resolved "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== json5@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: minimist "^1.2.0" json5@^2.1.2: version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz" integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" jsonfile@^6.0.1: version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: universalify "^2.0.0" @@ -4547,7 +4547,7 @@ jsonfile@^6.0.1: jsprim@^1.2.2: version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz" integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= dependencies: assert-plus "1.0.0" @@ -4557,36 +4557,36 @@ jsprim@^1.2.2: killable@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + resolved "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz" integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== last-call-webpack-plugin@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + resolved "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz" integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== dependencies: lodash "^4.17.5" @@ -4594,24 +4594,24 @@ last-call-webpack-plugin@^3.0.0: leaflet@^1.7.1: version "1.7.1" - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" + resolved "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz" integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== lines-and-columns@^1.1.6: version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= linkify-it@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz" integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== dependencies: uc.micro "^1.0.1" load-json-file@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= dependencies: graceful-fs "^4.1.2" @@ -4622,12 +4622,12 @@ load-json-file@^1.0.0: loader-runner@^2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== dependencies: big.js "^5.2.2" @@ -4636,7 +4636,7 @@ loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: loader-utils@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz" integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== dependencies: big.js "^5.2.2" @@ -4645,7 +4645,7 @@ loader-utils@^2.0.0: locate-path@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: p-locate "^3.0.0" @@ -4653,34 +4653,34 @@ locate-path@^3.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" lodash._reinterpolate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= lodash.get@^4.0: version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= lodash.has@^4.0: version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" + resolved "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz" integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI= lodash.memoize@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= lodash.template@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz" integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== dependencies: lodash._reinterpolate "^3.0.0" @@ -4688,34 +4688,34 @@ lodash.template@^4.5.0: lodash.templatesettings@^4.0.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz" integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== dependencies: lodash._reinterpolate "^3.0.0" lodash.uniq@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= lodash@^4.0.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.5, lodash@~4.17.10: version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== lodash@^4.17.11, lodash@^4.17.14: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loglevel@^1.6.8: version "1.7.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== loud-rejection@^1.0.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz" integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= dependencies: currently-unhandled "^0.4.1" @@ -4723,7 +4723,7 @@ loud-rejection@^1.0.0: lru-cache@^4.0.1: version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz" integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== dependencies: pseudomap "^1.0.2" @@ -4731,21 +4731,21 @@ lru-cache@^4.0.1: lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" make-dir@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== dependencies: pify "^4.0.1" @@ -4753,31 +4753,31 @@ make-dir@^2.0.0: make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" map-cache@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= map-visit@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" markdown-it@^10.0.0: version "10.0.0" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" + resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz" integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== dependencies: argparse "^1.0.7" @@ -4788,7 +4788,7 @@ markdown-it@^10.0.0: md5.js@^1.3.4: version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz" integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" @@ -4797,34 +4797,34 @@ md5.js@^1.3.4: mdn-data@2.0.14: version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== mdn-data@2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== mdurl@^1.0.1, mdurl@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= media-typer@0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= memfs@^3.1.2: version "3.2.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.2.0.tgz#f9438e622b5acd1daa8a4ae160c496fdd1325b26" + resolved "https://registry.npmjs.org/memfs/-/memfs-3.2.0.tgz" integrity sha512-f/xxz2TpdKv6uDn6GtHee8ivFyxwxmPuXatBb1FBwxYNuVpbM3k/Y1Z+vC0mH/dIXXrukYfe3qe5J32Dfjg93A== dependencies: fs-monkey "1.0.1" memory-fs@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= dependencies: errno "^0.1.3" @@ -4832,7 +4832,7 @@ memory-fs@^0.4.1: memory-fs@^0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz" integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== dependencies: errno "^0.1.3" @@ -4840,7 +4840,7 @@ memory-fs@^0.5.0: meow@^3.7.0: version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz" integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= dependencies: camelcase-keys "^2.0.0" @@ -4856,22 +4856,22 @@ meow@^3.7.0: merge-descriptors@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== methods@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" @@ -4890,7 +4890,7 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: miller-rabin@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz" integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" @@ -4898,41 +4898,41 @@ miller-rabin@^4.0.0: mime-db@1.45.0: version "1.45.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz" integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== mime-db@1.46.0, "mime-db@>= 1.43.0 < 2": version "1.46.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz" integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== mime-types@^2.1.12, mime-types@~2.1.19: version "2.1.28" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz" integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== dependencies: mime-db "1.45.0" mime-types@~2.1.17, mime-types@~2.1.24: version "2.1.29" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz" integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== dependencies: mime-db "1.46.0" mime@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.4: version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== mini-css-extract-plugin@^0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz" integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A== dependencies: loader-utils "^1.1.0" @@ -4942,57 +4942,57 @@ mini-css-extract-plugin@^0.9.0: minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@>=1.2.2, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== minipass-collect@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== dependencies: minipass "^3.0.0" minipass-flush@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== dependencies: minipass "^3.0.0" minipass-pipeline@^1.2.2: version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" minipass@^3.0.0, minipass@^3.1.1: version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz" integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== dependencies: yallist "^4.0.0" minizlib@^2.1.1: version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== dependencies: minipass "^3.0.0" @@ -5000,7 +5000,7 @@ minizlib@^2.1.1: mississippi@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + resolved "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz" integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== dependencies: concat-stream "^1.5.0" @@ -5016,7 +5016,7 @@ mississippi@^3.0.0: mixin-deep@^1.2.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" @@ -5024,19 +5024,19 @@ mixin-deep@^1.2.0: "mkdirp@>=0.5 0", mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== move-concurrently@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz" integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= dependencies: aproba "^1.1.1" @@ -5048,45 +5048,50 @@ move-concurrently@^1.0.1: ms@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== ms@^2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== multicast-dns-service-types@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + resolved "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz" integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= multicast-dns@^6.0.1: version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz" integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== dependencies: dns-packet "^1.3.1" thunky "^1.0.2" -nan@^2.12.1, nan@^2.13.2: +nan@^2.12.1: + version "2.17.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== + +nan@^2.13.2: version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + resolved "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== nanomatch@^1.2.9: version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" @@ -5103,32 +5108,32 @@ nanomatch@^1.2.9: negotiator@0.6.2: version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== neo-async@^2.5.0, neo-async@^2.6.1: version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== nice-try@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== node-fetch@2.6.1: version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== node-forge@^0.10.0: version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-gyp@^3.8.0: version "3.8.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz" integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== dependencies: fstream "^1.0.0" @@ -5146,7 +5151,7 @@ node-gyp@^3.8.0: node-libs-browser@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz" integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== dependencies: assert "^1.1.1" @@ -5175,12 +5180,12 @@ node-libs-browser@^2.2.1: node-releases@^1.1.70: version "1.1.70" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz" integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== node-sass@^4.14.1: version "4.14.1" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5" + resolved "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz" integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== dependencies: async-foreach "^0.1.3" @@ -5203,14 +5208,14 @@ node-sass@^4.14.1: "nopt@2 || 3": version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= dependencies: abbrev "1" normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -5220,24 +5225,24 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: normalize-path@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-range@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= normalize-url@1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz" integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= dependencies: object-assign "^4.0.1" @@ -5247,19 +5252,19 @@ normalize-url@1.9.1: normalize-url@^3.0.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== npm-run-path@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" "npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" @@ -5269,34 +5274,34 @@ npm-run-path@^2.0.0: nth-check@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz" integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== dependencies: boolbase "~1.0.0" num2fraction@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + resolved "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= number-is-nan@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= oauth-sign@~0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" @@ -5305,12 +5310,12 @@ object-copy@^0.1.0: object-inspect@^1.8.0, object-inspect@^1.9.0: version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== object-is@^1.0.1: version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== dependencies: call-bind "^1.0.2" @@ -5318,19 +5323,19 @@ object-is@^1.0.1: object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object-visit@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: call-bind "^1.0.0" @@ -5340,7 +5345,7 @@ object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: object.getownpropertydescriptors@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544" + resolved "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz" integrity sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng== dependencies: call-bind "^1.0.0" @@ -5349,14 +5354,14 @@ object.getownpropertydescriptors@^2.1.0: object.pick@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" object.values@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.2.tgz#7a2015e06fcb0f546bd652486ce8583a4731c731" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz" integrity sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag== dependencies: call-bind "^1.0.0" @@ -5366,38 +5371,38 @@ object.values@^1.1.0: obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== on-finished@~2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" on-headers@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" opn@^5.5.0: version "5.5.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + resolved "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz" integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== dependencies: is-wsl "^1.1.0" optimize-css-assets-webpack-plugin@^5.0.3: version "5.0.4" - resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" + resolved "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz" integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A== dependencies: cssnano "^4.1.10" @@ -5405,34 +5410,34 @@ optimize-css-assets-webpack-plugin@^5.0.3: orderedmap@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.1.tgz#c618e77611b3b21d0fe3edc92586265e0059c789" + resolved "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz" integrity sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ== original@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + resolved "https://registry.npmjs.org/original/-/original-1.0.2.tgz" integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== dependencies: url-parse "^1.4.3" os-browserify@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= os-homedir@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-tmpdir@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@0: version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" @@ -5440,69 +5445,69 @@ osenv@0: p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: p-limit "^2.0.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-map@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + resolved "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== p-map@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-retry@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + resolved "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz" integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== dependencies: retry "^0.12.0" p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parallel-transform@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + resolved "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz" integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== dependencies: cyclist "^1.0.1" @@ -5511,14 +5516,14 @@ parallel-transform@^1.1.0: parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== dependencies: asn1.js "^5.2.0" @@ -5529,14 +5534,14 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: parse-json@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz" integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= dependencies: error-ex "^1.2.0" parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= dependencies: error-ex "^1.3.1" @@ -5544,7 +5549,7 @@ parse-json@^4.0.0: parse-json@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -5554,79 +5559,79 @@ parse-json@^5.0.0: parse-passwd@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= path-browserify@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz" integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== path-complete-extname@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/path-complete-extname/-/path-complete-extname-1.0.0.tgz#f889985dc91000c815515c0bfed06c5acda0752b" + resolved "https://registry.npmjs.org/path-complete-extname/-/path-complete-extname-1.0.0.tgz" integrity sha512-CVjiWcMRdGU8ubs08YQVzhutOR5DEfO97ipRIlOGMK5Bek5nQySknBpuxVAVJ36hseTNs+vdIcv57ZrWxH7zvg== path-dirname@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= path-exists@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@0.1.7: version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= path-type@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz" integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= dependencies: graceful-fs "^4.1.2" @@ -5635,12 +5640,12 @@ path-type@^1.0.0: path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz" integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== dependencies: create-hash "^1.1.2" @@ -5651,60 +5656,60 @@ pbkdf2@^3.0.3: performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== pify@^2.0.0, pify@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pinkie-promise@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pkg-dir@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz" integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== dependencies: find-up "^3.0.0" pkg-dir@^4.1.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" pnp-webpack-plugin@^1.6.4: version "1.6.4" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz" integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== dependencies: ts-pnp "^1.1.6" portfinder@^1.0.26: version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz" integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== dependencies: async "^2.6.2" @@ -5713,12 +5718,12 @@ portfinder@^1.0.26: posix-character-classes@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postcss-attribute-case-insensitive@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz" integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== dependencies: postcss "^7.0.2" @@ -5726,7 +5731,7 @@ postcss-attribute-case-insensitive@^4.0.1: postcss-calc@^7.0.1: version "7.0.5" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" + resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz" integrity sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg== dependencies: postcss "^7.0.27" @@ -5735,7 +5740,7 @@ postcss-calc@^7.0.1: postcss-color-functional-notation@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + resolved "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz" integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== dependencies: postcss "^7.0.2" @@ -5743,7 +5748,7 @@ postcss-color-functional-notation@^2.0.1: postcss-color-gray@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + resolved "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz" integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== dependencies: "@csstools/convert-colors" "^1.4.0" @@ -5752,7 +5757,7 @@ postcss-color-gray@^5.0.0: postcss-color-hex-alpha@^5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + resolved "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz" integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== dependencies: postcss "^7.0.14" @@ -5760,7 +5765,7 @@ postcss-color-hex-alpha@^5.0.3: postcss-color-mod-function@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + resolved "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz" integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== dependencies: "@csstools/convert-colors" "^1.4.0" @@ -5769,7 +5774,7 @@ postcss-color-mod-function@^3.0.3: postcss-color-rebeccapurple@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + resolved "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz" integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== dependencies: postcss "^7.0.2" @@ -5777,7 +5782,7 @@ postcss-color-rebeccapurple@^4.0.1: postcss-colormin@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + resolved "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz" integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== dependencies: browserslist "^4.0.0" @@ -5788,7 +5793,7 @@ postcss-colormin@^4.0.3: postcss-convert-values@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + resolved "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz" integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== dependencies: postcss "^7.0.0" @@ -5796,14 +5801,14 @@ postcss-convert-values@^4.0.1: postcss-custom-media@^7.0.8: version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + resolved "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz" integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== dependencies: postcss "^7.0.14" postcss-custom-properties@^8.0.11: version "8.0.11" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + resolved "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz" integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== dependencies: postcss "^7.0.17" @@ -5811,7 +5816,7 @@ postcss-custom-properties@^8.0.11: postcss-custom-selectors@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + resolved "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz" integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== dependencies: postcss "^7.0.2" @@ -5819,7 +5824,7 @@ postcss-custom-selectors@^5.1.2: postcss-dir-pseudo-class@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + resolved "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz" integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== dependencies: postcss "^7.0.2" @@ -5827,35 +5832,35 @@ postcss-dir-pseudo-class@^5.0.0: postcss-discard-comments@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + resolved "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz" integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== dependencies: postcss "^7.0.0" postcss-discard-duplicates@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + resolved "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz" integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== dependencies: postcss "^7.0.0" postcss-discard-empty@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + resolved "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz" integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== dependencies: postcss "^7.0.0" postcss-discard-overridden@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + resolved "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz" integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== dependencies: postcss "^7.0.0" postcss-double-position-gradients@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + resolved "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz" integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== dependencies: postcss "^7.0.5" @@ -5863,7 +5868,7 @@ postcss-double-position-gradients@^1.0.0: postcss-env-function@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + resolved "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz" integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== dependencies: postcss "^7.0.2" @@ -5871,42 +5876,42 @@ postcss-env-function@^2.0.2: postcss-flexbugs-fixes@^4.2.1: version "4.2.1" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + resolved "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz" integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== dependencies: postcss "^7.0.26" postcss-focus-visible@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + resolved "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz" integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== dependencies: postcss "^7.0.2" postcss-focus-within@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + resolved "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz" integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== dependencies: postcss "^7.0.2" postcss-font-variant@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" + resolved "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz" integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== dependencies: postcss "^7.0.2" postcss-gap-properties@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + resolved "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz" integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== dependencies: postcss "^7.0.2" postcss-image-set-function@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + resolved "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz" integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== dependencies: postcss "^7.0.2" @@ -5914,7 +5919,7 @@ postcss-image-set-function@^3.0.1: postcss-import@^12.0.1: version "12.0.1" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" + resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz" integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== dependencies: postcss "^7.0.1" @@ -5924,7 +5929,7 @@ postcss-import@^12.0.1: postcss-initial@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" + resolved "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz" integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== dependencies: lodash.template "^4.5.0" @@ -5932,7 +5937,7 @@ postcss-initial@^3.0.0: postcss-lab-function@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + resolved "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz" integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== dependencies: "@csstools/convert-colors" "^1.4.0" @@ -5941,7 +5946,7 @@ postcss-lab-function@^2.0.1: postcss-load-config@^2.0.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" + resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz" integrity sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw== dependencies: cosmiconfig "^5.0.0" @@ -5949,7 +5954,7 @@ postcss-load-config@^2.0.0: postcss-loader@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + resolved "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz" integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== dependencies: loader-utils "^1.1.0" @@ -5959,21 +5964,21 @@ postcss-loader@^3.0.0: postcss-logical@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + resolved "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz" integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== dependencies: postcss "^7.0.2" postcss-media-minmax@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + resolved "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz" integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== dependencies: postcss "^7.0.2" postcss-merge-longhand@^4.0.11: version "4.0.11" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + resolved "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz" integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== dependencies: css-color-names "0.0.4" @@ -5983,7 +5988,7 @@ postcss-merge-longhand@^4.0.11: postcss-merge-rules@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + resolved "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz" integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== dependencies: browserslist "^4.0.0" @@ -5995,7 +6000,7 @@ postcss-merge-rules@^4.0.3: postcss-minify-font-values@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + resolved "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz" integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== dependencies: postcss "^7.0.0" @@ -6003,7 +6008,7 @@ postcss-minify-font-values@^4.0.2: postcss-minify-gradients@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + resolved "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz" integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== dependencies: cssnano-util-get-arguments "^4.0.0" @@ -6013,7 +6018,7 @@ postcss-minify-gradients@^4.0.2: postcss-minify-params@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + resolved "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz" integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== dependencies: alphanum-sort "^1.0.0" @@ -6025,7 +6030,7 @@ postcss-minify-params@^4.0.2: postcss-minify-selectors@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + resolved "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz" integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== dependencies: alphanum-sort "^1.0.0" @@ -6035,14 +6040,14 @@ postcss-minify-selectors@^4.0.2: postcss-modules-extract-imports@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz" integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== dependencies: postcss "^7.0.5" postcss-modules-local-by-default@^3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz" integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== dependencies: icss-utils "^4.1.1" @@ -6052,7 +6057,7 @@ postcss-modules-local-by-default@^3.0.2: postcss-modules-scope@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz" integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== dependencies: postcss "^7.0.6" @@ -6060,7 +6065,7 @@ postcss-modules-scope@^2.2.0: postcss-modules-values@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz" integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== dependencies: icss-utils "^4.0.0" @@ -6068,21 +6073,21 @@ postcss-modules-values@^3.0.0: postcss-nesting@^7.0.0: version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + resolved "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz" integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== dependencies: postcss "^7.0.2" postcss-normalize-charset@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + resolved "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz" integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== dependencies: postcss "^7.0.0" postcss-normalize-display-values@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + resolved "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz" integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== dependencies: cssnano-util-get-match "^4.0.0" @@ -6091,7 +6096,7 @@ postcss-normalize-display-values@^4.0.2: postcss-normalize-positions@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + resolved "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz" integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== dependencies: cssnano-util-get-arguments "^4.0.0" @@ -6101,7 +6106,7 @@ postcss-normalize-positions@^4.0.2: postcss-normalize-repeat-style@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + resolved "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz" integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== dependencies: cssnano-util-get-arguments "^4.0.0" @@ -6111,7 +6116,7 @@ postcss-normalize-repeat-style@^4.0.2: postcss-normalize-string@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + resolved "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz" integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== dependencies: has "^1.0.0" @@ -6120,7 +6125,7 @@ postcss-normalize-string@^4.0.2: postcss-normalize-timing-functions@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + resolved "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz" integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== dependencies: cssnano-util-get-match "^4.0.0" @@ -6129,7 +6134,7 @@ postcss-normalize-timing-functions@^4.0.2: postcss-normalize-unicode@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + resolved "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz" integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== dependencies: browserslist "^4.0.0" @@ -6138,7 +6143,7 @@ postcss-normalize-unicode@^4.0.1: postcss-normalize-url@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + resolved "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz" integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== dependencies: is-absolute-url "^2.0.0" @@ -6148,7 +6153,7 @@ postcss-normalize-url@^4.0.1: postcss-normalize-whitespace@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + resolved "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz" integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== dependencies: postcss "^7.0.0" @@ -6156,7 +6161,7 @@ postcss-normalize-whitespace@^4.0.2: postcss-ordered-values@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + resolved "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz" integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== dependencies: cssnano-util-get-arguments "^4.0.0" @@ -6165,21 +6170,21 @@ postcss-ordered-values@^4.1.2: postcss-overflow-shorthand@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + resolved "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz" integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== dependencies: postcss "^7.0.2" postcss-page-break@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + resolved "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz" integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== dependencies: postcss "^7.0.2" postcss-place@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + resolved "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz" integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== dependencies: postcss "^7.0.2" @@ -6187,7 +6192,7 @@ postcss-place@^4.0.1: postcss-preset-env@^6.7.0: version "6.7.0" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + resolved "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz" integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== dependencies: autoprefixer "^9.6.1" @@ -6230,7 +6235,7 @@ postcss-preset-env@^6.7.0: postcss-pseudo-class-any-link@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + resolved "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz" integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== dependencies: postcss "^7.0.2" @@ -6238,7 +6243,7 @@ postcss-pseudo-class-any-link@^6.0.0: postcss-reduce-initial@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + resolved "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz" integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== dependencies: browserslist "^4.0.0" @@ -6248,7 +6253,7 @@ postcss-reduce-initial@^4.0.3: postcss-reduce-transforms@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + resolved "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz" integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== dependencies: cssnano-util-get-match "^4.0.0" @@ -6258,21 +6263,21 @@ postcss-reduce-transforms@^4.0.2: postcss-replace-overflow-wrap@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + resolved "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz" integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== dependencies: postcss "^7.0.2" postcss-safe-parser@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" + resolved "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz" integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== dependencies: postcss "^7.0.26" postcss-selector-matches@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + resolved "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz" integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== dependencies: balanced-match "^1.0.0" @@ -6280,7 +6285,7 @@ postcss-selector-matches@^4.0.0: postcss-selector-not@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + resolved "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz" integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== dependencies: balanced-match "^1.0.0" @@ -6288,7 +6293,7 @@ postcss-selector-not@^4.0.0: postcss-selector-parser@^3.0.0: version "3.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz" integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== dependencies: dot-prop "^5.2.0" @@ -6297,7 +6302,7 @@ postcss-selector-parser@^3.0.0: postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz" integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== dependencies: cssesc "^2.0.0" @@ -6306,7 +6311,7 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz" integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== dependencies: cssesc "^3.0.0" @@ -6316,7 +6321,7 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: postcss-svgo@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + resolved "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz" integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== dependencies: is-svg "^3.0.0" @@ -6326,7 +6331,7 @@ postcss-svgo@^4.0.2: postcss-unique-selectors@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + resolved "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz" integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== dependencies: alphanum-sort "^1.0.0" @@ -6335,17 +6340,17 @@ postcss-unique-selectors@^4.0.1: postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3: version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + resolved "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz" integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== dependencies: flatten "^1.0.2" @@ -6354,7 +6359,7 @@ postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: version "7.0.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz" integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== dependencies: chalk "^2.4.2" @@ -6363,32 +6368,32 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2 prepend-http@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@^0.11.10: version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= promise-inflight@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= promise-polyfill@^8.1.3: version "8.2.0" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.0.tgz#367394726da7561457aba2133c9ceefbd6267da0" + resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.0.tgz" integrity sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g== prosemirror-commands@^1.0.0: version "1.1.6" - resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.6.tgz#727c045eb60e7d61f1b1d0a9411a7f60286bb1de" + resolved "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.6.tgz" integrity sha512-oh3DN9qhtYR+4/Yfb9+hAKjiV4pEqPRxsPqUeoVqJP7Dfbk4jQKYZFDKMZgLAdSFi49fMeiVYieN3fpjOLuP0Q== dependencies: prosemirror-model "^1.0.0" @@ -6397,7 +6402,7 @@ prosemirror-commands@^1.0.0: prosemirror-dropcursor@^1.0.0: version "1.3.3" - resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.3.tgz#583d6a82b4960d468132c07c40803cc1d697fda4" + resolved "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.3.tgz" integrity sha512-zavE+wh+qkDcP7LaWn+jXVujGyQzBYSmM8E2HSngQ3KaaR+HJYgEBYGs9ynLHqKWLlLCXsxWdVYPV49v4caFyg== dependencies: prosemirror-state "^1.0.0" @@ -6406,7 +6411,7 @@ prosemirror-dropcursor@^1.0.0: prosemirror-example-setup@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/prosemirror-example-setup/-/prosemirror-example-setup-1.1.2.tgz#0df63d14a26b174933345814cb6503ad72a4ccdb" + resolved "https://registry.npmjs.org/prosemirror-example-setup/-/prosemirror-example-setup-1.1.2.tgz" integrity sha512-MTpIMyqk08jFnzxeRMCinCEMtVSTUtxKgQBGxfCbVe9C6zIOqp9qZZJz5Ojaad1GETySyuj8+OIHHvQsIaaaGQ== dependencies: prosemirror-commands "^1.0.0" @@ -6421,7 +6426,7 @@ prosemirror-example-setup@^1.1.2: prosemirror-gapcursor@^1.0.0: version "1.1.5" - resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.1.5.tgz#0c37fd6cbb1d7c46358c2e7397f8da9a8b5c6246" + resolved "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.1.5.tgz" integrity sha512-SjbUZq5pgsBDuV3hu8GqgIpZR5eZvGLM+gPQTqjVVYSMUCfKW3EGXTEYaLHEl1bGduwqNC95O3bZflgtAb4L6w== dependencies: prosemirror-keymap "^1.0.0" @@ -6431,7 +6436,7 @@ prosemirror-gapcursor@^1.0.0: prosemirror-history@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.1.3.tgz#4f76a1e71db4ef7cdf0e13dec6d8da2aeaecd489" + resolved "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz" integrity sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg== dependencies: prosemirror-state "^1.2.2" @@ -6440,7 +6445,7 @@ prosemirror-history@^1.0.0: prosemirror-inputrules@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz#93f9199ca02473259c30d7e352e4c14022d54638" + resolved "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz" integrity sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw== dependencies: prosemirror-state "^1.0.0" @@ -6448,7 +6453,7 @@ prosemirror-inputrules@^1.0.0: prosemirror-keymap@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz#8b481bf8389a5ac40d38dbd67ec3da2c7eac6a6d" + resolved "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz" integrity sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg== dependencies: prosemirror-state "^1.0.0" @@ -6456,7 +6461,7 @@ prosemirror-keymap@^1.0.0: prosemirror-markdown@^1.4.5: version "1.5.1" - resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.5.1.tgz#877c7faea2225d3c52e988599bbe4457bcb3190f" + resolved "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.5.1.tgz" integrity sha512-QvucPHx+gKOQW1SETKUysrful9VBjKqpCFmPotgLfVZ3BdQEGy/NEIFhaXXo3TcuW316MMnKfA90K7GE5I7z8A== dependencies: markdown-it "^10.0.0" @@ -6464,7 +6469,7 @@ prosemirror-markdown@^1.4.5: prosemirror-menu@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.1.4.tgz#a845ae0e14ce1f92dd39d7f23caa6063265cd98c" + resolved "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.1.4.tgz" integrity sha512-2ROsji/X9ciDnVSRvSTqFygI34GEdHfQSsK4zBKjPxSEroeiHHcdRMS1ofNIf2zM0Vpp5/YqfpxynElymQkqzg== dependencies: crelt "^1.0.0" @@ -6474,21 +6479,21 @@ prosemirror-menu@^1.0.0: prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.2.0: version "1.13.3" - resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.13.3.tgz#3ccfde73b9c9e706933c72bdf7462906509ff1c9" + resolved "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.13.3.tgz" integrity sha512-wujIYYQEcxdkbKmIJiekVjqtylKxuoEcc+w2PnN7Itc58m/75J4rCUz2dibygVQJFi3gZrD2DNFLjOS6LP4w1g== dependencies: orderedmap "^1.1.0" prosemirror-schema-basic@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz#4bde5c339c845e0d08ec8fe473064e372ca51ae3" + resolved "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz" integrity sha512-G4q8WflNsR1Q33QAV4MQO0xWrHLOJ+BQcKswGXMy626wlQj6c/1n1v4eC9ns+h2y1r/fJHZEgSZnsNhm9lbrDw== dependencies: prosemirror-model "^1.2.0" prosemirror-schema-list@^1.0.0: version "1.1.4" - resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.4.tgz#471f9caf2d2bed93641d2e490434c0d2d4330df1" + resolved "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.1.4.tgz" integrity sha512-pNTuZflacFOBlxrTcWSdWhjoB8BaucwfJVp/gJNxztOwaN3wQiC65axclXyplf6TKgXD/EkWfS/QAov3/Znadw== dependencies: prosemirror-model "^1.0.0" @@ -6496,7 +6501,7 @@ prosemirror-schema-list@^1.0.0: prosemirror-state@^1.0.0, prosemirror-state@^1.2.2: version "1.3.4" - resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952" + resolved "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.4.tgz" integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA== dependencies: prosemirror-model "^1.0.0" @@ -6504,14 +6509,14 @@ prosemirror-state@^1.0.0, prosemirror-state@^1.2.2: prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0: version "1.2.11" - resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.2.11.tgz#87fc53b2b1344ca4c2c4cb3f3b61486794b6a0b3" + resolved "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.2.11.tgz" integrity sha512-i4N5bMZcmhZPJw1ULH2Ne6SumqrkWBQpJXo/PN6xwq8kv6q7IZVYDjF7DRe2vp3AiqZ/5KnLucJM7e82875LyQ== dependencies: prosemirror-model "^1.0.0" prosemirror-view@^1.0.0, prosemirror-view@^1.1.0: version "1.17.6" - resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.17.6.tgz#9c31c84b9b78bd3aa3343d1b90eff36869387a5b" + resolved "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.17.6.tgz" integrity sha512-ZnpIQg8DzrvpeBPLab3UUEjwjA37CwOjQruDyzdHYUf6MA95H48tchIOVrwUdQxFDhETaG5iQOWZlAzYj+olzw== dependencies: prosemirror-model "^1.1.0" @@ -6520,7 +6525,7 @@ prosemirror-view@^1.0.0, prosemirror-view@^1.1.0: proxy-addr@~2.0.5: version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz" integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== dependencies: forwarded "~0.1.2" @@ -6528,22 +6533,22 @@ proxy-addr@~2.0.5: prr@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= pseudomap@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.28: version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== public-encrypt@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" @@ -6555,7 +6560,7 @@ public-encrypt@^4.0.0: pump@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz" integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== dependencies: end-of-stream "^1.1.0" @@ -6563,7 +6568,7 @@ pump@^2.0.0: pump@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -6571,7 +6576,7 @@ pump@^3.0.0: pumpify@^1.3.3: version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + resolved "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz" integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== dependencies: duplexify "^3.6.0" @@ -6580,37 +6585,37 @@ pumpify@^1.3.3: punycode@1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@^1.2.4: version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== q@^1.1.2: version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= qs@6.7.0: version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + resolved "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== qs@~6.5.2: version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^4.1.0: version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + resolved "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz" integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= dependencies: object-assign "^4.1.0" @@ -6618,29 +6623,29 @@ query-string@^4.1.0: querystring-es3@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= querystring@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= querystringify@^2.1.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz" integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" @@ -6648,12 +6653,12 @@ randomfill@^1.0.3: range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== raw-body@2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz" integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== dependencies: bytes "3.1.0" @@ -6663,14 +6668,14 @@ raw-body@2.4.0: read-cache@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= dependencies: pify "^2.3.0" read-pkg-up@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz" integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= dependencies: find-up "^1.0.0" @@ -6678,7 +6683,7 @@ read-pkg-up@^1.0.1: read-pkg@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz" integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= dependencies: load-json-file "^1.0.0" @@ -6687,7 +6692,7 @@ read-pkg@^1.0.0: "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -6700,7 +6705,7 @@ read-pkg@^1.0.0: readable-stream@^3.0.6, readable-stream@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" @@ -6709,7 +6714,7 @@ readable-stream@^3.0.6, readable-stream@^3.6.0: readdirp@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz" integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: graceful-fs "^4.1.11" @@ -6718,14 +6723,14 @@ readdirp@^2.2.1: readdirp@~3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz" integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: picomatch "^2.2.1" redent@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + resolved "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz" integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= dependencies: indent-string "^2.1.0" @@ -6733,31 +6738,31 @@ redent@^1.0.0: regenerate-unicode-properties@^8.2.0: version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz" integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== dependencies: regenerate "^1.4.0" regenerate@^1.4.0: version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== regenerator-transform@^0.14.2: version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz" integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: "@babel/runtime" "^7.8.4" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" @@ -6765,7 +6770,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: regexp.prototype.flags@^1.2.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== dependencies: call-bind "^1.0.2" @@ -6773,7 +6778,7 @@ regexp.prototype.flags@^1.2.0: regexpu-core@^4.7.1: version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz" integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== dependencies: regenerate "^1.4.0" @@ -6785,41 +6790,41 @@ regexpu-core@^4.7.1: regjsgen@^0.5.1: version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: version "0.6.7" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.7.tgz#c00164e1e6713c2e3ee641f1701c4b7aa0a7f86c" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.7.tgz" integrity sha512-ib77G0uxsA2ovgiYbCVGx4Pv3PSttAx2vIwidqQzbL2U5S4Q+j00HdSAneSBuyVcMvEnTXMjiGgB+DlXozVhpQ== dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.6.1: version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= repeating@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz" integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= dependencies: is-finite "^1.0.0" request@^2.87.0, request@^2.88.0: version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" @@ -6845,29 +6850,29 @@ request@^2.87.0, request@^2.88.0: require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= require-main-filename@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== requires-port@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= resolve-cwd@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz" integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= dependencies: resolve-from "^3.0.0" resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz" integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= dependencies: expand-tilde "^2.0.0" @@ -6875,22 +6880,22 @@ resolve-dir@^1.0.0, resolve-dir@^1.0.1: resolve-from@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz" integrity sha1-six699nWiBvItuZTM17rywoYh0g= resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-url@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0: version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: is-core-module "^2.2.0" @@ -6898,41 +6903,41 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0: ret@~0.1.10: version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== retry@^0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= rgb-regex@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + resolved "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz" integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= rgba-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" @@ -6940,41 +6945,41 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: rope-sequence@^1.3.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.2.tgz#a19e02d72991ca71feb6b5f8a91154e48e3c098b" + resolved "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.2.tgz" integrity sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg== run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + resolved "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz" integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= dependencies: aproba "^1.1.1" safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sass-graph@2.2.5: version "2.2.5" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8" + resolved "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz" integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== dependencies: glob "^7.0.0" @@ -6984,7 +6989,7 @@ sass-graph@2.2.5: sass-loader@^8.0.2: version "8.0.2" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d" + resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz" integrity sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ== dependencies: clone-deep "^4.0.1" @@ -6995,12 +7000,12 @@ sass-loader@^8.0.2: sax@~1.2.4: version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== schema-utils@2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== dependencies: "@types/json-schema" "^7.0.4" @@ -7009,7 +7014,7 @@ schema-utils@2.7.0: schema-utils@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz" integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== dependencies: ajv "^6.1.0" @@ -7018,7 +7023,7 @@ schema-utils@^1.0.0: schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.7.0: version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: "@types/json-schema" "^7.0.5" @@ -7027,7 +7032,7 @@ schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.7.0: schema-utils@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz" integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== dependencies: "@types/json-schema" "^7.0.6" @@ -7036,7 +7041,7 @@ schema-utils@^3.0.0: scss-tokenizer@^0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + resolved "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz" integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= dependencies: js-base64 "^2.1.8" @@ -7044,46 +7049,46 @@ scss-tokenizer@^0.2.3: select-hose@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= selfsigned@^1.10.8: version "1.10.8" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz" integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w== dependencies: node-forge "^0.10.0" "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== semver@^6.0.0, semver@^6.3.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.3.2: version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz" integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== dependencies: lru-cache "^6.0.0" semver@~5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= send@0.17.1: version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz" integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== dependencies: debug "2.6.9" @@ -7102,21 +7107,21 @@ send@0.17.1: serialize-javascript@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz" integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== dependencies: randombytes "^2.1.0" serialize-javascript@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz" integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== dependencies: randombytes "^2.1.0" serve-index@^1.9.1: version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= dependencies: accepts "~1.3.4" @@ -7129,7 +7134,7 @@ serve-index@^1.9.1: serve-static@1.14.1: version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz" integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== dependencies: encodeurl "~1.0.2" @@ -7139,12 +7144,12 @@ serve-static@1.14.1: set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: extend-shallow "^2.0.1" @@ -7154,22 +7159,22 @@ set-value@^2.0.0, set-value@^2.0.1: setimmediate@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= setprototypeof@1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== setprototypeof@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -7177,38 +7182,38 @@ sha.js@^2.4.0, sha.js@^2.4.8: shallow-clone@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== dependencies: kind-of "^6.0.2" shebang-command@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= signal-exit@^3.0.0: version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== simple-swizzle@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= dependencies: is-arrayish "^0.3.1" snapdragon-node@^2.0.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" @@ -7217,14 +7222,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" @@ -7238,7 +7243,7 @@ snapdragon@^0.8.1: sockjs-client@^1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add" + resolved "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz" integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q== dependencies: debug "^3.2.6" @@ -7250,7 +7255,7 @@ sockjs-client@^1.5.0: sockjs@^0.3.21: version "0.3.21" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" + resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz" integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== dependencies: faye-websocket "^0.11.3" @@ -7259,19 +7264,19 @@ sockjs@^0.3.21: sort-keys@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz" integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= dependencies: is-plain-obj "^1.0.0" source-list-map@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: atob "^2.1.2" @@ -7282,7 +7287,7 @@ source-map-resolve@^0.5.0: source-map-support@~0.5.12, source-map-support@~0.5.19: version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== dependencies: buffer-from "^1.0.0" @@ -7290,39 +7295,39 @@ source-map-support@~0.5.12, source-map-support@~0.5.19: source-map-url@^0.4.0: version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@^0.4.2: version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz" integrity sha1-66T12pwNyZneaAMti092FzZSA2s= dependencies: amdefine ">=0.0.4" source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@~0.7.2: version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== spark-md5@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.1.tgz#83a0e255734f2ab4e5c466e5a2cfc9ba2aa2124d" + resolved "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz" integrity sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig== spdx-correct@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" @@ -7330,12 +7335,12 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" @@ -7343,12 +7348,12 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz" integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== spdy-transport@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== dependencies: debug "^4.1.0" @@ -7360,7 +7365,7 @@ spdy-transport@^3.0.0: spdy@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== dependencies: debug "^4.1.0" @@ -7371,19 +7376,19 @@ spdy@^4.0.2: split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz" integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== dependencies: asn1 "~0.2.3" @@ -7398,31 +7403,31 @@ sshpk@^1.7.0: ssri@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz" integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== dependencies: figgy-pudding "^3.5.1" ssri@^8.0.0: version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: minipass "^3.1.1" stable@^0.1.8: version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stackframe@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz" integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== static-extend@^0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" @@ -7430,19 +7435,19 @@ static-extend@^0.1.1: "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= stdout-stream@^1.4.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" + resolved "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz" integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== dependencies: readable-stream "^2.0.1" stimulus@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/stimulus/-/stimulus-1.1.1.tgz#53c2fded6849e7b85eed3ed8dd76e33abd74bec5" + resolved "https://registry.npmjs.org/stimulus/-/stimulus-1.1.1.tgz" integrity sha512-R0mBqKp48YnRDZOxZ8hiOH4Ilph3Yj78CIFTBkCwyHs4iGCpe7xlEdQ7cjIxb+7qVCSxFKgxO+mAQbsNgt/5XQ== dependencies: "@stimulus/core" "^1.1.1" @@ -7450,7 +7455,7 @@ stimulus@^1.1.1: stream-browserify@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz" integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" @@ -7458,7 +7463,7 @@ stream-browserify@^2.0.1: stream-each@^1.1.0: version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + resolved "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz" integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== dependencies: end-of-stream "^1.1.0" @@ -7466,7 +7471,7 @@ stream-each@^1.1.0: stream-http@^2.7.2: version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz" integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" @@ -7477,17 +7482,17 @@ stream-http@^2.7.2: stream-shift@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== strict-uri-encode@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= string-width@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" @@ -7496,7 +7501,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2": version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" @@ -7504,7 +7509,7 @@ string-width@^1.0.1: string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== dependencies: emoji-regex "^7.0.1" @@ -7513,12 +7518,12 @@ string-width@^3.0.0, string-width@^3.1.0: string.prototype.repeat@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf" + resolved "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz" integrity sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8= string.prototype.trimend@^1.0.1, string.prototype.trimend@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz" integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== dependencies: call-bind "^1.0.0" @@ -7526,7 +7531,7 @@ string.prototype.trimend@^1.0.1, string.prototype.trimend@^1.0.3: string.prototype.trimstart@^1.0.1, string.prototype.trimstart@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz" integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== dependencies: call-bind "^1.0.0" @@ -7534,61 +7539,61 @@ string.prototype.trimstart@^1.0.1, string.prototype.trimstart@^1.0.3: string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" strip-bom@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= dependencies: is-utf8 "^0.2.0" strip-eof@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-indent@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz" integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= dependencies: get-stdin "^4.0.1" style-loader@^1.2.1: version "1.3.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + resolved "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz" integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: loader-utils "^2.0.0" @@ -7596,7 +7601,7 @@ style-loader@^1.2.1: stylehacks@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz" integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== dependencies: browserslist "^4.0.0" @@ -7605,33 +7610,33 @@ stylehacks@^4.0.0: supports-color@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz" integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== dependencies: has-flag "^3.0.0" supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" svgo@^1.0.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + resolved "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz" integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== dependencies: chalk "^2.4.1" @@ -7650,12 +7655,12 @@ svgo@^1.0.0: tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^2.0.0: version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + resolved "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz" integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== dependencies: block-stream "*" @@ -7664,7 +7669,7 @@ tar@^2.0.0: tar@^6.0.2: version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + resolved "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz" integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== dependencies: chownr "^2.0.0" @@ -7676,14 +7681,14 @@ tar@^6.0.2: tdigest@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.1.tgz#2e3cb2c39ea449e55d1e6cd91117accca4588021" + resolved "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz" integrity sha1-Ljyyw56kSeVdHmzZEReszKRYgCE= dependencies: bintrees "1.0.1" terser-webpack-plugin@^1.4.3: version "1.4.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz" integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== dependencies: cacache "^12.0.2" @@ -7698,7 +7703,7 @@ terser-webpack-plugin@^1.4.3: terser-webpack-plugin@^4.0.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz" integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== dependencies: cacache "^15.0.5" @@ -7713,7 +7718,7 @@ terser-webpack-plugin@^4.0.0: terser@^4.1.2: version "4.8.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + resolved "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== dependencies: commander "^2.20.0" @@ -7722,7 +7727,7 @@ terser@^4.1.2: terser@^5.3.4: version "5.6.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.0.tgz#138cdf21c5e3100b1b3ddfddf720962f88badcd2" + resolved "https://registry.npmjs.org/terser/-/terser-5.6.0.tgz" integrity sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA== dependencies: commander "^2.20.0" @@ -7731,7 +7736,7 @@ terser@^5.3.4: through2@^2.0.0: version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== dependencies: readable-stream "~2.3.6" @@ -7739,41 +7744,41 @@ through2@^2.0.0: thunky@^1.0.2: version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== timers-browserify@^2.0.4: version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz" integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" timsort@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= to-arraybuffer@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= to-fast-properties@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-object-path@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" @@ -7781,14 +7786,14 @@ to-regex-range@^2.1.0: to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" @@ -7798,12 +7803,12 @@ to-regex@^3.0.1, to-regex@^3.0.2: toidentifier@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== tough-cookie@~2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== dependencies: psl "^1.1.28" @@ -7811,51 +7816,51 @@ tough-cookie@~2.5.0: trim-newlines@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz" integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= "true-case-path@^1.0.2": version "1.0.3" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" + resolved "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz" integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== dependencies: glob "^7.1.2" ts-pnp@^1.1.6: version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + resolved "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tslib@^1.9.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tty-browserify@0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= tunnel-agent@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= dependencies: safe-buffer "^5.0.1" turbolinks@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/turbolinks/-/turbolinks-5.2.0.tgz#e6877a55ea5c1cb3bb225f0a4ae303d6d32ff77c" + resolved "https://registry.npmjs.org/turbolinks/-/turbolinks-5.2.0.tgz" integrity sha512-pMiez3tyBo6uRHFNNZoYMmrES/IaGgMhQQM+VFF36keryjb5ms0XkVpmKHkfW/4Vy96qiGW3K9bz0tF5sK9bBw== tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" @@ -7863,27 +7868,27 @@ type-is@~1.6.17, type-is@~1.6.18: typedarray@^0.0.6: version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^4.1.5: version "4.1.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz" integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz" integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== unicode-match-property-ecmascript@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz" integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== dependencies: unicode-canonical-property-names-ecmascript "^1.0.4" @@ -7891,17 +7896,17 @@ unicode-match-property-ecmascript@^1.0.4: unicode-match-property-value-ecmascript@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz" integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== unicode-property-aliases-ecmascript@^1.0.4: version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== union-value@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== dependencies: arr-union "^3.1.0" @@ -7911,46 +7916,46 @@ union-value@^1.0.0: uniq@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + resolved "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz" integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= uniqs@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + resolved "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz" integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= unique-filename@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz" integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== dependencies: unique-slug "^2.0.0" unique-slug@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz" integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== dependencies: imurmurhash "^0.1.4" universalify@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unquote@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + resolved "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz" integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= unset-value@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" @@ -7958,24 +7963,24 @@ unset-value@^1.0.0: upath@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse@^1.4.3, url-parse@^1.4.7: version "1.5.1" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz" integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== dependencies: querystringify "^2.1.1" @@ -7983,7 +7988,7 @@ url-parse@^1.4.3, url-parse@^1.4.7: url@^0.11.0: version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= dependencies: punycode "1.3.2" @@ -7991,17 +7996,17 @@ url@^0.11.0: use@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= util.promisify@~1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + resolved "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz" integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== dependencies: define-properties "^1.1.3" @@ -8011,36 +8016,36 @@ util.promisify@~1.0.0: util@0.10.3: version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + resolved "https://registry.npmjs.org/util/-/util-0.10.3.tgz" integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" util@^0.11.0: version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + resolved "https://registry.npmjs.org/util/-/util-0.11.1.tgz" integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== dependencies: inherits "2.0.3" utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-compile-cache@^2.1.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz" integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -8048,17 +8053,17 @@ validate-npm-package-license@^3.0.1: vary@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= vendors@^1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + resolved "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== verror@1.10.0: version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= dependencies: assert-plus "^1.0.0" @@ -8067,24 +8072,24 @@ verror@1.10.0: vm-browserify@^1.0.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== w3c-keyname@^2.2.0: version "2.2.4" - resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b" + resolved "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz" integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw== watchpack-chokidar2@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + resolved "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz" integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" watchpack@^1.7.4: version "1.7.5" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz" integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" @@ -8095,14 +8100,14 @@ watchpack@^1.7.4: wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== dependencies: minimalistic-assert "^1.0.0" webpack-assets-manifest@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/webpack-assets-manifest/-/webpack-assets-manifest-3.1.1.tgz#39bbc3bf2ee57fcd8ba07cda51c9ba4a3c6ae1de" + resolved "https://registry.npmjs.org/webpack-assets-manifest/-/webpack-assets-manifest-3.1.1.tgz" integrity sha512-JV9V2QKc5wEWQptdIjvXDUL1ucbPLH2f27toAY3SNdGZp+xSaStAgpoMcvMZmqtFrBc9a5pTS1058vxyMPOzRQ== dependencies: chalk "^2.0" @@ -8115,7 +8120,7 @@ webpack-assets-manifest@^3.1.1: webpack-cli@^3.3.12: version "3.3.12" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a" + resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz" integrity sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag== dependencies: chalk "^2.4.2" @@ -8132,7 +8137,7 @@ webpack-cli@^3.3.12: webpack-dev-middleware@^3.7.2: version "3.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz" integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== dependencies: memory-fs "^0.4.1" @@ -8143,7 +8148,7 @@ webpack-dev-middleware@^3.7.2: webpack-dev-server@^3.11.2: version "3.11.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz" integrity sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ== dependencies: ansi-html "0.0.7" @@ -8182,7 +8187,7 @@ webpack-dev-server@^3.11.2: webpack-log@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + resolved "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz" integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== dependencies: ansi-colors "^3.0.0" @@ -8190,7 +8195,7 @@ webpack-log@^2.0.0: webpack-sources@^1.0.0, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" @@ -8198,7 +8203,7 @@ webpack-sources@^1.0.0, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack- webpack@^4.44.1: version "4.46.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + resolved "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz" integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -8227,7 +8232,7 @@ webpack@^4.44.1: websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== dependencies: http-parser-js ">=0.5.1" @@ -8236,38 +8241,38 @@ websocket-driver@>=0.5.1, websocket-driver@^0.7.4: websocket-extensions@>=0.1.1: version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== which-module@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" worker-farm@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz" integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== dependencies: errno "~0.1.7" wrap-ansi@^5.1.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz" integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== dependencies: ansi-styles "^3.2.0" @@ -8276,49 +8281,49 @@ wrap-ansi@^5.1.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= ws@^6.2.1: version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + resolved "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== dependencies: async-limiter "~1.0.0" xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz" integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== yallist@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.2: version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^1.7.2: version "1.10.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== yargs-parser@^13.1.2: version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== dependencies: camelcase "^5.0.0" @@ -8326,7 +8331,7 @@ yargs-parser@^13.1.2: yargs@^13.3.2: version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== dependencies: cliui "^5.0.0" @@ -8342,10 +8347,10 @@ yargs@^13.3.2: yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zepto@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98" + resolved "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz" integrity sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g= From e55e9813056bde43a3e3604fed7a4828c109ccf9 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 5 Jan 2023 13:33:17 -0300 Subject: [PATCH 038/814] fix: no eliminar atributo role se usan para la accesibilidad de las notas al pie --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 709c87c3..b92f172a 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -198,7 +198,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy class colspan rowspan].freeze + name rel target referrerpolicy class colspan rowspan role].freeze end def allowed_tags From 501091acc5242469de119e582064846d84483fbb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 6 Jan 2023 12:48:53 -0300 Subject: [PATCH 039/814] fix: no eliminar --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index b92f172a..abf2dac6 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -203,7 +203,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_tags @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td br].freeze + figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze end # Decifra el valor From 9c5e370d42bf22f3c782dec4244f0fefdbe004cf Mon Sep 17 00:00:00 2001 From: f Date: Wed, 25 Jan 2023 11:49:12 -0300 Subject: [PATCH 040/814] feat: mantener data-turbo --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index abf2dac6..0458a290 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -198,7 +198,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy class colspan rowspan role].freeze + name rel target referrerpolicy class colspan rowspan role data-turbo].freeze end def allowed_tags From 5611042c58d266e745fa7ca023c2a58944157fed Mon Sep 17 00:00:00 2001 From: f Date: Wed, 25 Jan 2023 13:11:12 -0300 Subject: [PATCH 041/814] editor 0.1.14 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ecbdf0ba..b8e5a939 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.13", + "@suttyweb/editor": "^0.1.14", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 7c634e9b..c68ca2b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,10 +1171,10 @@ resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.13": - version "0.1.13" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.13.tgz#376b87bb7ef92d459c63177fcc590aaf7f04c1c3" - integrity sha512-HBjz7Z/yCIoVrc73ZrmTmhZlJgM7c0mfPAHgL1R9PC0Y8uwaoyfaYKfpBLfes8GOLcUhax+K6CxQORqEq8cv7w== +"@suttyweb/editor@^0.1.14": + version "0.1.14" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.14.tgz#a0f6c1d0e2347e2da05f1f8be4d1cc0ddf2e8e71" + integrity sha512-BnGY7hvZg9XRaVpO1imeQ2+62f3dYkJ6mOG8UamZEbsqKOlsCis8PUGTy8yb6Pl2lyDq+El730N98hOpcIWgmw== "@types/caseless@*": version "0.12.2" From ecff604c8e8b82289bb6fae91b99426881b35616 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:09:58 -0300 Subject: [PATCH 042/814] =?UTF-8?q?fix:=20eliminar=20el=20elemento=20sin?= =?UTF-8?q?=20src=20v=C3=A1lido=20en=20un=20solo=20lugar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_content.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 9d3a1040..7598dc31 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -47,16 +47,13 @@ class MetadataContent < MetadataTemplate # Eliminar elementos sin src y comprobar su origen html.css(elements).each do |element| - unless element['src'] - element.remove - next - end - begin + raise URI::Error unless element['src'].present? + uri = URI element['src'] # No permitimos recursos externos - element.remove unless uri.scheme == 'https' && uri.hostname.end_with?(Site.domain) + raise URI::Error unless Rails.application.config.hosts.include?(uri.hostname) rescue URI::Error element.remove end From 1adfc91a7f413cedf999dea66d210f0eb8fb2cc8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:10:47 -0300 Subject: [PATCH 043/814] feat: convertir urls del panel en urls internas sutty/editor#59 --- app/models/metadata_content.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 7598dc31..233d7448 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -54,6 +54,10 @@ class MetadataContent < MetadataTemplate # No permitimos recursos externos raise URI::Error unless Rails.application.config.hosts.include?(uri.hostname) + + element['src'] = convert_src_to_internal_path uri + + raise URI::Error if element['src'].blank? rescue URI::Error element.remove end @@ -71,4 +75,27 @@ class MetadataContent < MetadataTemplate html.to_s.html_safe end + + # Convierte una URI en una ruta interna del sitio actual + # + # XXX: No verifica si el archivo existe o no. Se supone que existe + # porque ya fue subido antes. + # + # @param uri [URI] + # @return [String,nil] + def convert_src_to_internal_path(uri) + signed_id = uri.path.split('/').fifth + blob = ActiveStorage::Blob.find_signed(signed_id) + + return unless blob + return unless blob.service_name == site.name + + blob_path = Pathname.new(blob.service.path_for(blob.key)).realpath + site_path = Pathname.new(site.path).realpath + + blob_path.relative_path_from(site_path).to_s + rescue ActiveSupport::MessageVerifier::InvalidSignature => e + ExceptionNotifier.notify_exception(e, data: { site: site.name }) + nil + end end From 04622751efcaff344818977213d548340e51ca8f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:12:09 -0300 Subject: [PATCH 044/814] feat: realiza el paso inverso sutty/editor#59 --- app/models/metadata_content.rb | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 233d7448..06c266a5 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -24,7 +24,11 @@ class MetadataContent < MetadataTemplate end def to_s - sanitizer.sanitize value, tags: [], attributes: [] + Nokogiri::HTML.fragment(value).tap do |html| + html.css('[src^="public/"]').each do |element| + element['src'] = convert_internal_path_to_src element['src'] + end + end.to_s end private @@ -76,6 +80,21 @@ class MetadataContent < MetadataTemplate html.to_s.html_safe end + # Convierte una ubicación local al sitio en una URL de ActiveStorage + # + # XXX: Por qué son tan díficiles de encontrar las rutas de AS + # + # @param path [String] + # @return [String] + def convert_internal_path_to_src(path) + key = path.split('/').second + blob = ActiveStorage::Blob.find_by(service_name: site.name, key: key) + + return unless blob + + "/rails/active_storage/blobs/#{blob.signed_id}/#{blob.filename}" + end + # Convierte una URI en una ruta interna del sitio actual # # XXX: No verifica si el archivo existe o no. Se supone que existe From 0781bee40ab84749997d70d583df75517b5e73d5 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:12:27 -0300 Subject: [PATCH 045/814] fix: usar MetadataContent#to_s para procesar los adjuntos --- app/views/posts/attributes/_new_content.haml | 2 +- app/views/posts/show.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/attributes/_new_content.haml b/app/views/posts/attributes/_new_content.haml index 520daff8..cbdf8f94 100644 --- a/app/views/posts/attributes/_new_content.haml +++ b/app/views/posts/attributes/_new_content.haml @@ -4,6 +4,6 @@ post: post, attribute: attribute, metadata: metadata .new-editor.content{ id: attribute } - = text_area_tag "#{base}[#{attribute}]", metadata.value.html_safe, + = text_area_tag "#{base}[#{attribute}]", metadata.to_s.html_safe, dir: dir, lang: locale, **field_options(attribute, metadata), class: 'd-none' diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index da3dd16a..c88905dc 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -38,4 +38,4 @@ - cache [metadata, I18n.locale] do %section.content.pb-3{ id: attr, dir: dir } - = @post.public_send(attr).value.html_safe + = @post.public_send(attr).to_s.html_safe From 4e4091f6c98e3d9e547252a5f94262bec344b952 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:13:00 -0300 Subject: [PATCH 046/814] feat: limpieza de estilos esto permite guardar los nuevos estilos sin permitir otras cosas sutty/editor!1 --- app/models/metadata_content.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 06c266a5..1664a18f 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -77,9 +77,40 @@ class MetadataContent < MetadataTemplate resource['controls'] = true end + # Elimina los estilos salvo los que asigne el editor + html.css('[style]').each do |element| + if (style = sanitize_style(element['style'])).present? + element['style'] = style + else + element.remove_attribute('style') + end + end + html.to_s.html_safe end + # Limpia estilos en base a una lista de permitidos + # + # @param style [String] + # @return [String] + def sanitize_style(style) + style.split(';').reduce({}) do |style_hash, style_string| + key, value = style_string.split(':', 2) + + style_hash[key] ||= value + style_hash + end.slice(*allowed_styles).map do |style_pair| + style_pair.join(':') + end.join(';') + end + + # Estilos permitidos + # + # @return [Array] + def allowed_styles + @allowed_styles ||= %w[text-align color background-color] + end + # Convierte una ubicación local al sitio en una URL de ActiveStorage # # XXX: Por qué son tan díficiles de encontrar las rutas de AS From d095dbcc1454beeb98aa4ab99ca1ee8754675bbf Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:51:30 -0300 Subject: [PATCH 047/814] fix: usar HTML5 --- app/models/metadata_content.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 1664a18f..761518e8 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -24,7 +24,7 @@ class MetadataContent < MetadataTemplate end def to_s - Nokogiri::HTML.fragment(value).tap do |html| + Nokogiri::HTML5.fragment(value).tap do |html| html.css('[src^="public/"]').each do |element| element['src'] = convert_internal_path_to_src element['src'] end @@ -46,7 +46,7 @@ class MetadataContent < MetadataTemplate # TODO: En lugar de comprobar el Content Type acá, restringir los # tipos de archivo a aceptar en ActiveStorage. def sanitize(html_string) - html = Nokogiri::HTML.fragment(super html_string) + html = Nokogiri::HTML5.fragment(super html_string) elements = 'img,audio,video,iframe' # Eliminar elementos sin src y comprobar su origen From 727435569c5fba11bb3b02363c041ee9af49fb39 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:51:58 -0300 Subject: [PATCH 048/814] =?UTF-8?q?fix:=20rehabilitar=20protecci=C3=B3n=20?= =?UTF-8?q?contra=20dns=20rebinding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lo habíamos deshabilitado en 2022 sin una explicación real y nos impide verificar la procedencia de los archivos. --- config/initializers/hosts.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/initializers/hosts.rb b/config/initializers/hosts.rb index 58ee2e39..db8bd9c4 100644 --- a/config/initializers/hosts.rb +++ b/config/initializers/hosts.rb @@ -1,11 +1,10 @@ # frozen_string_literal: true Rails.application.configure do - next unless ENV['RAILS_ENV'] == 'development' + next Rails.env.test? domain = ENV.fetch('SUTTY', 'sutty.nl') - config.hosts << domain config.hosts << "panel.#{domain}" config.hosts << "api.#{domain}" end From 28767145a5a953335cd82c154416e770d5a56822 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Feb 2023 17:54:34 -0300 Subject: [PATCH 049/814] feat: habilitar la api pero no el panel retrocompatibilidad con sitios que llaman a api.sit.io --- config/initializers/hosts.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/initializers/hosts.rb b/config/initializers/hosts.rb index db8bd9c4..e0a3c2be 100644 --- a/config/initializers/hosts.rb +++ b/config/initializers/hosts.rb @@ -7,4 +7,5 @@ Rails.application.configure do config.hosts << "panel.#{domain}" config.hosts << "api.#{domain}" + config.hosts << /\Aapi\./ end From de10837ad3f1162d2e90e1704b4461c4524421e3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 3 Feb 2023 11:50:09 -0300 Subject: [PATCH 050/814] fix: typo --- config/initializers/hosts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/hosts.rb b/config/initializers/hosts.rb index e0a3c2be..49d0b333 100644 --- a/config/initializers/hosts.rb +++ b/config/initializers/hosts.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true Rails.application.configure do - next Rails.env.test? + next if Rails.env.test? domain = ENV.fetch('SUTTY', 'sutty.nl') From df48f0cf5760bd2eb644d162dd4e729699ca292d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 14 Mar 2023 15:36:20 -0300 Subject: [PATCH 051/814] fix: retrocompatibilidad --- app/views/posts/attributes/_content.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/attributes/_content.haml b/app/views/posts/attributes/_content.haml index 53e7bbfa..608ca6a3 100644 --- a/app/views/posts/attributes/_content.haml +++ b/app/views/posts/attributes/_content.haml @@ -127,4 +127,4 @@ %p= t('editor.word') .editor-content.form-control.h-auto.mt-1{ contenteditable: 'true' } - = metadata.value.html_safe + = metadata.value.to_s From 07da26b0a415dacdda2b102b41a78122f4437b13 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 14 Mar 2023 15:41:28 -0300 Subject: [PATCH 052/814] fixup! fix: retrocompatibilidad --- app/views/posts/attributes/_content.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/attributes/_content.haml b/app/views/posts/attributes/_content.haml index 608ca6a3..9a5069c9 100644 --- a/app/views/posts/attributes/_content.haml +++ b/app/views/posts/attributes/_content.haml @@ -127,4 +127,4 @@ %p= t('editor.word') .editor-content.form-control.h-auto.mt-1{ contenteditable: 'true' } - = metadata.value.to_s + = metadata.to_s.html_safe From 3b94072b092a3ab3a54bb45ae9211ef9bea9833b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 Mar 2023 14:54:58 -0300 Subject: [PATCH 053/814] =?UTF-8?q?fix:=20mantener=20la=20numeraci=C3=B3n?= =?UTF-8?q?=20de=20items=20sutty/editor#85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 0458a290..e5e9af7b 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -203,7 +203,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_tags @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze + figcaption a sub sup small table thead tbody tfoot tr th td br code start].freeze end # Decifra el valor From 3aaf60489a7cf72520b345214e15dd1b46d39e6c Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 Mar 2023 14:56:50 -0300 Subject: [PATCH 054/814] feat: aceptar otros atributos de listas sutty/editor#85 --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index e5e9af7b..ca5b48e3 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -203,7 +203,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_tags @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td br code start].freeze + figcaption a sub sup small table thead tbody tfoot tr th td br code start type reversed].freeze end # Decifra el valor From 465d12a7f9d48521bc6303e9351794eba0b69a55 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 Mar 2023 17:20:09 -0300 Subject: [PATCH 055/814] feat: editor v0.1.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8e5a939..ca34b723 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.14", + "@suttyweb/editor": "^0.1.15", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From 5bdcaef73887529ad2be6f0638bcf7ef42527b9c Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 Mar 2023 17:21:50 -0300 Subject: [PATCH 056/814] feat: descargar archivos remotos sutty/editor#62 --- .../disk_controller_decorator.rb | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/app/controllers/active_storage/disk_controller_decorator.rb b/app/controllers/active_storage/disk_controller_decorator.rb index 0634a2ec..e49c22f1 100644 --- a/app/controllers/active_storage/disk_controller_decorator.rb +++ b/app/controllers/active_storage/disk_controller_decorator.rb @@ -21,11 +21,26 @@ module ActiveStorage def update if (token = decode_verified_token) if acceptable_content?(token) - named_disk_service(token[:service_name]).upload token[:key], request.body, checksum: token[:checksum] - blob = ActiveStorage::Blob.find_by_key token[:key] site = Site.find_by_name token[:service_name] + if remote_file?(token) + begin + url = request.body.read + body = Down.download(url, max_size: 111.megabytes) + checksum = nil + rescue StandardError => e + ExceptionNotifier.notify_exception(e, data: { key: token[:key], url: url, site: site.name }) + + head :content_too_large + end + else + body = request.body + checksum = token[:checksum] + end + + named_disk_service(token[:service_name]).upload token[:key], body, checksum: checksum + site.static_files.attach(blob) else head :unprocessable_entity @@ -36,6 +51,12 @@ module ActiveStorage rescue ActiveStorage::IntegrityError head :unprocessable_entity end + + private + + def remote_file?(token) + token[:content_type] == 'sutty/download-from-url' + end end end end From e8678d6fdf7042f4a36f6fb2fd1d0b8b9f77f4d9 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 Mar 2023 17:43:27 -0300 Subject: [PATCH 057/814] feat: editor 0.1.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ca34b723..df1bc15e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.15", + "@suttyweb/editor": "^0.1.16", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From 30a70e9308c4e04e6250871b86c9176582ebb4b3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 Mar 2023 18:03:34 -0300 Subject: [PATCH 058/814] =?UTF-8?q?fix:=20cambi=C3=B3=20la=20ruta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/etc/new_editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/etc/new_editor.js b/app/javascript/etc/new_editor.js index 0a7842ae..dbc87bbc 100644 --- a/app/javascript/etc/new_editor.js +++ b/app/javascript/etc/new_editor.js @@ -1,6 +1,6 @@ import SuttyEditor from "@suttyweb/editor"; -import "@suttyweb/editor/dist/editor.css"; +import "@suttyweb/editor/dist/style.css"; document.addEventListener("turbolinks:load", () => { document.querySelectorAll(".new-editor").forEach((editorContainer) => { From 4b6b422f958e1894d8aeea3e79e002e8eba409fb Mon Sep 17 00:00:00 2001 From: f Date: Mon, 3 Apr 2023 16:34:35 -0300 Subject: [PATCH 059/814] BREAKING CHANGE: clonar el skel en la rama de la plantilla #12760 --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 4b2a8eb9..d0557f78 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -470,7 +470,7 @@ class Site < ApplicationRecord def clone_skel! return if jekyll? - Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path + Rugged::Repository.clone_at(ENV['SKEL_SUTTY'], path, checkout_branch: design.gem) end # Elimina el directorio del sitio From 0cc36f2a1babc4ef5524448bf2c48eca68f85412 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 7 Apr 2023 14:24:47 -0300 Subject: [PATCH 060/814] =?UTF-8?q?fix:=20actualizar=20la=20informaci?= =?UTF-8?q?=C3=B3n=20y=20guardar=20la=20url=20#12971?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit para evitar que falle el trabajo de análisis --- app/controllers/active_storage/disk_controller_decorator.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/active_storage/disk_controller_decorator.rb b/app/controllers/active_storage/disk_controller_decorator.rb index e49c22f1..3e74fe1b 100644 --- a/app/controllers/active_storage/disk_controller_decorator.rb +++ b/app/controllers/active_storage/disk_controller_decorator.rb @@ -28,7 +28,9 @@ module ActiveStorage begin url = request.body.read body = Down.download(url, max_size: 111.megabytes) - checksum = nil + checksum = Digest::MD5.file(body.path).base64digest + blob.metadata[:url] = url + blob.update_columns checksum: checksum, byte_size: body.size, metadata: blob.metadata rescue StandardError => e ExceptionNotifier.notify_exception(e, data: { key: token[:key], url: url, site: site.name }) From 4442338a68a2f130f104b5b5fffdb8d54639440e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Mar 2023 14:57:30 -0300 Subject: [PATCH 061/814] feat: realizar la limpieza en segundo plano --- app/jobs/cleanup_job.rb | 8 ++++++++ lib/tasks/cleanup.rake | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 app/jobs/cleanup_job.rb diff --git a/app/jobs/cleanup_job.rb b/app/jobs/cleanup_job.rb new file mode 100644 index 00000000..13053cb0 --- /dev/null +++ b/app/jobs/cleanup_job.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Realiza tareas de limpieza en segundo plano +class CleanupJob < ApplicationJob + def perform(before = nil) + CleanupService.new(before: before).cleanup_everything! + end +end diff --git a/lib/tasks/cleanup.rake b/lib/tasks/cleanup.rake index e14693bc..1c52abaf 100644 --- a/lib/tasks/cleanup.rake +++ b/lib/tasks/cleanup.rake @@ -4,8 +4,6 @@ namespace :cleanup do desc 'Cleanup sites' task everything: :environment do before = ENV.fetch('BEFORE', '30').to_i.days.ago - service = CleanupService.new(before: before) - - service.cleanup_everything! + CleanupJob.perform_later(before) end end From d99f02bd0cd08558621ceaeed7e3b48b565d719b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Mar 2023 15:06:26 -0300 Subject: [PATCH 062/814] =?UTF-8?q?feat:=20informar=20qu=C3=A9=20se=20est?= =?UTF-8?q?=C3=A1=20haciendo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/cleanup_service.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/services/cleanup_service.rb b/app/services/cleanup_service.rb index ad87cf9a..01b42d9e 100644 --- a/app/services/cleanup_service.rb +++ b/app/services/cleanup_service.rb @@ -26,6 +26,8 @@ class CleanupService Site.where('updated_at < ?', before).find_each do |site| next unless File.directory? site.path + Rails.logger.info "Limpiando dependencias, archivos temporales y repositorio git de #{site.name}" + site.deploys.find_each(&:cleanup!) site.repository.gc @@ -40,6 +42,8 @@ class CleanupService Site.where('updated_at >= ?', before).find_each do |site| next unless File.directory? site.path + Rails.logger.info "Limpiando repositorio git de #{site.name}" + site.repository.gc site.touch end From 2fac95d2e8be45eeeea51bdbadbbae71bcd27224 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Mar 2023 15:06:46 -0300 Subject: [PATCH 063/814] =?UTF-8?q?fix:=20obtener=20los=20sitios=20ordenad?= =?UTF-8?q?os=20para=20ir=20actualiz=C3=A1ndolos=20en=20orden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/cleanup_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/cleanup_service.rb b/app/services/cleanup_service.rb index 01b42d9e..b0792159 100644 --- a/app/services/cleanup_service.rb +++ b/app/services/cleanup_service.rb @@ -23,7 +23,7 @@ class CleanupService # # @return [nil] def cleanup_older_sites! - Site.where('updated_at < ?', before).find_each do |site| + Site.where('updated_at < ?', before).order(updated_at: :desc).find_each do |site| next unless File.directory? site.path Rails.logger.info "Limpiando dependencias, archivos temporales y repositorio git de #{site.name}" @@ -39,7 +39,7 @@ class CleanupService # # @return [nil] def cleanup_newer_sites! - Site.where('updated_at >= ?', before).find_each do |site| + Site.where('updated_at >= ?', before).order(updated_at: :desc).find_each do |site| next unless File.directory? site.path Rails.logger.info "Limpiando repositorio git de #{site.name}" From cd7aa1d124c3e9b7ca7d9a182dec1fd3b7758608 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Mar 2023 15:10:53 -0300 Subject: [PATCH 064/814] =?UTF-8?q?fix:=20detectar=20cu=C3=A1ndo=20estamos?= =?UTF-8?q?=20en=20hainish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b2472035..fe2ab1bc 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,9 @@ # frozen_string_literal: true -puts 'Usa haini.sh para generar un entorno de trabajo reproducible' +if ENV['RAILS_ENV'] != 'production' && ENV['HAIN_ENV'].nil? + puts 'Usa haini.sh para generar un entorno de trabajo reproducible' +end + source 'https://gems.sutty.nl' ruby '~> 2.7' From ae7481550a3c6d92c0cbe34df6c2c72cbdcc94fd Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Mar 2023 15:12:10 -0300 Subject: [PATCH 065/814] feat: hacer limpieza de emergencia #12854 --- Procfile | 2 +- lib/tasks/cleanup.rake | 3 ++- monit.conf | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Procfile b/Procfile index 4cc6e5b3..14bdb0c5 100644 --- a/Procfile +++ b/Procfile @@ -8,4 +8,4 @@ prometheus: bundle exec prometheus_exporter -b 0.0.0.0 --prefix "sutty_" distributed_press_tokens_renew: bundle exec rake distributed_press:tokens:renew cleanup: bundle exec rake cleanup:everything stats: bundle exec rake stats:process_all -distributed_press_renew_tokens: bundle exec rake distributed_press:tokens:renew +emergency_cleanup: bundle exec rake cleanup:everything BEFORE=7 diff --git a/lib/tasks/cleanup.rake b/lib/tasks/cleanup.rake index 1c52abaf..20044871 100644 --- a/lib/tasks/cleanup.rake +++ b/lib/tasks/cleanup.rake @@ -2,8 +2,9 @@ namespace :cleanup do desc 'Cleanup sites' - task everything: :environment do + task everything: :environment do |_, args| before = ENV.fetch('BEFORE', '30').to_i.days.ago + CleanupJob.perform_later(before) end end diff --git a/monit.conf b/monit.conf index 0bd18907..b0aa9884 100644 --- a/monit.conf +++ b/monit.conf @@ -19,7 +19,6 @@ check program stats every "0 1 * * *" if status != 0 then alert -check program distributed_press_tokens_renew - with path "/usr/bin/foreman run -f /srv/Procfile -d /srv distributed_press_tokens_renew" as uid "rails" gid "www-data" - every "0 3 * * *" - if status != 0 then alert +check filesystem root with path / + if space usage > 80% for 5 times within 15 cycles then alert + if space usage > 90% for 5 cycles then exec "/usr/bin/foreman run -f /srv/Procfile -d /srv emergency_cleanup" as uid "rails" gid "www-data" From e504501678096249dea3f170ccede64c7f191cd2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 10 Apr 2023 19:24:40 -0300 Subject: [PATCH 066/814] fix: deshabilitar el modo oscuro #12994 hasta que lo podamos revisar mejor --- app/assets/stylesheets/application.scss | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index bba48558..06c0f8df 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -46,14 +46,6 @@ $sizes: ( --color: #{$magenta}; } -@media (prefers-color-scheme: dark) { - :root { - --foreground: #{$white}; - --background: #{$black}; - --color: #{$cyan}; - } -} - // TODO: Encontrar la forma de generar esto desde los locales de Rails $custom-file-text: ( en: 'Browse', From f041706bc7ccb78ed17681f99f4bb94f3c51d98c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 12 Apr 2023 12:28:03 -0300 Subject: [PATCH 067/814] feat: poder cambiar al tema oscuro en firefox --- app/assets/stylesheets/dark.scss | 9 +++++++++ app/views/layouts/application.html.haml | 1 + config/locales/en.yml | 1 + config/locales/es.yml | 1 + 4 files changed, 12 insertions(+) create mode 100644 app/assets/stylesheets/dark.scss diff --git a/app/assets/stylesheets/dark.scss b/app/assets/stylesheets/dark.scss new file mode 100644 index 00000000..9893c70b --- /dev/null +++ b/app/assets/stylesheets/dark.scss @@ -0,0 +1,9 @@ +$black: black; +$white: white; +$cyan: #13fefe; + +:root { + --foreground: #{$white}; + --background: #{$black}; + --color: #{$cyan}; +} diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 965a856f..a73c74d8 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -14,6 +14,7 @@ %script{ type: 'text/javascript', src: '/env.js' } = csrf_meta_tags = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' + = stylesheet_link_tag 'dark', rel: 'alternate stylesheet', media: 'all', 'data-turbolinks-track': 'reload', title: t('dark') = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' = stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' = favicon_link_tag 'sutty_cuadrada.png', rel: 'apple-touch-icon', type: 'image/png' diff --git a/config/locales/en.yml b/config/locales/en.yml index 3ddf681d..29f6bcbb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,4 +1,5 @@ en: + dark: Dark dir: ltr en: English es: Castellano diff --git a/config/locales/es.yml b/config/locales/es.yml index 01f1085c..c38a5ee0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,5 @@ es: + dark: Oscuro es: Castellano en: English es-AR: Castellano Rioplatense From d942d4355b31ed83718a87a4bfdcbf8f1749788d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 12 Apr 2023 13:08:16 -0300 Subject: [PATCH 068/814] feat: editor 0.1.22 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index df1bc15e..6a5d0446 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.16", + "@suttyweb/editor": "^0.1.22", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From 35ee19f6d839cae67a5fe5ef7394f3d8caf36c3c Mon Sep 17 00:00:00 2001 From: f Date: Sat, 15 Apr 2023 15:27:43 -0300 Subject: [PATCH 069/814] fix: editor 0.1.23 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a5d0446..4b81ff15 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.22", + "@suttyweb/editor": "^0.1.23", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From 9e348bfdd81a4b0acce2b660940245ed40b26267 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 19 Apr 2023 14:56:20 -0300 Subject: [PATCH 070/814] fix: los subdominios para los sitios vienen de un certificado wildcard #13159 --- app/controllers/api/v1/sites_controller.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/controllers/api/v1/sites_controller.rb b/app/controllers/api/v1/sites_controller.rb index ae64cf74..185d0b24 100644 --- a/app/controllers/api/v1/sites_controller.rb +++ b/app/controllers/api/v1/sites_controller.rb @@ -9,7 +9,7 @@ module Api # Lista de nombres de dominios a emitir certificados def index - render json: sites_names + alternative_names + api_names + www_names + render json: alternative_names + api_names + www_names end private @@ -18,13 +18,6 @@ module Api name.end_with?('.') ? name[0..-2] : "#{name}.#{Site.domain}" end - # Nombres de los sitios - def sites_names - Site.all.order(:name).pluck(:name).map do |name| - canonicalize name - end - end - # Dominios alternativos def alternative_names (DeployAlternativeDomain.all.map(&:hostname) + DeployLocalizedDomain.all.map(&:hostname)).map do |name| From 11fe98ecdc76a25f343414afde8dd1fa86d86c37 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 19 Apr 2023 14:56:56 -0300 Subject: [PATCH 071/814] fix: ignorar los subdominios en los dominios alternativos #13159 --- app/controllers/api/v1/sites_controller.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/controllers/api/v1/sites_controller.rb b/app/controllers/api/v1/sites_controller.rb index 185d0b24..05abc38a 100644 --- a/app/controllers/api/v1/sites_controller.rb +++ b/app/controllers/api/v1/sites_controller.rb @@ -18,10 +18,16 @@ module Api name.end_with?('.') ? name[0..-2] : "#{name}.#{Site.domain}" end + def subdomain?(name) + name.end_with? ".#{Site.domain}" + end + # Dominios alternativos def alternative_names (DeployAlternativeDomain.all.map(&:hostname) + DeployLocalizedDomain.all.map(&:hostname)).map do |name| canonicalize name + end.reject do |name| + subdomain? name end end @@ -34,6 +40,8 @@ module Api .or(Site.where(colaboracion_anonima: true)) .select("'api.' || name as name").map(&:name).map do |name| canonicalize name + end.reject do |name| + subdomain? name end end From 712514bc8c03b0ccd9f0289e3956aeddc8993c0b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 20 Apr 2023 18:11:43 -0300 Subject: [PATCH 072/814] feat: avisar que hay que publicar al cambiar la configuracion #13114 --- app/controllers/sites_controller.rb | 1 + app/views/layouts/_flash.haml | 2 +- config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index 63865e44..17287eb0 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -57,6 +57,7 @@ class SitesController < ApplicationController usuarie: current_usuarie) if service.update.valid? + flash[:notice] = I18n.t('sites.update.post') redirect_to site_posts_path(site, locale: site.default_locale) else render 'edit' diff --git a/app/views/layouts/_flash.haml b/app/views/layouts/_flash.haml index 7bd7ec0b..2d65ff78 100644 --- a/app/views/layouts/_flash.haml +++ b/app/views/layouts/_flash.haml @@ -1,4 +1,4 @@ - flash.each do |type, message| - unless type == 'js' = render 'bootstrap/alert' do - = message + = sanitize_markdown message, tags: %w[a strong em] diff --git a/config/locales/en.yml b/config/locales/en.yml index 3ddf681d..b37214e5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -402,6 +402,8 @@ en: title: 'Edit %{site}' submit: 'Save changes' btn: 'Configuration' + update: + post: "Your changes have been saved. **If you enabled a publication method, don't forget to publish changes.**" form: errors: title: There were errors and we couldn't save your changes :( diff --git a/config/locales/es.yml b/config/locales/es.yml index 01f1085c..aaff1a24 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -408,6 +408,8 @@ es: title: 'Editar %{site}' submit: 'Guardar cambios' btn: 'Configuración' + update: + post: "Tus cambios han sido guardados. **Si agregaste un método de publicación, no te olvides de publicar cambios.**" form: errors: title: Hubo errores y no pudimos guardar tus cambios :( From e9d33b625a8843f9fb9a20015b36045a4e7ba010 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 25 Apr 2023 14:51:54 -0300 Subject: [PATCH 073/814] =?UTF-8?q?feat:=20encontrar=20el=20post=20a=20par?= =?UTF-8?q?tir=20de=20su=20indexaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/indexed_post.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/models/indexed_post.rb b/app/models/indexed_post.rb index 7f6865f6..184cd05f 100644 --- a/app/models/indexed_post.rb +++ b/app/models/indexed_post.rb @@ -36,6 +36,15 @@ class IndexedPost < ApplicationRecord belongs_to :site + # Encuentra el post original + # + # @return [nil,Post] + def post + return if post_id.blank? + + @post ||= site.posts(lang: locale).find(post_id, uuid: true) + end + # Convertir locale a direccionario de PG # # @param [String,Symbol] From f38251af7a30ca65848c68971fe6aad10a7ef074 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Apr 2023 15:15:56 -0300 Subject: [PATCH 074/814] fix: permisos para posts indexados #13266 --- app/policies/indexed_post_policy.rb | 66 +++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 app/policies/indexed_post_policy.rb diff --git a/app/policies/indexed_post_policy.rb b/app/policies/indexed_post_policy.rb new file mode 100644 index 00000000..e0151c7a --- /dev/null +++ b/app/policies/indexed_post_policy.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# Política de acceso a artículos +class IndexedPostPolicy + attr_reader :indexed_post, :usuarie, :site + + def initialize(usuarie, indexed_post) + @usuarie = usuarie + @indexed_post = indexed_post + @site = indexed_post.site + end + + def index? + true + end + + # Les invitades solo pueden ver sus propios posts + def show? + site.usuarie?(usuarie) || site.indexed_posts.by_usuarie(usuarie.id).find_by_post_id(indexed_post.post_id).present? + end + + def preview? + show? + end + + def new? + create? + end + + def create? + true + end + + def edit? + update? + end + + # Les invitades solo pueden modificar sus propios artículos + def update? + show? + end + + # Solo las usuarias pueden eliminar artículos. Les invitades pueden + # borrar sus propios artículos + def destroy? + update? + end + + # Las usuarias pueden ver todos los posts + # + # Les invitades solo pueden ver sus propios posts + class Scope + attr_reader :usuarie, :scope + + def initialize(usuarie, scope) + @usuarie = usuarie + @scope = scope + end + + def resolve + return scope if scope&.first&.site&.usuarie? usuarie + + scope.by_usuarie(usuarie.id) + end + end +end From a9bce070e8753c28dc208e650366b30013f5d9fa Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Apr 2023 15:25:09 -0300 Subject: [PATCH 075/814] fix: temporalmente deshabilitar el cambio de plantillas #13260 --- app/views/sites/_form.haml | 59 +++++++++++++++++++------------------- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 69997ffa..0dcccbe3 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -46,36 +46,37 @@ .invalid-feedback= site.errors.messages[:description].join(', ') %hr/ - .form-group#design_id - %h2= t('.design.title') - %p.lead= t('.help.design') - - if invalid? site, :design_id - = render 'bootstrap/alert' do - = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', - layouts: site.incompatible_layouts.to_sentence) - .row.row-cols-1.row-cols-md-2.designs - -# Demasiado complejo para un f.collection_radio_buttons - - Design.all.order(priority: :desc).each do |design| - .design.col.d-flex.flex-column - .custom-control.custom-radio - = f.radio_button :design_id, design.id, - checked: design.id == site.design_id, - disabled: design.disabled, - required: true, class: 'custom-control-input' - = f.label "design_id_#{design.id}", design.name, - class: 'custom-control-label' - .flex-fill - = sanitize_markdown design.description, - tags: %w[p a strong em] + - unless site.persisted? + .form-group#design_id + %h2= t('.design.title') + %p.lead= t('.help.design') + - if invalid? site, :design_id + = render 'bootstrap/alert' do + = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', + layouts: site.incompatible_layouts.to_sentence) + .row.row-cols-1.row-cols-md-2.designs + -# Demasiado complejo para un f.collection_radio_buttons + - Design.all.order(priority: :desc).each do |design| + .design.col.d-flex.flex-column + .custom-control.custom-radio + = f.radio_button :design_id, design.id, + checked: design.id == site.design_id, + disabled: design.disabled, + required: true, class: 'custom-control-input' + = f.label "design_id_#{design.id}", design.name, + class: 'custom-control-label' + .flex-fill + = sanitize_markdown design.description, + tags: %w[p a strong em] - .btn-group{ role: 'group', 'aria-label': t('.design.actions') } - - if design.url - = link_to t('.design.url'), design.url, - target: '_blank', class: 'btn' - - if design.license - = link_to t('.design.license'), design.license, - target: '_blank', class: 'btn' - %hr/ + .btn-group{ role: 'group', 'aria-label': t('.design.actions') } + - if design.url + = link_to t('.design.url'), design.url, + target: '_blank', class: 'btn' + - if design.license + = link_to t('.design.license'), design.license, + target: '_blank', class: 'btn' + %hr/ .form-group.licenses#license_id %h2= t('.licencia.title') diff --git a/config/locales/en.yml b/config/locales/en.yml index 2628ffb1..1f46ffed 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -410,7 +410,7 @@ en: name: "The name of your site. It can only include numbers and letters." title: 'The title can be anything you want' description: 'You site description that appears in search engines. Between 50 and 160 characters.' - design: 'Select the design for your site. You can change it later. We add more designs from time to time!' + design: 'Select the design for your site. We add more designs from time to time!' licencia: 'Everything we publish has automatic copyright. This means nobody can use our works without explicit permission. By using licenses, we stablish conditions by which we want to share diff --git a/config/locales/es.yml b/config/locales/es.yml index 6ad61228..3630ea25 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -416,7 +416,7 @@ es: name: 'El nombre de tu sitio que formará parte de la dirección (**ejemplo**.sutty.nl). Solo puede contener letras minúsculas, números y guiones.' title: 'El título de tu sitio puede ser lo que quieras.' description: 'La descripción del sitio, que saldrá en buscadores. Entre 50 y 160 caracteres.' - design: 'Elegí el diseño que va a tener tu sitio aquí. Podés cambiarlo luego. De tanto en tanto vamos sumando diseños nuevos.' + design: 'Elegí el diseño que va a tener tu sitio aquí. De tanto en tanto vamos sumando diseños nuevos.' licencia: 'Todo lo que publicamos posee automáticamente derechos de autore. Esto significa que nadie puede hacer uso de nuestras obras sin permiso explícito. Con las licencias establecemos From 1839d48893ca278a71208d40c17f3ed4d009233a Mon Sep 17 00:00:00 2001 From: f Date: Sat, 29 Apr 2023 18:10:28 -0300 Subject: [PATCH 076/814] fix: permitir el atributo start #13321 --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 5de54be1..b324e71c 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -202,7 +202,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name].freeze + name start].freeze end def allowed_tags From e9fd650ba9c224330f88c4f4fde460d270a9fd29 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 16:08:21 -0300 Subject: [PATCH 077/814] fix: ignorar posts #13428 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit versiones de jekyll-locales menores a 0.2 dejan symlinks rotos en lugar de la colección _posts. con esto ignoramos la colección del todo, porque solo usamos las que están en idiomas. sutty obliga efectivamente a todos los sitios jekyll a usar jekyll-locales o al menos colocar los posts en un directorio de idiomas. una salvedad sería agregar esto en la configuración: ```yaml locales: - "posts" ``` --- config/initializers/core_extensions.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 1516a43a..abbdfda1 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -37,6 +37,19 @@ end # # TODO: Aplicar monkey patches en otro lado... module Jekyll + Configuration.class_eval do + # No agregar colecciones por defecto, solo las que digamos en base a + # los idiomas. Esto remueve la colección "posts". + # + # Las colecciones de idiomas son agregadas por Site. + # + # @see Site#configuration + # @return [Jekyll::Configuration] + def add_default_collections + self + end + end + Site.class_eval do def configure_theme self.theme = nil From e473de6a4ec515886b6fd172cc2ffa9d2abaafe4 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:31:40 -0300 Subject: [PATCH 078/814] fix: leer los archivos de datos correctamente #13428 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit los archivos de datos se leen con rutas relativas, lo que puede mezclar el cwd en usos concurrentes. depreca la dependencia en jekyll-data además! --- Gemfile | 2 +- Gemfile.lock | 3 -- .../jekyll/readers/data_reader_decorator.rb | 36 +++++++++++++++++++ app/models/site.rb | 4 +-- config/initializers/core_extensions.rb | 34 +++++++++++------- 5 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 app/lib/jekyll/readers/data_reader_decorator.rb diff --git a/Gemfile b/Gemfile index b2472035..5f1f6268 100644 --- a/Gemfile +++ b/Gemfile @@ -52,7 +52,7 @@ gem 'icalendar' gem 'inline_svg' gem 'httparty' gem 'safe_yaml' -gem 'jekyll', '~> 4.2' +gem 'jekyll', '~> 4.2.0' gem 'jekyll-data' gem 'jekyll-commonmark' gem 'jekyll-images' diff --git a/Gemfile.lock b/Gemfile.lock index 67ce13e2..951ae8c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -284,8 +284,6 @@ GEM jekyll-commonmark (1.3.2) commonmarker (~> 0.14, < 0.22) jekyll (>= 3.7, < 5.0) - jekyll-data (1.1.2) - jekyll (>= 3.3, < 5.0.0) jekyll-dotenv (0.2.0) dotenv (~> 2.7) jekyll (~> 4) @@ -644,7 +642,6 @@ DEPENDENCIES jbuilder (~> 2.5) jekyll (~> 4.2) jekyll-commonmark - jekyll-data jekyll-images jekyll-include-cache kaminari diff --git a/app/lib/jekyll/readers/data_reader_decorator.rb b/app/lib/jekyll/readers/data_reader_decorator.rb new file mode 100644 index 00000000..9fed7ac7 --- /dev/null +++ b/app/lib/jekyll/readers/data_reader_decorator.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Jekyll + module Readers + # Permite leer datos utilizando rutas absolutas. + # + # {Jekyll::DataReader} usa {Dir.chdir} con rutas relativas, lo que + # en nuestro uso provoca confusiones en el lector de datos. + # + # Con este módulo, podemos leer todos los archivos usando rutas + # absolutas, lo que nos permite reemplazar jekyll-data, que agregaba + # código duplicado. + module DataReaderDecorator + extend ActiveSupport::Concern + + included do + def read_data_to(dir, data) + return unless File.directory?(dir) && !@entry_filter.symlink?(dir) + + Dir.glob(File.join(dir, '*')).each do |path| + next if @entry_filter.symlink?(path) + + entry = Pathname.new(path).relative_path_from(dir).to_s + + if File.directory?(path) + read_data_to(path, data[sanitize_filename(entry)] = {}) + else + key = sanitize_filename(File.basename(entry, ".*")) + data[key] = read_data_file(path) + end + end + end + end + end + end +end diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..a6e1c541 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -375,9 +375,7 @@ class Site < ApplicationRecord begin install_gems - Jekyll::Site.new(configuration).tap do |site| - site.reader = JekyllData::Reader.new(site) if site.theme - end + Jekyll::Site.new(configuration) end end diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index abbdfda1..861491ae 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -2,6 +2,7 @@ String.include CoreExtensions::String::StripTags Jekyll::Document.include CoreExtensions::Jekyll::Document::Path +Jekyll::DataReader.include Jekyll::Readers::DataReaderDecorator # Definir tags de Liquid que provienen de complementos para que siempre # devuelvan contenido vacío. @@ -70,9 +71,27 @@ module Jekyll # No necesitamos los archivos estáticos def retrieve_static_files(_, _); end - # Solo lee los datos + # Solo lee los datos, desde la plantilla y luego desde el sitio, + # usando rutas absolutas, para evitar el uso confuso de Dir.chdir. + # + # Reemplaza jekyll-data también! + # + # @return [Hash] def read_data - @site.data = DataReader.new(site).read(site.config['data_dir']) + @site.data = + begin + reader = DataReader.new(site) + theme_dir = site.in_theme_dir('_data') + data_dir = site.in_source_dir(site.config['data_dir']) + + if theme_dir + reader.read_data_to(theme_dir, reader.content) + reader.read_data_to(data_dir, reader.content) + reader.content + else + reader.read data_dir + end + end end # Lee los layouts @@ -174,14 +193,3 @@ module PgSearch end end end - -# JekyllData::Reader del plugin jekyll-data modifica Jekyll::Site#reader -# para también leer los datos que vienen en el theme. -module JekyllData - Reader.class_eval do - def read_data - super - read_theme_data - end - end -end From 1c294d450ea40b636b05e6ce48f5f27b461faffb Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:38:39 -0300 Subject: [PATCH 079/814] fix: deprecar Site#run_in_path #13428 ya no es necesario y Dir.chdir no es concurrente, con lo que nos ahorramos posibles bugs. --- app/models/site.rb | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index a6e1c541..fb790fe8 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -212,10 +212,8 @@ class Site < ApplicationRecord # Trae los datos del directorio _data dentro del sitio def data unless jekyll.data.present? - run_in_path do - jekyll.reader.read_data - jekyll.data['layouts'] ||= {} - end + jekyll.reader.read_data + jekyll.data['layouts'] ||= {} end jekyll.data @@ -225,9 +223,7 @@ class Site < ApplicationRecord # colecciones. def collections unless @read - run_in_path do - jekyll.reader.read_collections - end + jekyll.reader.read_collections @read = true end @@ -322,9 +318,7 @@ class Site < ApplicationRecord # # @return [Hash] def theme_layouts - run_in_path do - jekyll.reader.read_layouts - end + jekyll.reader.read_layouts end # Trae todos los valores disponibles para un campo @@ -550,10 +544,6 @@ class Site < ApplicationRecord I18n.t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.error')) end - def run_in_path(&block) - Dir.chdir path, &block - end - # Instala las gemas cuando es necesario: # # * El sitio existe From 622d3b47db784249c08408b9ea042902c77b6192 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:41:00 -0300 Subject: [PATCH 080/814] BREAKING CHANGE: deprecar Deploy#gems_dir por Site#bundle_path #13428 --- app/models/deploy.rb | 5 ----- app/models/deploy_local.rb | 4 ++-- app/models/site.rb | 5 +++++ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index a92708c0..573fe2f0 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -50,11 +50,6 @@ class Deploy < ApplicationRecord site.path end - # XXX: Ver DeployLocal#bundle - def gems_dir - @gems_dir ||= Rails.root.join('_storage', 'gems', site.name) - end - # Corre un comando, lo registra en la base de datos y devuelve el # estado. # diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 75ea8b1c..b8885509 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -55,7 +55,7 @@ class DeployLocal < Deploy # # @return [nil] def cleanup! - FileUtils.rm_rf(gems_dir) + FileUtils.rm_rf(site.bundle_path) FileUtils.rm_rf(yarn_cache_dir) FileUtils.rm_rf(File.join(site.path, 'node_modules')) FileUtils.rm_rf(File.join(site.path, '.sass-cache')) @@ -138,7 +138,7 @@ class DeployLocal < Deploy end def bundle(output: false) - run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output + run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output end def jekyll_build(output: false) diff --git a/app/models/site.rb b/app/models/site.rb index fb790fe8..754f9df1 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -453,6 +453,11 @@ class Site < ApplicationRecord @docs = nil end + # @return [Pathname] + def bundle_path + @bundle_path ||= Rails.root.join('_storage', 'gems', name) + end + private # Asegurarse que el sitio tenga una llave privada From 310bd3171067012f909925a5560bda86cfd9e8e9 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:42:14 -0300 Subject: [PATCH 081/814] fix: no usar :send #13428 --- app/models/deploy_local.rb | 31 +++++++++++++++++-------------- app/models/site.rb | 5 +++-- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index b8885509..b5a15cfe 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -7,6 +7,18 @@ class DeployLocal < Deploy before_destroy :remove_destination! + def git_lfs(output: false) + run %(git lfs fetch), output: output + run %(git lfs checkout), output: output + end + + def bundle(output: false) + # XXX: Desde que ya no compartimos el directorio de gemas, tenemos + # que hacer limpieza después de instalar. + + run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output + end + # Realizamos la construcción del sitio usando Jekyll y un entorno # limpio para no pasarle secretos # @@ -114,9 +126,11 @@ class DeployLocal < Deploy File.exist? pnpm_lock end - def git_lfs(output: false) - run %(git lfs fetch), output: output - run %(git lfs checkout), output: output + def pnpm(output: false) + return true unless pnpm_lock? + + run %(pnpm config set store-dir "#{pnpm_cache_dir}"), output: output + run 'pnpm install --production', output: output end def gem(output: false) @@ -130,17 +144,6 @@ class DeployLocal < Deploy run 'yarn install --production', output: output end - def pnpm(output: false) - return true unless pnpm_lock? - - run %(pnpm config set store-dir "#{pnpm_cache_dir}"), output: output - run 'pnpm install --production', output: output - end - - def bundle(output: false) - run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output - end - def jekyll_build(output: false) run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}"), output: output end diff --git a/app/models/site.rb b/app/models/site.rb index 754f9df1..fab16b58 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -558,10 +558,11 @@ class Site < ApplicationRecord def install_gems return unless persisted? - deploys.find_by_type('DeployLocal').send(:git_lfs) + deploy_local = deploys.find_by_type('DeployLocal') + deploy_local.git_lfs if !gem_dir? || gemfile_updated? || gemfile_lock_updated? - deploys.find_by_type('DeployLocal').send(:bundle) + deploy_local.bundle touch end end From 8d9328cd66dd2979ae0d10c1e94b90c1ed42a0ce Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:42:37 -0300 Subject: [PATCH 082/814] =?UTF-8?q?fix:=20en=20algunos=20casos=20el=20dire?= =?UTF-8?q?ctorio=20exist=C3=ADa=20aunque=20vac=C3=ADo=20#13428?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index fab16b58..9bc2c7f4 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -561,15 +561,25 @@ class Site < ApplicationRecord deploy_local = deploys.find_by_type('DeployLocal') deploy_local.git_lfs - if !gem_dir? || gemfile_updated? || gemfile_lock_updated? + if !gems_installed? || gemfile_updated? || gemfile_lock_updated? deploy_local.bundle touch end end + def gem_path + @gem_path ||= + begin + ruby_version = Gem::Version.new(RUBY_VERSION) + ruby_version.canonical_segments[2] = 0 + + bundle_path.join('ruby', ruby_version.canonical_segments.join('.')) + end + end + # Detecta si el repositorio de gemas existe - def gem_dir? - Rails.root.join('_storage', 'gems', name).directory? + def gems_installed? + gem_path.directory? && !gem_path.empty? end # Detecta si el Gemfile fue modificado From 5d8c1556a8bbfb1e2762f2d233d4f14a97c1e8ea Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:43:02 -0300 Subject: [PATCH 083/814] fix: no fallar si no existe el Gemfile.lock #13428 --- app/models/site.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 9bc2c7f4..924b6069 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -587,8 +587,15 @@ class Site < ApplicationRecord updated_at < File.mtime(File.join(path, 'Gemfile')) end + # @return [String] + def gemfile_lock_path + @gemfile_lock_path ||= File.join(path, 'Gemfile.lock') + end + # Detecta si el Gemfile.lock fue modificado def gemfile_lock_updated? - updated_at < File.mtime(File.join(path, 'Gemfile.lock')) + return false unless File.exist? gemfile_lock_path + + updated_at < File.mtime(gemfile_lock_path) end end From dc20e4c9ce3e583b8542abda342f97d1fa7ec224 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:48:06 -0300 Subject: [PATCH 084/814] fix: permite instalar gemas por primera vez #13428 --- app/models/deploy_local.rb | 2 +- app/models/site.rb | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index b5a15cfe..4f8744f3 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -16,7 +16,7 @@ class DeployLocal < Deploy # XXX: Desde que ya no compartimos el directorio de gemas, tenemos # que hacer limpieza después de instalar. - run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output + run %(bundle install #{'--deployment' if site.gemfile_lock_path?} --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output end # Realizamos la construcción del sitio usando Jekyll y un entorno diff --git a/app/models/site.rb b/app/models/site.rb index 924b6069..786cb780 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -458,6 +458,10 @@ class Site < ApplicationRecord @bundle_path ||= Rails.root.join('_storage', 'gems', name) end + def gemfile_lock_path? + File.exist? gemfile_lock_path + end + private # Asegurarse que el sitio tenga una llave privada @@ -594,7 +598,7 @@ class Site < ApplicationRecord # Detecta si el Gemfile.lock fue modificado def gemfile_lock_updated? - return false unless File.exist? gemfile_lock_path + return false unless gemfile_lock_path? updated_at < File.mtime(gemfile_lock_path) end From b869a2a34eebb6ed9b3bb70dbb5b746cbb048f04 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 15:56:39 -0300 Subject: [PATCH 085/814] fix: poder informar errores con archivos subidos #13427 --- app/jobs/gitlab_notifier_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/gitlab_notifier_job.rb b/app/jobs/gitlab_notifier_job.rb index 575d57d8..b12e0821 100644 --- a/app/jobs/gitlab_notifier_job.rb +++ b/app/jobs/gitlab_notifier_job.rb @@ -32,7 +32,7 @@ class GitlabNotifierJob < ApplicationJob count: 1, issue: @issue['iid'], user_agents: [user_agent].compact, - params: [request&.filtered_parameters].compact, + params: request&.filtered_parameters&.as_json, urls: [url].compact } end @@ -194,7 +194,7 @@ class GitlabNotifierJob < ApplicationJob ``` #{request.request_method} #{url} - #{pp request.filtered_parameters} + #{pp request.filtered_parameters.as_json} ``` REQUEST From 068bed5c0ad58be73949dd9b01304db4295f7002 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 May 2023 14:34:24 -0300 Subject: [PATCH 086/814] Revert "deshabilitar el paginado temporalmente" This reverts commit 9c4a0a86f3eeec8f578e3872096896a710e01632. --- app/controllers/posts_controller.rb | 4 ++-- app/views/posts/index.haml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 9720fe13..21a6dc06 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -23,7 +23,7 @@ class PostsController < ApplicationController return unless stale?([current_usuarie, site, filter_params]) # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale) + @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) # De este tipo @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] # Que estén dentro de la categoría @@ -154,7 +154,7 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout).to_hash.select do |_, v| + @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select do |_, v| v.present? end.transform_keys(&:to_sym) end diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index e8c3dea7..470e9641 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -85,6 +85,8 @@ %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') %div + = link_to_prev_page @posts, t('posts.prev'), class: 'btn' + = link_to_next_page @posts, t('posts.next'), class: 'btn' %tbody - dir = @site.data.dig(params[:locale], 'dir') - size = @posts.size From 3540886554455ac1627b190327d32117e04bf129 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 May 2023 14:36:42 -0300 Subject: [PATCH 087/814] feat: poder paginar solo algunos sitios #12714 --- app/controllers/posts_controller.rb | 3 ++- app/views/posts/index.haml | 7 ++++--- db/migrate/20230519143500_add_pagination_to_site.rb | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20230519143500_add_pagination_to_site.rb diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 21a6dc06..057c3068 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -23,7 +23,8 @@ class PostsController < ApplicationController return unless stale?([current_usuarie, site, filter_params]) # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) + @posts = site.indexed_posts.where(locale: locale) + @posts = @posts.page(filter_params.delete(:page)) if site.pagination # De este tipo @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] # Que estén dentro de la categoría diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 470e9641..ae53aa7a 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -84,9 +84,10 @@ %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') - %div - = link_to_prev_page @posts, t('posts.prev'), class: 'btn' - = link_to_next_page @posts, t('posts.next'), class: 'btn' + - if @site.pagination + %div + = link_to_prev_page @posts, t('posts.prev'), class: 'btn' + = link_to_next_page @posts, t('posts.next'), class: 'btn' %tbody - dir = @site.data.dig(params[:locale], 'dir') - size = @posts.size diff --git a/db/migrate/20230519143500_add_pagination_to_site.rb b/db/migrate/20230519143500_add_pagination_to_site.rb new file mode 100644 index 00000000..776fa318 --- /dev/null +++ b/db/migrate/20230519143500_add_pagination_to_site.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Agrega la opción de paginación a los sitios +class AddPaginationToSites < ActiveRecord::Migration[6.1] + def change + add_column :sites, :pagination, :boolean, default: false + end +end From d0f7843fbf90ef936afe955b046d8cab1ee6f7d8 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 May 2023 14:40:42 -0300 Subject: [PATCH 088/814] fixup! feat: poder paginar solo algunos sitios #12714 --- db/migrate/20230519143500_add_pagination_to_site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230519143500_add_pagination_to_site.rb b/db/migrate/20230519143500_add_pagination_to_site.rb index 776fa318..387dc588 100644 --- a/db/migrate/20230519143500_add_pagination_to_site.rb +++ b/db/migrate/20230519143500_add_pagination_to_site.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Agrega la opción de paginación a los sitios -class AddPaginationToSites < ActiveRecord::Migration[6.1] +class AddPaginationToSite < ActiveRecord::Migration[6.1] def change add_column :sites, :pagination, :boolean, default: false end From 2d3f1746897029d2ea142062bdc38d862b6967a2 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 23 May 2023 18:33:50 -0300 Subject: [PATCH 089/814] feat: alt text --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2beb5589..2974a8b3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.23", + "@suttyweb/editor": "^0.1.24", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From e35bddf915ea332c0a169556d581d41744b6f0ad Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 10:04:22 -0300 Subject: [PATCH 090/814] fix: no permitir que les usuaries elijan un idioma que no existe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit porque se les rompe el panel después --- app/models/usuarie.rb | 12 ++++++++++++ config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 2bc7a1b5..42f20c0b 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -10,6 +10,7 @@ class Usuarie < ApplicationRecord validates_uniqueness_of :email validates_with EmailAddress::ActiveRecordValidator, field: :email + validate :locale_available! before_create :lang_from_locale! before_update :remove_confirmation_invitation_inconsistencies! @@ -78,4 +79,15 @@ class Usuarie < ApplicationRecord self.invitation_accepted_at ||= Time.now.utc end end + + # Muestra un error si el idioma no está disponible al cambiar el + # idioma de la cuenta. + # + # @return [nil] + def locale_available! + return if I18n.locale_available? self.lang + + errors.add(:lang, I18n.t('activerecord.errors.models.usuarie.attributes.lang.not_available')) + nil + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..ab6a9305 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -194,6 +194,10 @@ en: layout_incompatible: error: "Design can't be changed because there are posts with incompatible layouts" help: "Your site has posts with layouts only compatible with the current design. If you change it, the site won't work as you expect. If you're trying out designs, you can delete posts in the following incompatible layouts:: %{layouts}." + usuarie: + attributes: + lang: + not_available: "This language is not yet available, would you help us by translating Sutty into it?" errors: argument_error: 'Argument `%{argument}` must be an instance of %{class}' unknown_locale: 'Unknown %{locale} locale' diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..e3c271da 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -194,6 +194,10 @@ es: layout_incompatible: error: 'No se puede cambiar la plantilla porque hay artículos con formatos incompatibles' help: 'En tu sitio hay artículos que solo son compatibles con el diseño actual, si cambias la plantilla el sitio no funcionará como esperas. Si estás probando plantillas, puedes eliminar los artículos en los formatos incompatibles: %{layouts}.' + usuarie: + attributes: + lang: + not_available: "Este idioma todavía no está disponible, ¿nos ayudas a agregarlo y mantenerlo?" errors: argument_error: 'El argumento `%{argument}` debe ser una instancia de %{class}' unknown_locale: 'El idioma %{locale} es desconocido' From 4e002e042bc5b0e5c129ab8cac3df03cf340fefb Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 10:06:11 -0300 Subject: [PATCH 091/814] fix: no permitir idiomas que no existen en el cambio de idioma #13493 --- app/controllers/application_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ee153394..2746ab10 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -59,7 +59,11 @@ class ApplicationController < ActionController::Base # # @return [String,Symbol] def current_locale - session[:locale] = params[:change_locale_to] if params[:change_locale_to].present? + locale = params[:change_locale_to] + + if locale.present? && I18n.locale_available?(locale) + session[:locale] = params[:change_locale_to] + end session[:locale] || current_usuarie&.lang || I18n.locale end From 66a635fa4e44708365304e2d86b5116fc27642ab Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 10:45:39 -0300 Subject: [PATCH 092/814] fix: son atributos, no elementos sutty/editor#85 --- app/models/metadata_template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 3e974b18..823443d2 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -202,12 +202,12 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy class colspan rowspan role data-turbo].freeze + name rel target referrerpolicy class colspan rowspan role data-turbo start type reversed].freeze end def allowed_tags @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td br code start type reversed].freeze + figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze end # Decifra el valor From 9fd9e5fa4e3fd69b833bce22daed61b42a46e9d2 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 10:58:08 -0300 Subject: [PATCH 093/814] fix: deshabilitar la interfaz de orden para invitades #13439 --- app/views/posts/index.haml | 49 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index e8c3dea7..46fafa49 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -1,3 +1,10 @@ +- reorder_allowed = policy(site).reorder? +- if reorder_allowed + - reorder_controller = { controller: 'reorder' } + - reorder_target = { target: 'reorder.row' } +- else + - reorder_target = reorder_controller = {} + %main.row %aside.menu.col-md-3 = render 'sites/header', site: @site @@ -67,22 +74,23 @@ %h2= t('posts.empty') - else = form_tag site_posts_reorder_path, method: :post do - %input{ type: 'hidden', name: 'post[lang]', value: @locale } - %table.table{ data: { controller: 'reorder' } } + %table.table{ data: reorder_controller } %caption.sr-only= t('posts.caption') %thead %tr.sticky-top %th.border-0{ colspan: '4' } .d-flex.flex-row.justify-content-between %div - = submit_tag t('posts.reorder.submit'), class: 'btn' - %button.btn{ data: { action: 'reorder#unselect' } } - = t('posts.reorder.unselect') - %span.badge{ data: { target: 'reorder.counter' } } 0 - %button.btn{ data: { action: 'reorder#up' } }= t('posts.reorder.up') - %button.btn{ data: { action: 'reorder#down' } }= t('posts.reorder.down') - %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') - %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') + - if reorder_allowed + = submit_tag t('posts.reorder.submit'), class: 'btn' + %button.btn{ data: { action: 'reorder#unselect' } } + = t('posts.reorder.unselect') + %span.badge{ data: { target: 'reorder.counter' } } 0 + %button.btn{ data: { action: 'reorder#up' } }= t('posts.reorder.up') + %button.btn{ data: { action: 'reorder#down' } }= t('posts.reorder.down') + %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') + %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') + %input{ type: 'hidden', name: 'post[lang]', value: @locale } %div %tbody @@ -94,16 +102,17 @@ les botones por permisos. - cache_if @usuarie, [post, I18n.locale] do - checkbox_id = "checkbox-#{post.post_id}" - %tr{ id: post.post_id, data: { target: 'reorder.row' } } - %td - .custom-control.custom-checkbox - %input.custom-control-input{ id: checkbox_id, type: 'checkbox', autocomplete: 'off', data: { action: 'reorder#select' } } - %label.custom-control-label{ for: checkbox_id } - %span.sr-only= t('posts.reorder.select') - -# Orden más alto es mayor prioridad - = hidden_field 'post[reorder]', post.post_id, - value: size - i, - data: { reorder: true } + %tr{ id: post.post_id, data: reorder_target } + - if reorder_allowed + %td + .custom-control.custom-checkbox + %input.custom-control-input{ id: checkbox_id, type: 'checkbox', autocomplete: 'off', data: { action: 'reorder#select' } } + %label.custom-control-label{ for: checkbox_id } + %span.sr-only= t('posts.reorder.select') + -# Orden más alto es mayor prioridad + = hidden_field 'post[reorder]', post.post_id, + value: size - i, + data: { reorder: true } %td.w-100{ class: dir } = link_to site_post_path(@site, post.path) do %span{ lang: post.locale, dir: dir }= post.title From 2a983778b48534f4fedd010965e00f8079d1ffe9 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 11:41:16 -0300 Subject: [PATCH 094/814] fixup! fix: deshabilitar la interfaz de orden para invitades #13439 --- app/views/posts/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 46fafa49..6108a208 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -1,4 +1,4 @@ -- reorder_allowed = policy(site).reorder? +- reorder_allowed = policy(@site).reorder? - if reorder_allowed - reorder_controller = { controller: 'reorder' } - reorder_target = { target: 'reorder.row' } From 28b74492f0d6ec60eaaf7545e36cfb425e5ffeaf Mon Sep 17 00:00:00 2001 From: Sutty Date: Tue, 16 May 2023 16:38:49 +0000 Subject: [PATCH 095/814] =?UTF-8?q?fix:=20dump=20de=20producci=C3=B3n=20#1?= =?UTF-8?q?3498?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/application.rb | 2 + db/schema.rb | 400 -------- db/structure.sql | 2267 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2269 insertions(+), 400 deletions(-) delete mode 100644 db/schema.rb create mode 100644 db/structure.sql diff --git a/config/application.rb b/config/application.rb index 057a22d3..606ccaf4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -45,6 +45,8 @@ module Sutty config.active_storage.queues.purge = :default config.active_job.queue_adapter = :que + config.active_record.schema_format = :sql + config.to_prepare do # Load application's model / class decorators Dir.glob(File.join(File.dirname(__FILE__), '..', 'app', '**', '*_decorator.rb')).sort.each do |c| diff --git a/db/schema.rb b/db/schema.rb deleted file mode 100644 index fd82d447..00000000 --- a/db/schema.rb +++ /dev/null @@ -1,400 +0,0 @@ -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# This file is the source Rails uses to define your schema when running `bin/rails -# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to -# be faster and is potentially less error prone than running all of your -# migrations from scratch. Old migrations may fail to apply correctly if those -# migrations use external dependencies or application code. -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema.define(version: 2023_04_15_153231) do - - # These are extensions that must be enabled in order to support this database - enable_extension "pg_trgm" - enable_extension "pgcrypto" - enable_extension "plpgsql" - - create_table "access_logs", id: :uuid, default: nil, force: :cascade do |t| - t.string "host" - t.float "msec" - t.string "server_protocol" - t.string "request_method" - t.string "request_completion" - t.string "uri" - t.string "query_string" - t.integer "status" - t.string "sent_http_content_type" - t.string "sent_http_content_encoding" - t.string "sent_http_etag" - t.string "sent_http_last_modified" - t.string "http_accept" - t.string "http_accept_encoding" - t.string "http_accept_language" - t.string "http_pragma" - t.string "http_cache_control" - t.string "http_if_none_match" - t.string "http_dnt" - t.string "http_user_agent" - t.string "http_origin" - t.float "request_time" - t.integer "bytes_sent" - t.integer "body_bytes_sent" - t.integer "request_length" - t.string "http_connection" - t.string "pipe" - t.integer "connection_requests" - t.string "geoip2_data_country_name" - t.string "geoip2_data_city_name" - t.string "ssl_server_name" - t.string "ssl_protocol" - t.string "ssl_early_data" - t.string "ssl_session_reused" - t.string "ssl_curves" - t.string "ssl_ciphers" - t.string "ssl_cipher" - t.string "sent_http_x_xss_protection" - t.string "sent_http_x_frame_options" - t.string "sent_http_x_content_type_options" - t.string "sent_http_strict_transport_security" - t.string "nginx_version" - t.integer "pid" - t.string "remote_user" - t.boolean "crawler", default: false - t.string "http_referer" - t.datetime "created_at", precision: 6 - t.index ["geoip2_data_city_name"], name: "index_access_logs_on_geoip2_data_city_name" - t.index ["geoip2_data_country_name"], name: "index_access_logs_on_geoip2_data_country_name" - t.index ["host"], name: "index_access_logs_on_host" - t.index ["http_origin"], name: "index_access_logs_on_http_origin" - t.index ["http_user_agent"], name: "index_access_logs_on_http_user_agent" - t.index ["status"], name: "index_access_logs_on_status" - t.index ["uri"], name: "index_access_logs_on_uri" - end - - create_table "action_text_rich_texts", force: :cascade do |t| - t.string "name", null: false - t.text "body" - t.string "record_type", null: false - t.bigint "record_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true - end - - create_table "active_storage_attachments", force: :cascade do |t| - t.string "name", null: false - t.string "record_type", null: false - t.bigint "record_id", null: false - t.bigint "blob_id", null: false - t.datetime "created_at", null: false - t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" - t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true - end - - create_table "active_storage_blobs", force: :cascade do |t| - t.string "key", null: false - t.string "filename", null: false - t.string "content_type" - t.text "metadata" - t.bigint "byte_size", null: false - t.string "checksum", null: false - t.datetime "created_at", null: false - t.string "service_name", null: false - t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true - end - - create_table "active_storage_variant_records", force: :cascade do |t| - t.bigint "blob_id", null: false - t.string "variation_digest", null: false - t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true - end - - create_table "blazer_audits", force: :cascade do |t| - t.bigint "user_id" - t.bigint "query_id" - t.text "statement" - t.string "data_source" - t.datetime "created_at" - t.index ["query_id"], name: "index_blazer_audits_on_query_id" - t.index ["user_id"], name: "index_blazer_audits_on_user_id" - end - - create_table "blazer_checks", force: :cascade do |t| - t.bigint "creator_id" - t.bigint "query_id" - t.string "state" - t.string "schedule" - t.text "emails" - t.text "slack_channels" - t.string "check_type" - t.text "message" - t.datetime "last_run_at" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["creator_id"], name: "index_blazer_checks_on_creator_id" - t.index ["query_id"], name: "index_blazer_checks_on_query_id" - end - - create_table "blazer_dashboard_queries", force: :cascade do |t| - t.bigint "dashboard_id" - t.bigint "query_id" - t.integer "position" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["dashboard_id"], name: "index_blazer_dashboard_queries_on_dashboard_id" - t.index ["query_id"], name: "index_blazer_dashboard_queries_on_query_id" - end - - create_table "blazer_dashboards", force: :cascade do |t| - t.bigint "creator_id" - t.text "name" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["creator_id"], name: "index_blazer_dashboards_on_creator_id" - end - - create_table "blazer_queries", force: :cascade do |t| - t.bigint "creator_id" - t.string "name" - t.text "description" - t.text "statement" - t.string "data_source" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["creator_id"], name: "index_blazer_queries_on_creator_id" - end - - create_table "build_stats", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.bigint "deploy_id" - t.bigint "bytes" - t.float "seconds" - t.string "action", null: false - t.text "log" - t.boolean "status", default: false - t.index ["deploy_id"], name: "index_build_stats_on_deploy_id" - end - - create_table "csp_reports", id: :uuid, default: nil, force: :cascade do |t| - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.string "disposition" - t.string "referrer" - t.string "blocked_uri" - t.string "document_uri" - t.string "effective_directive" - t.string "original_policy" - t.string "script_sample" - t.string "status_code" - t.string "violated_directive" - t.integer "column_number" - t.integer "line_number" - t.string "source_file" - end - - create_table "deploys", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.bigint "site_id" - t.string "type" - t.text "values" - t.index ["site_id"], name: "index_deploys_on_site_id" - t.index ["type"], name: "index_deploys_on_type" - end - - create_table "designs", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" - t.text "description" - t.string "gem" - t.string "url" - t.string "license" - t.boolean "disabled", default: false - t.text "credits" - t.string "designer_url" - t.integer "priority" - end - - create_table "indexed_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.bigint "site_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.string "locale", default: "simple" - t.string "layout", null: false - t.string "path", null: false - t.string "title", default: "" - t.jsonb "front_matter", default: "{}" - t.string "content", default: "" - t.tsvector "indexed_content" - t.integer "order", default: 0 - t.string "dictionary" - t.index ["front_matter"], name: "index_indexed_posts_on_front_matter", using: :gin - t.index ["indexed_content"], name: "index_indexed_posts_on_indexed_content", using: :gin - t.index ["layout"], name: "index_indexed_posts_on_layout" - t.index ["locale"], name: "index_indexed_posts_on_locale" - t.index ["site_id"], name: "index_indexed_posts_on_site_id" - end - - create_table "licencias", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" - t.text "description" - t.text "deed" - t.string "url" - t.string "icons" - end - - create_table "log_entries", force: :cascade do |t| - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.bigint "site_id" - t.text "text" - t.boolean "sent", default: false - t.index ["site_id"], name: "index_log_entries_on_site_id" - end - - create_table "maintenances", force: :cascade do |t| - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.text "message" - t.datetime "estimated_from" - t.datetime "estimated_to" - t.boolean "are_we_back", default: false - end - - create_table "mobility_string_translations", force: :cascade do |t| - t.string "locale", null: false - t.string "key", null: false - t.string "value" - t.string "translatable_type" - t.bigint "translatable_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["translatable_id", "translatable_type", "key"], name: "index_mobility_string_translations_on_translatable_attribute" - t.index ["translatable_id", "translatable_type", "locale", "key"], name: "index_mobility_string_translations_on_keys", unique: true - t.index ["translatable_type", "key", "value", "locale"], name: "index_mobility_string_translations_on_query_keys" - end - - create_table "mobility_text_translations", force: :cascade do |t| - t.string "locale", null: false - t.string "key", null: false - t.text "value" - t.string "translatable_type" - t.bigint "translatable_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["translatable_id", "translatable_type", "key"], name: "index_mobility_text_translations_on_translatable_attribute" - t.index ["translatable_id", "translatable_type", "locale", "key"], name: "index_mobility_text_translations_on_keys", unique: true - end - - create_table "roles", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.bigint "site_id" - t.bigint "usuarie_id" - t.string "rol" - t.boolean "temporal" - t.index ["site_id", "usuarie_id"], name: "index_roles_on_site_id_and_usuarie_id", unique: true - t.index ["site_id"], name: "index_roles_on_site_id" - t.index ["usuarie_id"], name: "index_roles_on_usuarie_id" - end - - create_table "rollups", force: :cascade do |t| - t.string "name", null: false - t.string "interval", null: false - t.datetime "time", null: false - t.jsonb "dimensions", default: {}, null: false - t.float "value" - t.index ["name", "interval", "time", "dimensions"], name: "index_rollups_on_name_and_interval_and_time_and_dimensions", unique: true - end - - create_table "sites", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" - t.bigint "design_id" - t.bigint "licencia_id" - t.string "status", default: "waiting" - t.text "description" - t.string "title" - t.boolean "colaboracion_anonima", default: false - t.boolean "contact", default: false - t.string "private_key_ciphertext" - t.boolean "acepta_invitades", default: false - t.string "tienda_api_key_ciphertext", default: "" - t.string "tienda_url", default: "" - t.string "api_key_ciphertext" - t.index ["design_id"], name: "index_sites_on_design_id" - t.index ["licencia_id"], name: "index_sites_on_licencia_id" - t.index ["name"], name: "index_sites_on_name", unique: true - end - - create_table "stats", force: :cascade do |t| - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.bigint "site_id" - t.string "name", null: false - t.index ["name"], name: "index_stats_on_name", using: :hash - t.index ["site_id"], name: "index_stats_on_site_id" - end - - create_table "usuaries", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" - t.integer "failed_attempts", default: 0, null: false - t.string "unlock_token" - t.datetime "locked_at" - t.boolean "acepta_politicas_de_privacidad", default: false - t.string "invitation_token" - t.datetime "invitation_created_at" - t.datetime "invitation_sent_at" - t.datetime "invitation_accepted_at" - t.integer "invitation_limit" - t.string "invited_by_type" - t.bigint "invited_by_id" - t.integer "invitations_count", default: 0 - t.string "lang", default: "es" - t.index ["confirmation_token"], name: "index_usuaries_on_confirmation_token", unique: true - t.index ["email"], name: "index_usuaries_on_email", unique: true - t.index ["invitation_token"], name: "index_usuaries_on_invitation_token", unique: true - t.index ["invitations_count"], name: "index_usuaries_on_invitations_count" - t.index ["invited_by_id"], name: "index_usuaries_on_invited_by_id" - t.index ["invited_by_type", "invited_by_id"], name: "index_usuaries_on_invited_by" - t.index ["reset_password_token"], name: "index_usuaries_on_reset_password_token", unique: true - t.index ["unlock_token"], name: "index_usuaries_on_unlock_token", unique: true - end - - add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" - add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" - - create_trigger("indexed_posts_before_insert_update_row_tr", :compatibility => 1). - on("indexed_posts"). - before(:insert, :update) do - <<-SQL_ACTIONS -new.indexed_content := to_tsvector(('pg_catalog.' || new.dictionary)::regconfig, coalesce(new.title, '') || ' -' || coalesce(new.content,'')); - SQL_ACTIONS - end - - create_trigger("access_logs_before_insert_row_tr", :compatibility => 1). - on("access_logs"). - before(:insert) do - "new.created_at := to_timestamp(new.msec);" - end - -end diff --git a/db/structure.sql b/db/structure.sql new file mode 100644 index 00000000..e50ae337 --- /dev/null +++ b/db/structure.sql @@ -0,0 +1,2267 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 15.2 +-- Dumped by pg_dump version 15.2 + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: public; Type: SCHEMA; Schema: -; Owner: - +-- + +-- *not* creating schema, since initdb creates it + + +-- +-- Name: dblink; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS dblink WITH SCHEMA public; + + +-- +-- Name: EXTENSION dblink; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION dblink IS 'connect to other PostgreSQL databases from within a database'; + + +-- +-- Name: pg_trgm; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public; + + +-- +-- Name: EXTENSION pg_trgm; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION pg_trgm IS 'text similarity measurement and index searching based on trigrams'; + + +-- +-- Name: pgcrypto; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public; + + +-- +-- Name: EXTENSION pgcrypto; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions'; + + +-- +-- Name: que_validate_tags(jsonb); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.que_validate_tags(tags_array jsonb) RETURNS boolean + LANGUAGE sql + AS $$ + SELECT bool_and( + jsonb_typeof(value) = 'string' + AND + char_length(value::text) <= 100 + ) + FROM jsonb_array_elements(tags_array) +$$; + + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: que_jobs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.que_jobs ( + priority smallint DEFAULT 100 NOT NULL, + run_at timestamp with time zone DEFAULT now() NOT NULL, + id bigint NOT NULL, + job_class text NOT NULL, + error_count integer DEFAULT 0 NOT NULL, + last_error_message text, + queue text DEFAULT 'default'::text NOT NULL, + last_error_backtrace text, + finished_at timestamp with time zone, + expired_at timestamp with time zone, + args jsonb DEFAULT '[]'::jsonb NOT NULL, + data jsonb DEFAULT '{}'::jsonb NOT NULL, + job_schema_version integer NOT NULL, + kwargs jsonb DEFAULT '{}'::jsonb NOT NULL, + CONSTRAINT error_length CHECK (((char_length(last_error_message) <= 500) AND (char_length(last_error_backtrace) <= 10000))), + CONSTRAINT job_class_length CHECK ((char_length( +CASE job_class + WHEN 'ActiveJob::QueueAdapters::QueAdapter::JobWrapper'::text THEN ((args -> 0) ->> 'job_class'::text) + ELSE job_class +END) <= 200)), + CONSTRAINT queue_length CHECK ((char_length(queue) <= 100)), + CONSTRAINT valid_args CHECK ((jsonb_typeof(args) = 'array'::text)), + CONSTRAINT valid_data CHECK (((jsonb_typeof(data) = 'object'::text) AND ((NOT (data ? 'tags'::text)) OR ((jsonb_typeof((data -> 'tags'::text)) = 'array'::text) AND (jsonb_array_length((data -> 'tags'::text)) <= 5) AND public.que_validate_tags((data -> 'tags'::text)))))) +) +WITH (fillfactor='90'); + + +-- +-- Name: TABLE que_jobs; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.que_jobs IS '7'; + + +-- +-- Name: access_logs_before_insert_row_tr(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.access_logs_before_insert_row_tr() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + new.created_at := to_timestamp(new.msec); + RETURN NEW; +END; +$$; + + +-- +-- Name: indexed_posts_before_insert_update_row_tr(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.indexed_posts_before_insert_update_row_tr() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + new.indexed_content := to_tsvector(('pg_catalog.' || new.dictionary)::regconfig, coalesce(new.title, '') || ' + ' || coalesce(new.content,'')); + RETURN NEW; +END; +$$; + + +-- +-- Name: que_determine_job_state(public.que_jobs); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.que_determine_job_state(job public.que_jobs) RETURNS text + LANGUAGE sql + AS $$ + SELECT + CASE + WHEN job.expired_at IS NOT NULL THEN 'expired' + WHEN job.finished_at IS NOT NULL THEN 'finished' + WHEN job.error_count > 0 THEN 'errored' + WHEN job.run_at > CURRENT_TIMESTAMP THEN 'scheduled' + ELSE 'ready' + END +$$; + + +-- +-- Name: que_job_notify(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.que_job_notify() RETURNS trigger + LANGUAGE plpgsql + AS $$ + DECLARE + locker_pid integer; + sort_key json; + BEGIN + -- Don't do anything if the job is scheduled for a future time. + IF NEW.run_at IS NOT NULL AND NEW.run_at > now() THEN + RETURN null; + END IF; + + -- Pick a locker to notify of the job's insertion, weighted by their number + -- of workers. Should bounce pseudorandomly between lockers on each + -- invocation, hence the md5-ordering, but still touch each one equally, + -- hence the modulo using the job_id. + SELECT pid + INTO locker_pid + FROM ( + SELECT *, last_value(row_number) OVER () + 1 AS count + FROM ( + SELECT *, row_number() OVER () - 1 AS row_number + FROM ( + SELECT * + FROM public.que_lockers ql, generate_series(1, ql.worker_count) AS id + WHERE + listening AND + queues @> ARRAY[NEW.queue] AND + ql.job_schema_version = NEW.job_schema_version + ORDER BY md5(pid::text || id::text) + ) t1 + ) t2 + ) t3 + WHERE NEW.id % count = row_number; + + IF locker_pid IS NOT NULL THEN + -- There's a size limit to what can be broadcast via LISTEN/NOTIFY, so + -- rather than throw errors when someone enqueues a big job, just + -- broadcast the most pertinent information, and let the locker query for + -- the record after it's taken the lock. The worker will have to hit the + -- DB in order to make sure the job is still visible anyway. + SELECT row_to_json(t) + INTO sort_key + FROM ( + SELECT + 'job_available' AS message_type, + NEW.queue AS queue, + NEW.priority AS priority, + NEW.id AS id, + -- Make sure we output timestamps as UTC ISO 8601 + to_char(NEW.run_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"') AS run_at + ) t; + + PERFORM pg_notify('que_listener_' || locker_pid::text, sort_key::text); + END IF; + + RETURN null; + END +$$; + + +-- +-- Name: que_state_notify(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.que_state_notify() RETURNS trigger + LANGUAGE plpgsql + AS $$ + DECLARE + row record; + message json; + previous_state text; + current_state text; + BEGIN + IF TG_OP = 'INSERT' THEN + previous_state := 'nonexistent'; + current_state := public.que_determine_job_state(NEW); + row := NEW; + ELSIF TG_OP = 'DELETE' THEN + previous_state := public.que_determine_job_state(OLD); + current_state := 'nonexistent'; + row := OLD; + ELSIF TG_OP = 'UPDATE' THEN + previous_state := public.que_determine_job_state(OLD); + current_state := public.que_determine_job_state(NEW); + + -- If the state didn't change, short-circuit. + IF previous_state = current_state THEN + RETURN null; + END IF; + + row := NEW; + ELSE + RAISE EXCEPTION 'Unrecognized TG_OP: %', TG_OP; + END IF; + + SELECT row_to_json(t) + INTO message + FROM ( + SELECT + 'job_change' AS message_type, + row.id AS id, + row.queue AS queue, + + coalesce(row.data->'tags', '[]'::jsonb) AS tags, + + to_char(row.run_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"') AS run_at, + to_char(now() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"') AS time, + + CASE row.job_class + WHEN 'ActiveJob::QueueAdapters::QueAdapter::JobWrapper' THEN + coalesce( + row.args->0->>'job_class', + 'ActiveJob::QueueAdapters::QueAdapter::JobWrapper' + ) + ELSE + row.job_class + END AS job_class, + + previous_state AS previous_state, + current_state AS current_state + ) t; + + PERFORM pg_notify('que_state', message::text); + + RETURN null; + END +$$; + + +-- +-- Name: access_logs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.access_logs ( + id uuid DEFAULT public.gen_random_uuid() NOT NULL, + host character varying, + msec double precision, + server_protocol character varying, + request_method character varying, + request_completion character varying, + uri character varying, + query_string character varying, + status integer, + sent_http_content_type character varying, + sent_http_content_encoding character varying, + sent_http_etag character varying, + sent_http_last_modified character varying, + http_accept character varying, + http_accept_encoding character varying, + http_accept_language character varying, + http_pragma character varying, + http_cache_control character varying, + http_if_none_match character varying, + http_dnt character varying, + http_user_agent character varying, + http_origin character varying, + request_time double precision, + bytes_sent integer, + body_bytes_sent integer, + request_length integer, + http_connection character varying, + pipe character varying, + connection_requests integer, + geoip2_data_country_name character varying, + geoip2_data_city_name character varying, + ssl_server_name character varying, + ssl_protocol character varying, + ssl_early_data character varying, + ssl_session_reused character varying, + ssl_curves character varying, + ssl_ciphers character varying, + ssl_cipher character varying, + sent_http_x_xss_protection character varying, + sent_http_x_frame_options character varying, + sent_http_x_content_type_options character varying, + sent_http_strict_transport_security character varying, + nginx_version character varying, + pid integer, + remote_user character varying, + crawler boolean DEFAULT false, + http_referer character varying, + created_at timestamp(6) without time zone, + request_uri character varying DEFAULT ''::character varying, + datacenter_co2 numeric, + network_co2 numeric, + consumer_device_co2 numeric, + production_co2 numeric, + total_co2 numeric, + node character varying +); + + +-- +-- Name: action_text_rich_texts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.action_text_rich_texts ( + id bigint NOT NULL, + name character varying NOT NULL, + body text, + record_type character varying NOT NULL, + record_id integer NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: action_text_rich_texts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.action_text_rich_texts_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: action_text_rich_texts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.action_text_rich_texts_id_seq OWNED BY public.action_text_rich_texts.id; + + +-- +-- Name: active_storage_attachments; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_storage_attachments ( + id bigint NOT NULL, + name character varying NOT NULL, + record_type character varying NOT NULL, + record_id integer NOT NULL, + blob_id integer NOT NULL, + created_at timestamp without time zone NOT NULL +); + + +-- +-- Name: active_storage_attachments_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_storage_attachments_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: active_storage_attachments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_storage_attachments_id_seq OWNED BY public.active_storage_attachments.id; + + +-- +-- Name: active_storage_blobs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_storage_blobs ( + id bigint NOT NULL, + key character varying NOT NULL, + filename character varying NOT NULL, + content_type character varying, + metadata text, + byte_size bigint NOT NULL, + checksum character varying NOT NULL, + created_at timestamp without time zone NOT NULL, + service_name character varying NOT NULL +); + + +-- +-- Name: active_storage_blobs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_storage_blobs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: active_storage_blobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_storage_blobs_id_seq OWNED BY public.active_storage_blobs.id; + + +-- +-- Name: active_storage_variant_records; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.active_storage_variant_records ( + id bigint NOT NULL, + blob_id bigint NOT NULL, + variation_digest character varying NOT NULL +); + + +-- +-- Name: active_storage_variant_records_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.active_storage_variant_records_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: active_storage_variant_records_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.active_storage_variant_records_id_seq OWNED BY public.active_storage_variant_records.id; + + +-- +-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.ar_internal_metadata ( + key character varying NOT NULL, + value character varying, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: blazer_audits; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.blazer_audits ( + id bigint NOT NULL, + user_id bigint, + query_id bigint, + statement text, + data_source character varying, + created_at timestamp without time zone +); + + +-- +-- Name: blazer_audits_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.blazer_audits_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: blazer_audits_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.blazer_audits_id_seq OWNED BY public.blazer_audits.id; + + +-- +-- Name: blazer_checks; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.blazer_checks ( + id bigint NOT NULL, + creator_id bigint, + query_id bigint, + state character varying, + schedule character varying, + emails text, + slack_channels text, + check_type character varying, + message text, + last_run_at timestamp without time zone, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: blazer_checks_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.blazer_checks_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: blazer_checks_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.blazer_checks_id_seq OWNED BY public.blazer_checks.id; + + +-- +-- Name: blazer_dashboard_queries; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.blazer_dashboard_queries ( + id bigint NOT NULL, + dashboard_id bigint, + query_id bigint, + "position" integer, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: blazer_dashboard_queries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.blazer_dashboard_queries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: blazer_dashboard_queries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.blazer_dashboard_queries_id_seq OWNED BY public.blazer_dashboard_queries.id; + + +-- +-- Name: blazer_dashboards; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.blazer_dashboards ( + id bigint NOT NULL, + creator_id bigint, + name text, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: blazer_dashboards_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.blazer_dashboards_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: blazer_dashboards_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.blazer_dashboards_id_seq OWNED BY public.blazer_dashboards.id; + + +-- +-- Name: blazer_queries; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.blazer_queries ( + id bigint NOT NULL, + creator_id bigint, + name character varying, + description text, + statement text, + data_source character varying, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: blazer_queries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.blazer_queries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: blazer_queries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.blazer_queries_id_seq OWNED BY public.blazer_queries.id; + + +-- +-- Name: build_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.build_stats ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + deploy_id integer, + bytes bigint, + seconds double precision, + action character varying NOT NULL, + log text, + status boolean DEFAULT false +); + + +-- +-- Name: build_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.build_stats_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: build_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.build_stats_id_seq OWNED BY public.build_stats.id; + + +-- +-- Name: codes_of_conduct; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.codes_of_conduct ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + title character varying, + description text, + content text +); + + +-- +-- Name: codes_of_conduct_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.codes_of_conduct_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: codes_of_conduct_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.codes_of_conduct_id_seq OWNED BY public.codes_of_conduct.id; + + +-- +-- Name: csp_reports; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.csp_reports ( + id uuid DEFAULT public.gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + disposition character varying, + referrer character varying, + blocked_uri character varying, + document_uri character varying, + effective_directive character varying, + original_policy character varying, + script_sample character varying, + status_code character varying, + violated_directive character varying, + column_number integer, + line_number integer, + source_file character varying +); + + +-- +-- Name: deploys; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.deploys ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + site_id integer, + type character varying, + "values" text +); + + +-- +-- Name: deploys_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.deploys_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: deploys_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.deploys_id_seq OWNED BY public.deploys.id; + + +-- +-- Name: designs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.designs ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + name character varying, + description text, + gem character varying, + url character varying, + license character varying, + disabled boolean DEFAULT false, + credits text, + designer_url character varying, + priority integer +); + + +-- +-- Name: designs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.designs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: designs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.designs_id_seq OWNED BY public.designs.id; + + +-- +-- Name: distributed_press_publishers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.distributed_press_publishers ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + instance character varying, + token_ciphertext text NOT NULL, + expires_at timestamp without time zone +); + + +-- +-- Name: distributed_press_publishers_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.distributed_press_publishers_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: distributed_press_publishers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.distributed_press_publishers_id_seq OWNED BY public.distributed_press_publishers.id; + + +-- +-- Name: indexed_posts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.indexed_posts ( + id uuid DEFAULT public.gen_random_uuid() NOT NULL, + site_id bigint, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + locale character varying DEFAULT 'simple'::character varying, + layout character varying NOT NULL, + path character varying NOT NULL, + title character varying DEFAULT ''::character varying, + front_matter jsonb DEFAULT '"{}"'::jsonb, + content character varying DEFAULT ''::character varying, + indexed_content tsvector, + "order" integer DEFAULT 0, + dictionary character varying, + post_id uuid +); + + +-- +-- Name: licencias; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.licencias ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + name character varying, + description text, + deed text, + url character varying, + icons character varying, + short_description character varying +); + + +-- +-- Name: licencias_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.licencias_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: licencias_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.licencias_id_seq OWNED BY public.licencias.id; + + +-- +-- Name: log_entries; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.log_entries ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + text text, + sent boolean DEFAULT false +); + + +-- +-- Name: log_entries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.log_entries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: log_entries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.log_entries_id_seq OWNED BY public.log_entries.id; + + +-- +-- Name: maintenances; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.maintenances ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + message text, + estimated_from timestamp without time zone, + estimated_to timestamp without time zone, + are_we_back boolean DEFAULT false +); + + +-- +-- Name: maintenances_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.maintenances_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: maintenances_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.maintenances_id_seq OWNED BY public.maintenances.id; + + +-- +-- Name: mobility_string_translations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.mobility_string_translations ( + id bigint NOT NULL, + locale character varying NOT NULL, + key character varying NOT NULL, + value character varying, + translatable_type character varying, + translatable_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: mobility_string_translations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.mobility_string_translations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: mobility_string_translations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.mobility_string_translations_id_seq OWNED BY public.mobility_string_translations.id; + + +-- +-- Name: mobility_text_translations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.mobility_text_translations ( + id bigint NOT NULL, + locale character varying NOT NULL, + key character varying NOT NULL, + value text, + translatable_type character varying, + translatable_id integer, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: mobility_text_translations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.mobility_text_translations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: mobility_text_translations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.mobility_text_translations_id_seq OWNED BY public.mobility_text_translations.id; + + +-- +-- Name: privacy_policies; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.privacy_policies ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + title character varying, + description text, + content text +); + + +-- +-- Name: privacy_policies_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.privacy_policies_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: privacy_policies_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.privacy_policies_id_seq OWNED BY public.privacy_policies.id; + + +-- +-- Name: que_jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.que_jobs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: que_jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.que_jobs_id_seq OWNED BY public.que_jobs.id; + + +-- +-- Name: que_lockers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE UNLOGGED TABLE public.que_lockers ( + pid integer NOT NULL, + worker_count integer NOT NULL, + worker_priorities integer[] NOT NULL, + ruby_pid integer NOT NULL, + ruby_hostname text NOT NULL, + queues text[] NOT NULL, + listening boolean NOT NULL, + job_schema_version integer DEFAULT 1, + CONSTRAINT valid_queues CHECK (((array_ndims(queues) = 1) AND (array_length(queues, 1) IS NOT NULL))), + CONSTRAINT valid_worker_priorities CHECK (((array_ndims(worker_priorities) = 1) AND (array_length(worker_priorities, 1) IS NOT NULL))) +); + + +-- +-- Name: que_values; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.que_values ( + key text NOT NULL, + value jsonb DEFAULT '{}'::jsonb NOT NULL, + CONSTRAINT valid_value CHECK ((jsonb_typeof(value) = 'object'::text)) +) +WITH (fillfactor='90'); + + +-- +-- Name: roles; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.roles ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + site_id integer, + usuarie_id integer, + rol character varying, + temporal boolean +); + + +-- +-- Name: roles_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.roles_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.roles_id_seq OWNED BY public.roles.id; + + +-- +-- Name: rollups; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.rollups ( + id bigint NOT NULL, + name character varying NOT NULL, + "interval" character varying NOT NULL, + "time" timestamp without time zone NOT NULL, + dimensions jsonb DEFAULT '{}'::jsonb NOT NULL, + value double precision +); + + +-- +-- Name: rollups_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.rollups_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: rollups_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.rollups_id_seq OWNED BY public.rollups.id; + + +-- +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.schema_migrations ( + version character varying NOT NULL +); + + +-- +-- Name: sites; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.sites ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + name character varying, + design_id integer, + licencia_id integer, + status character varying DEFAULT 'waiting'::character varying, + description text, + title character varying, + colaboracion_anonima boolean DEFAULT false, + contact boolean DEFAULT false, + private_key_ciphertext character varying, + acepta_invitades boolean DEFAULT false, + tienda_api_key_ciphertext character varying DEFAULT ''::character varying, + tienda_url character varying DEFAULT ''::character varying, + api_key_ciphertext character varying, + slugify_mode character varying DEFAULT 'default'::character varying +); + + +-- +-- Name: sites_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.sites_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: sites_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.sites_id_seq OWNED BY public.sites.id; + + +-- +-- Name: stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.stats ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + name character varying NOT NULL +); + + +-- +-- Name: stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.stats_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.stats_id_seq OWNED BY public.stats.id; + + +-- +-- Name: usuaries; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.usuaries ( + id bigint NOT NULL, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + email character varying DEFAULT ''::character varying NOT NULL, + encrypted_password character varying DEFAULT ''::character varying NOT NULL, + reset_password_token character varying, + reset_password_sent_at timestamp without time zone, + remember_created_at timestamp without time zone, + confirmation_token character varying, + confirmed_at timestamp without time zone, + confirmation_sent_at timestamp without time zone, + unconfirmed_email character varying, + failed_attempts integer DEFAULT 0 NOT NULL, + unlock_token character varying, + locked_at timestamp without time zone, + invitation_token character varying, + invitation_created_at timestamp without time zone, + invitation_sent_at timestamp without time zone, + invitation_accepted_at timestamp without time zone, + invitation_limit integer, + invited_by_type character varying, + invited_by_id integer, + invitations_count integer DEFAULT 0, + lang character varying DEFAULT 'es'::character varying, + privacy_policy_accepted_at timestamp without time zone, + terms_of_service_accepted_at timestamp without time zone, + code_of_conduct_accepted_at timestamp without time zone, + available_for_feedback_accepted_at timestamp without time zone +); + + +-- +-- Name: usuaries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.usuaries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: usuaries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.usuaries_id_seq OWNED BY public.usuaries.id; + + +-- +-- Name: action_text_rich_texts id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.action_text_rich_texts ALTER COLUMN id SET DEFAULT nextval('public.action_text_rich_texts_id_seq'::regclass); + + +-- +-- Name: active_storage_attachments id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_attachments ALTER COLUMN id SET DEFAULT nextval('public.active_storage_attachments_id_seq'::regclass); + + +-- +-- Name: active_storage_blobs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('public.active_storage_blobs_id_seq'::regclass); + + +-- +-- Name: active_storage_variant_records id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_variant_records ALTER COLUMN id SET DEFAULT nextval('public.active_storage_variant_records_id_seq'::regclass); + + +-- +-- Name: blazer_audits id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_audits ALTER COLUMN id SET DEFAULT nextval('public.blazer_audits_id_seq'::regclass); + + +-- +-- Name: blazer_checks id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_checks ALTER COLUMN id SET DEFAULT nextval('public.blazer_checks_id_seq'::regclass); + + +-- +-- Name: blazer_dashboard_queries id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_dashboard_queries ALTER COLUMN id SET DEFAULT nextval('public.blazer_dashboard_queries_id_seq'::regclass); + + +-- +-- Name: blazer_dashboards id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_dashboards ALTER COLUMN id SET DEFAULT nextval('public.blazer_dashboards_id_seq'::regclass); + + +-- +-- Name: blazer_queries id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_queries ALTER COLUMN id SET DEFAULT nextval('public.blazer_queries_id_seq'::regclass); + + +-- +-- Name: build_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.build_stats ALTER COLUMN id SET DEFAULT nextval('public.build_stats_id_seq'::regclass); + + +-- +-- Name: codes_of_conduct id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.codes_of_conduct ALTER COLUMN id SET DEFAULT nextval('public.codes_of_conduct_id_seq'::regclass); + + +-- +-- Name: deploys id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.deploys ALTER COLUMN id SET DEFAULT nextval('public.deploys_id_seq'::regclass); + + +-- +-- Name: designs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.designs ALTER COLUMN id SET DEFAULT nextval('public.designs_id_seq'::regclass); + + +-- +-- Name: distributed_press_publishers id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.distributed_press_publishers ALTER COLUMN id SET DEFAULT nextval('public.distributed_press_publishers_id_seq'::regclass); + + +-- +-- Name: licencias id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.licencias ALTER COLUMN id SET DEFAULT nextval('public.licencias_id_seq'::regclass); + + +-- +-- Name: log_entries id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.log_entries ALTER COLUMN id SET DEFAULT nextval('public.log_entries_id_seq'::regclass); + + +-- +-- Name: maintenances id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.maintenances ALTER COLUMN id SET DEFAULT nextval('public.maintenances_id_seq'::regclass); + + +-- +-- Name: mobility_string_translations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.mobility_string_translations ALTER COLUMN id SET DEFAULT nextval('public.mobility_string_translations_id_seq'::regclass); + + +-- +-- Name: mobility_text_translations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.mobility_text_translations ALTER COLUMN id SET DEFAULT nextval('public.mobility_text_translations_id_seq'::regclass); + + +-- +-- Name: privacy_policies id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.privacy_policies ALTER COLUMN id SET DEFAULT nextval('public.privacy_policies_id_seq'::regclass); + + +-- +-- Name: que_jobs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.que_jobs ALTER COLUMN id SET DEFAULT nextval('public.que_jobs_id_seq'::regclass); + + +-- +-- Name: roles id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.roles ALTER COLUMN id SET DEFAULT nextval('public.roles_id_seq'::regclass); + + +-- +-- Name: rollups id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.rollups ALTER COLUMN id SET DEFAULT nextval('public.rollups_id_seq'::regclass); + + +-- +-- Name: sites id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.sites ALTER COLUMN id SET DEFAULT nextval('public.sites_id_seq'::regclass); + + +-- +-- Name: stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.stats ALTER COLUMN id SET DEFAULT nextval('public.stats_id_seq'::regclass); + + +-- +-- Name: usuaries id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.usuaries ALTER COLUMN id SET DEFAULT nextval('public.usuaries_id_seq'::regclass); + + +-- +-- Name: access_logs access_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.access_logs + ADD CONSTRAINT access_logs_pkey PRIMARY KEY (id); + + +-- +-- Name: action_text_rich_texts action_text_rich_texts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.action_text_rich_texts + ADD CONSTRAINT action_text_rich_texts_pkey PRIMARY KEY (id); + + +-- +-- Name: active_storage_attachments active_storage_attachments_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_attachments + ADD CONSTRAINT active_storage_attachments_pkey PRIMARY KEY (id); + + +-- +-- Name: active_storage_blobs active_storage_blobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_blobs + ADD CONSTRAINT active_storage_blobs_pkey PRIMARY KEY (id); + + +-- +-- Name: active_storage_variant_records active_storage_variant_records_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_variant_records + ADD CONSTRAINT active_storage_variant_records_pkey PRIMARY KEY (id); + + +-- +-- Name: blazer_audits blazer_audits_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_audits + ADD CONSTRAINT blazer_audits_pkey PRIMARY KEY (id); + + +-- +-- Name: blazer_checks blazer_checks_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_checks + ADD CONSTRAINT blazer_checks_pkey PRIMARY KEY (id); + + +-- +-- Name: blazer_dashboard_queries blazer_dashboard_queries_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_dashboard_queries + ADD CONSTRAINT blazer_dashboard_queries_pkey PRIMARY KEY (id); + + +-- +-- Name: blazer_dashboards blazer_dashboards_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_dashboards + ADD CONSTRAINT blazer_dashboards_pkey PRIMARY KEY (id); + + +-- +-- Name: blazer_queries blazer_queries_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blazer_queries + ADD CONSTRAINT blazer_queries_pkey PRIMARY KEY (id); + + +-- +-- Name: build_stats build_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.build_stats + ADD CONSTRAINT build_stats_pkey PRIMARY KEY (id); + + +-- +-- Name: codes_of_conduct codes_of_conduct_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.codes_of_conduct + ADD CONSTRAINT codes_of_conduct_pkey PRIMARY KEY (id); + + +-- +-- Name: csp_reports csp_reports_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.csp_reports + ADD CONSTRAINT csp_reports_pkey PRIMARY KEY (id); + + +-- +-- Name: deploys deploys_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.deploys + ADD CONSTRAINT deploys_pkey PRIMARY KEY (id); + + +-- +-- Name: designs designs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.designs + ADD CONSTRAINT designs_pkey PRIMARY KEY (id); + + +-- +-- Name: distributed_press_publishers distributed_press_publishers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.distributed_press_publishers + ADD CONSTRAINT distributed_press_publishers_pkey PRIMARY KEY (id); + + +-- +-- Name: indexed_posts indexed_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.indexed_posts + ADD CONSTRAINT indexed_posts_pkey PRIMARY KEY (id); + + +-- +-- Name: licencias licencias_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.licencias + ADD CONSTRAINT licencias_pkey PRIMARY KEY (id); + + +-- +-- Name: log_entries log_entries_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.log_entries + ADD CONSTRAINT log_entries_pkey PRIMARY KEY (id); + + +-- +-- Name: maintenances maintenances_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.maintenances + ADD CONSTRAINT maintenances_pkey PRIMARY KEY (id); + + +-- +-- Name: mobility_string_translations mobility_string_translations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.mobility_string_translations + ADD CONSTRAINT mobility_string_translations_pkey PRIMARY KEY (id); + + +-- +-- Name: mobility_text_translations mobility_text_translations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.mobility_text_translations + ADD CONSTRAINT mobility_text_translations_pkey PRIMARY KEY (id); + + +-- +-- Name: privacy_policies privacy_policies_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.privacy_policies + ADD CONSTRAINT privacy_policies_pkey PRIMARY KEY (id); + + +-- +-- Name: que_jobs que_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.que_jobs + ADD CONSTRAINT que_jobs_pkey PRIMARY KEY (id); + + +-- +-- Name: que_lockers que_lockers_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.que_lockers + ADD CONSTRAINT que_lockers_pkey PRIMARY KEY (pid); + + +-- +-- Name: que_values que_values_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.que_values + ADD CONSTRAINT que_values_pkey PRIMARY KEY (key); + + +-- +-- Name: roles roles_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.roles + ADD CONSTRAINT roles_pkey PRIMARY KEY (id); + + +-- +-- Name: rollups rollups_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.rollups + ADD CONSTRAINT rollups_pkey PRIMARY KEY (id); + + +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + +-- +-- Name: sites sites_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.sites + ADD CONSTRAINT sites_pkey PRIMARY KEY (id); + + +-- +-- Name: stats stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.stats + ADD CONSTRAINT stats_pkey PRIMARY KEY (id); + + +-- +-- Name: usuaries usuaries_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.usuaries + ADD CONSTRAINT usuaries_pkey PRIMARY KEY (id); + + +-- +-- Name: index_access_logs_on_geoip2_data_city_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_geoip2_data_city_name ON public.access_logs USING btree (geoip2_data_city_name); + + +-- +-- Name: index_access_logs_on_geoip2_data_country_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_geoip2_data_country_name ON public.access_logs USING btree (geoip2_data_country_name); + + +-- +-- Name: index_access_logs_on_host; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_host ON public.access_logs USING btree (host); + + +-- +-- Name: index_access_logs_on_http_origin; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_http_origin ON public.access_logs USING btree (http_origin); + + +-- +-- Name: index_access_logs_on_http_user_agent; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_http_user_agent ON public.access_logs USING btree (http_user_agent); + + +-- +-- Name: index_access_logs_on_status; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_status ON public.access_logs USING btree (status); + + +-- +-- Name: index_access_logs_on_uri; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_access_logs_on_uri ON public.access_logs USING btree (uri); + + +-- +-- Name: index_action_text_rich_texts_uniqueness; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_action_text_rich_texts_uniqueness ON public.action_text_rich_texts USING btree (record_type, record_id, name); + + +-- +-- Name: index_active_storage_attachments_on_blob_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_active_storage_attachments_on_blob_id ON public.active_storage_attachments USING btree (blob_id); + + +-- +-- Name: index_active_storage_attachments_uniqueness; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON public.active_storage_attachments USING btree (record_type, record_id, name, blob_id); + + +-- +-- Name: index_active_storage_blobs_on_key_and_service_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_active_storage_blobs_on_key_and_service_name ON public.active_storage_blobs USING btree (key, service_name); + + +-- +-- Name: index_active_storage_variant_records_uniqueness; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON public.active_storage_variant_records USING btree (blob_id, variation_digest); + + +-- +-- Name: index_blazer_audits_on_query_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_audits_on_query_id ON public.blazer_audits USING btree (query_id); + + +-- +-- Name: index_blazer_audits_on_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_audits_on_user_id ON public.blazer_audits USING btree (user_id); + + +-- +-- Name: index_blazer_checks_on_creator_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_checks_on_creator_id ON public.blazer_checks USING btree (creator_id); + + +-- +-- Name: index_blazer_checks_on_query_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_checks_on_query_id ON public.blazer_checks USING btree (query_id); + + +-- +-- Name: index_blazer_dashboard_queries_on_dashboard_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_dashboard_queries_on_dashboard_id ON public.blazer_dashboard_queries USING btree (dashboard_id); + + +-- +-- Name: index_blazer_dashboard_queries_on_query_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_dashboard_queries_on_query_id ON public.blazer_dashboard_queries USING btree (query_id); + + +-- +-- Name: index_blazer_dashboards_on_creator_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_dashboards_on_creator_id ON public.blazer_dashboards USING btree (creator_id); + + +-- +-- Name: index_blazer_queries_on_creator_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_blazer_queries_on_creator_id ON public.blazer_queries USING btree (creator_id); + + +-- +-- Name: index_build_stats_on_deploy_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_build_stats_on_deploy_id ON public.build_stats USING btree (deploy_id); + + +-- +-- Name: index_deploys_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_deploys_on_site_id ON public.deploys USING btree (site_id); + + +-- +-- Name: index_deploys_on_type; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_deploys_on_type ON public.deploys USING btree (type); + + +-- +-- Name: index_designs_on_gem; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_designs_on_gem ON public.designs USING btree (gem); + + +-- +-- Name: index_designs_on_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_designs_on_name ON public.designs USING btree (name); + + +-- +-- Name: index_indexed_posts_on_front_matter; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_indexed_posts_on_front_matter ON public.indexed_posts USING gin (front_matter); + + +-- +-- Name: index_indexed_posts_on_indexed_content; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_indexed_posts_on_indexed_content ON public.indexed_posts USING gin (indexed_content); + + +-- +-- Name: index_indexed_posts_on_layout; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_indexed_posts_on_layout ON public.indexed_posts USING btree (layout); + + +-- +-- Name: index_indexed_posts_on_locale; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_indexed_posts_on_locale ON public.indexed_posts USING btree (locale); + + +-- +-- Name: index_indexed_posts_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_indexed_posts_on_site_id ON public.indexed_posts USING btree (site_id); + + +-- +-- Name: index_licencias_on_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_licencias_on_name ON public.licencias USING btree (name); + + +-- +-- Name: index_log_entries_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_log_entries_on_site_id ON public.log_entries USING btree (site_id); + + +-- +-- Name: index_mobility_string_translations_on_keys; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_mobility_string_translations_on_keys ON public.mobility_string_translations USING btree (translatable_id, translatable_type, locale, key); + + +-- +-- Name: index_mobility_string_translations_on_query_keys; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_mobility_string_translations_on_query_keys ON public.mobility_string_translations USING btree (translatable_type, key, value, locale); + + +-- +-- Name: index_mobility_string_translations_on_translatable_attribute; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_mobility_string_translations_on_translatable_attribute ON public.mobility_string_translations USING btree (translatable_id, translatable_type, key); + + +-- +-- Name: index_mobility_text_translations_on_keys; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_mobility_text_translations_on_keys ON public.mobility_text_translations USING btree (translatable_id, translatable_type, locale, key); + + +-- +-- Name: index_mobility_text_translations_on_translatable_attribute; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_mobility_text_translations_on_translatable_attribute ON public.mobility_text_translations USING btree (translatable_id, translatable_type, key); + + +-- +-- Name: index_roles_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_roles_on_site_id ON public.roles USING btree (site_id); + + +-- +-- Name: index_roles_on_site_id_and_usuarie_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_roles_on_site_id_and_usuarie_id ON public.roles USING btree (site_id, usuarie_id); + + +-- +-- Name: index_roles_on_usuarie_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_roles_on_usuarie_id ON public.roles USING btree (usuarie_id); + + +-- +-- Name: index_rollups_on_name_and_interval_and_time_and_dimensions; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_rollups_on_name_and_interval_and_time_and_dimensions ON public.rollups USING btree (name, "interval", "time", dimensions); + + +-- +-- Name: index_sites_on_design_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_sites_on_design_id ON public.sites USING btree (design_id); + + +-- +-- Name: index_sites_on_licencia_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_sites_on_licencia_id ON public.sites USING btree (licencia_id); + + +-- +-- Name: index_sites_on_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_sites_on_name ON public.sites USING btree (name); + + +-- +-- Name: index_stats_on_name; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_stats_on_name ON public.stats USING hash (name); + + +-- +-- Name: index_stats_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_stats_on_site_id ON public.stats USING btree (site_id); + + +-- +-- Name: index_usuaries_on_confirmation_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_usuaries_on_confirmation_token ON public.usuaries USING btree (confirmation_token); + + +-- +-- Name: index_usuaries_on_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_usuaries_on_email ON public.usuaries USING btree (email); + + +-- +-- Name: index_usuaries_on_invitation_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_usuaries_on_invitation_token ON public.usuaries USING btree (invitation_token); + + +-- +-- Name: index_usuaries_on_invitations_count; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_usuaries_on_invitations_count ON public.usuaries USING btree (invitations_count); + + +-- +-- Name: index_usuaries_on_invited_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_usuaries_on_invited_by_id ON public.usuaries USING btree (invited_by_id); + + +-- +-- Name: index_usuaries_on_invited_by_type_and_invited_by_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_usuaries_on_invited_by_type_and_invited_by_id ON public.usuaries USING btree (invited_by_type, invited_by_id); + + +-- +-- Name: index_usuaries_on_reset_password_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_usuaries_on_reset_password_token ON public.usuaries USING btree (reset_password_token); + + +-- +-- Name: index_usuaries_on_unlock_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_usuaries_on_unlock_token ON public.usuaries USING btree (unlock_token); + + +-- +-- Name: que_jobs_args_gin_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX que_jobs_args_gin_idx ON public.que_jobs USING gin (args jsonb_path_ops); + + +-- +-- Name: que_jobs_data_gin_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX que_jobs_data_gin_idx ON public.que_jobs USING gin (data jsonb_path_ops); + + +-- +-- Name: que_jobs_kwargs_gin_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX que_jobs_kwargs_gin_idx ON public.que_jobs USING gin (kwargs jsonb_path_ops); + + +-- +-- Name: que_poll_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX que_poll_idx ON public.que_jobs USING btree (job_schema_version, queue, priority, run_at, id) WHERE ((finished_at IS NULL) AND (expired_at IS NULL)); + + +-- +-- Name: access_logs access_logs_before_insert_row_tr; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER access_logs_before_insert_row_tr BEFORE INSERT ON public.access_logs FOR EACH ROW EXECUTE FUNCTION public.access_logs_before_insert_row_tr(); + + +-- +-- Name: indexed_posts indexed_posts_before_insert_update_row_tr; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER indexed_posts_before_insert_update_row_tr BEFORE INSERT OR UPDATE ON public.indexed_posts FOR EACH ROW EXECUTE FUNCTION public.indexed_posts_before_insert_update_row_tr(); + + +-- +-- Name: que_jobs que_job_notify; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER que_job_notify AFTER INSERT ON public.que_jobs FOR EACH ROW WHEN ((NOT (COALESCE(current_setting('que.skip_notify'::text, true), ''::text) = 'true'::text))) EXECUTE FUNCTION public.que_job_notify(); + + +-- +-- Name: que_jobs que_state_notify; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER que_state_notify AFTER INSERT OR DELETE OR UPDATE ON public.que_jobs FOR EACH ROW WHEN ((NOT (COALESCE(current_setting('que.skip_notify'::text, true), ''::text) = 'true'::text))) EXECUTE FUNCTION public.que_state_notify(); + + +-- +-- Name: active_storage_variant_records fk_rails_993965df05; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_variant_records + ADD CONSTRAINT fk_rails_993965df05 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); + + +-- +-- Name: active_storage_attachments fk_rails_c3b3935057; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.active_storage_attachments + ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); + + +-- +-- Name: publisher; Type: PUBLICATION; Schema: -; Owner: - +-- + +CREATE PUBLICATION publisher FOR ALL TABLES WITH (publish = 'insert, update, delete, truncate'); + + +-- +-- PostgreSQL database dump complete +-- + From 707695f97d935f2ddc6e006233e993f623690c6a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 15:52:41 -0300 Subject: [PATCH 096/814] =?UTF-8?q?fix:=20la=20replicaci=C3=B3n=20la=20con?= =?UTF-8?q?figuramos=20en=20otro=20lado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/structure.sql | 7 ------- 1 file changed, 7 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index e50ae337..ab92db9a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2254,13 +2254,6 @@ ALTER TABLE ONLY public.active_storage_attachments ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id); --- --- Name: publisher; Type: PUBLICATION; Schema: -; Owner: - --- - -CREATE PUBLICATION publisher FOR ALL TABLES WITH (publish = 'insert, update, delete, truncate'); - - -- -- PostgreSQL database dump complete -- From 11d0431b3455e827b6f19f065ec402286a1a50ca Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 15:53:01 -0300 Subject: [PATCH 097/814] =?UTF-8?q?fix:=20dblink=20no=20es=20una=20extensi?= =?UTF-8?q?=C3=B3n=20que=20usemos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/structure.sql | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index ab92db9a..97aec2d1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -23,20 +23,6 @@ SET row_security = off; -- *not* creating schema, since initdb creates it --- --- Name: dblink; Type: EXTENSION; Schema: -; Owner: - --- - -CREATE EXTENSION IF NOT EXISTS dblink WITH SCHEMA public; - - --- --- Name: EXTENSION dblink; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON EXTENSION dblink IS 'connect to other PostgreSQL databases from within a database'; - - -- -- Name: pg_trgm; Type: EXTENSION; Schema: -; Owner: - -- From eba42c9b7914aeaae04d9c155eee5a1185f2c99a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 16:52:29 -0300 Subject: [PATCH 098/814] fix: hacer el dump desde rails --- db/structure.sql | 93 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index 97aec2d1..e0d8f710 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1,10 +1,3 @@ --- --- PostgreSQL database dump --- - --- Dumped from database version 15.2 --- Dumped by pg_dump version 15.2 - SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; @@ -1242,7 +1235,8 @@ CREATE TABLE public.sites ( tienda_api_key_ciphertext character varying DEFAULT ''::character varying, tienda_url character varying DEFAULT ''::character varying, api_key_ciphertext character varying, - slugify_mode character varying DEFAULT 'default'::character varying + slugify_mode character varying DEFAULT 'default'::character varying, + pagination boolean DEFAULT false ); @@ -2244,3 +2238,86 @@ ALTER TABLE ONLY public.active_storage_attachments -- PostgreSQL database dump complete -- +SET search_path TO "$user", public; + +INSERT INTO "schema_migrations" (version) VALUES +('20180925183241'), +('20190211184815'), +('20190703190859'), +('20190703200455'), +('20190705195758'), +('20190705215536'), +('20190706000159'), +('20190706002615'), +('20190711183726'), +('20190712165059'), +('20190716195155'), +('20190716195449'), +('20190716195811'), +('20190716195812'), +('20190716202024'), +('20190717214308'), +('20190718185817'), +('20190719221653'), +('20190723220002'), +('20190725185427'), +('20190726003756'), +('20190730211624'), +('20190730211756'), +('20190820225238'), +('20190829163530'), +('20190829180743'), +('20200118155319'), +('20200126175158'), +('20200130193655'), +('20200205173039'), +('20200206151057'), +('20200206163257'), +('20200527221900'), +('20200529154040'), +('20200615171026'), +('20200616133218'), +('20200801230101'), +('20200801233025'), +('20200810230944'), +('20200811210507'), +('20200816003344'), +('20200820165316'), +('20200822204920'), +('20201111203031'), +('20201207152354'), +('20201224162153'), +('20201224162154'), +('20210414152728'), +('20210504224144'), +('20210504224343'), +('20210506212356'), +('20210507221120'), +('20210511211357'), +('20210722191718'), +('20210807003928'), +('20210807004941'), +('20210926205448'), +('20211008201239'), +('20211022224008'), +('20211022225449'), +('20220406211042'), +('20220428135113'), +('20220712135053'), +('20220802153308'), +('20230119165420'), +('20230318183722'), +('20230322214924'), +('20230322231344'), +('20230325163802'), +('20230328200129'), +('20230328213242'), +('20230328231029'), +('20230411185406'), +('20230415153231'), +('20230421182627'), +('20230424174544'), +('20230519143500'), +('20230524190240'); + + From 8d7d1c10b18cd4725f994c9f5900517947f3f9d3 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 12:04:44 -0300 Subject: [PATCH 099/814] fix: indexar posts luego de crear el sitio #13610 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit se producía una condición donde el sitio se quería indexar sin haber terminado de instalar las gemas y todo fallaba. no tenemos que usar más callbacks, solo servicios --- app/models/site/index.rb | 2 -- app/services/site_service.rb | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index e11095e3..c2c55ade 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -8,8 +8,6 @@ class Site extend ActiveSupport::Concern included do - # TODO: Debería ser un Job? - after_create :index_posts! has_many :indexed_posts, dependent: :destroy def index_posts! diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 2c29538c..367d3b08 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -33,6 +33,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do add_licencias && add_code_of_conduct && add_privacy_policy && + site.index_posts! && deploy end From 6e4247206719c8330f6229139df17858e8de734c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 13:33:25 -0300 Subject: [PATCH 100/814] =?UTF-8?q?fix:=20darle=20bola=20a=20los=20mensaje?= =?UTF-8?q?s=20de=20deprecaci=C3=B3n=20de=20bundler=20#13610?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit se configuraban las opciones que le pasábamos pero no se aplicaban en el comando actual, con lo que quería instalar las gemas globalmente y fallaba la creación de sitios. --- app/models/deploy_local.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 75ea8b1c..ed5f1919 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -138,7 +138,12 @@ class DeployLocal < Deploy end def bundle(output: false) - run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output + run %(bundle config set --local clean 'true'), output: output + run %(bundle config set --local deployment 'true'), output: output + run %(bundle config set --local path '#{gems_dir}'), output: output + run %(bundle config set --local without 'test development'), output: output + run %(bundle config set --local cache_all 'false'), output: output + run %(bundle install), output: output end def jekyll_build(output: false) From d17db5428abb9df95ddf32bf8cdbd7189a60fec5 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 18:28:34 -0300 Subject: [PATCH 101/814] fix: deprecar Dir#chdir #13619 --- app/models/deploy.rb | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index a92708c0..515a8530 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -65,22 +65,20 @@ class Deploy < ApplicationRecord lines = [] time_start - Dir.chdir(site.path) do - Open3.popen2e(env, cmd, unsetenv_others: true) do |_, o, t| - # TODO: Enviar a un websocket para ver el proceso en vivo? - Thread.new do - o.each do |line| - lines << line + Open3.popen2e(env, cmd, unsetenv_others: true, chdir: site.path) do |_, o, t| + # TODO: Enviar a un websocket para ver el proceso en vivo? + Thread.new do + o.each do |line| + lines << line - puts line if output - end - rescue IOError => e - lines << e.message - puts e.message if output + puts line if output end - - r = t.value + rescue IOError => e + lines << e.message + puts e.message if output end + + r = t.value end time_stop From 6d64fa144392d0b011ca56ec677f99f095857a27 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 18:51:16 -0300 Subject: [PATCH 102/814] fix: generar un registro cuando falla distributed press #13628 --- app/models/deploy_distributed_press.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 889d8e34..2c892b55 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -52,7 +52,12 @@ class DeployDistributedPress < Deploy end end - status = c.publish(publishing_site, deploy_local.destination) + begin + status = c.publish(publishing_site, deploy_local.destination) + rescue DistributedPress::V1::Error => e + ExceptionNotifier.notify_exception(e, data: { site: site.name }) + status = false + end if status self.remote_info[:distributed_press] = c.show(publishing_site).to_h From bb7487e941f86fb74a3be4dbc7383ebd5384c721 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 6 Jul 2023 12:43:28 -0300 Subject: [PATCH 103/814] fix: correr chdir de a uno por thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit como jekyll no es multi-threaded, pero rails si, es posible que se produzca una excepción en Dir.chdir si se intenta leer sitios concurrentemente (por ejemplo, abrir dos pestañas del mismo sitio). closes #13717 closes #13716 closes #13715 closes #13619 --- app/models/site.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..81264a24 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -447,6 +447,10 @@ class Site < ApplicationRecord find_by(name: "#{Site.domain}.") end + def self.one_at_a_time + @@one_at_a_time ||= Thread::Mutex.new + end + def reset @read = false @layouts = nil @@ -553,7 +557,9 @@ class Site < ApplicationRecord end def run_in_path(&block) - Dir.chdir path, &block + Site.one_at_a_time.synchronize do + Dir.chdir path, &block + end end # Instala las gemas cuando es necesario: From 42b6744f81c8b3399893fba9cf561ef6f96b2b4b Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 18 Jul 2023 15:47:26 -0300 Subject: [PATCH 104/814] feat: Job para hacer push #12919 --- app/jobs/git_push_job.rb | 12 ++++++++++++ app/models/site/repository.rb | 31 ++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 app/jobs/git_push_job.rb diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb new file mode 100644 index 00000000..fb3ca662 --- /dev/null +++ b/app/jobs/git_push_job.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Permite pushear los cambios cada vez que se +# hacen commits en un sitio +class GitPushJob < ApplicationJob + # @param :site [Site] + # @return [nil] + def perform(site) + #detectar que el repo local tiene repo remoto + site.repository.push if site.repository.origin + end +end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 62e4c45e..10ab481d 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -29,7 +29,7 @@ class Site # Obtiene el origin # - # @return [Rugged::Remote] + # @return [Rugged::Remote, nil] def origin @origin ||= rugged.remotes.find do |remote| remote.name == 'origin' @@ -154,17 +154,15 @@ class Site # # @return [Boolean] def gc - env = { 'PATH' => '/usr/bin', 'LANG' => ENV['LANG'], 'HOME' => path } - cmd = 'git gc' + git_sh("git gc") + end - r = nil - Dir.chdir(path) do - Open3.popen2e(env, cmd, unsetenv_others: true) do |_, _, t| - r = t.value - end - end - - r&.success? + # Pushea cambios al repositorio remoto + # + # @return [Boolean, nil] + def push + origin.push(rugged.head.canonical_name, credentials: credentials) + git_sh("git lfs push") end private @@ -192,5 +190,16 @@ class Site def relativize(file) Pathname.new(file).relative_path_from(Pathname.new(path)).to_s end + + def git_sh(cmd) + env = { 'PATH' => '/usr/bin', 'LANG' => ENV['LANG'], 'HOME' => path } + + r = nil + Open3.popen2e(env, cmd, unsetenv_others: true, chdir: path) do |_, _, t| + r = t.value + end + + r&.success? + end end end From d77b8ba67be5d4955cfaeb141197a1ab0ab86963 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 20 Jul 2023 14:58:21 -0300 Subject: [PATCH 105/814] feat: created job to make git pull #12980 --- app/jobs/git_pull_job.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 app/jobs/git_pull_job.rb diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb new file mode 100644 index 00000000..0c9ef237 --- /dev/null +++ b/app/jobs/git_pull_job.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Permite traer los cambios cada vez que se +# hace un push al repositorio +class GitPullJob < ApplicationJob + # @param :site [Site] + # @return [nil] + def perform(site) + # hace un fetch para ver cambios + site.repository.fetch + + # hace un merge + site.repository.merge(site.usuarie) + site.repository.git_sh("git lfs fetch") + + end + end \ No newline at end of file From ca9fa31cf135d79e0204aad24d716a7f04c917c7 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 20 Jul 2023 15:31:38 -0300 Subject: [PATCH 106/814] fix: change git_sh method to accept array of params #12919 --- app/jobs/git_push_job.rb | 1 - app/models/site/repository.rb | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb index fb3ca662..3c62bee2 100644 --- a/app/jobs/git_push_job.rb +++ b/app/jobs/git_push_job.rb @@ -6,7 +6,6 @@ class GitPushJob < ApplicationJob # @param :site [Site] # @return [nil] def perform(site) - #detectar que el repo local tiene repo remoto site.repository.push if site.repository.origin end end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 10ab481d..6306730e 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -154,7 +154,7 @@ class Site # # @return [Boolean] def gc - git_sh("git gc") + git_sh("git", "gc") end # Pushea cambios al repositorio remoto @@ -162,7 +162,7 @@ class Site # @return [Boolean, nil] def push origin.push(rugged.head.canonical_name, credentials: credentials) - git_sh("git lfs push") + git_sh("git", "lfs", "push", "origin", "#{default_branch}") end private @@ -191,11 +191,15 @@ class Site Pathname.new(file).relative_path_from(Pathname.new(path)).to_s end - def git_sh(cmd) + # Ejecuta un comando de git + # + # @param :args [Array] + # @return [Boolean] + def git_sh(*args) env = { 'PATH' => '/usr/bin', 'LANG' => ENV['LANG'], 'HOME' => path } r = nil - Open3.popen2e(env, cmd, unsetenv_others: true, chdir: path) do |_, _, t| + Open3.popen2e(env, args, unsetenv_others: true, chdir: path) do |_, _, t| r = t.value end From c2d64e11d7c0c6fb414e6970f6c933db19442561 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 20 Jul 2023 16:26:43 -0300 Subject: [PATCH 107/814] fix: missing splat in git_sh method #12919 --- app/models/site/repository.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 6306730e..a900fea2 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -162,7 +162,7 @@ class Site # @return [Boolean, nil] def push origin.push(rugged.head.canonical_name, credentials: credentials) - git_sh("git", "lfs", "push", "origin", "#{default_branch}") + git_sh("git", "lfs", "push", "origin", "default_branch") end private @@ -199,7 +199,7 @@ class Site env = { 'PATH' => '/usr/bin', 'LANG' => ENV['LANG'], 'HOME' => path } r = nil - Open3.popen2e(env, args, unsetenv_others: true, chdir: path) do |_, _, t| + Open3.popen2e(env, *args, unsetenv_others: true, chdir: path) do |_, _, t| r = t.value end From 3e12bfbe9ec950ec4dfd639717664742bc0491b6 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 21 Jul 2023 17:12:26 -0300 Subject: [PATCH 108/814] fix: add git lfs fetch to repository#fetch method #12980 --- app/jobs/git_pull_job.rb | 12 ++++-------- app/models/site/repository.rb | 6 +++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index 0c9ef237..de263403 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -4,14 +4,10 @@ # hace un push al repositorio class GitPullJob < ApplicationJob # @param :site [Site] + # @param :usuarie [Usuarie] # @return [nil] - def perform(site) - # hace un fetch para ver cambios + def perform(site, usuarie) site.repository.fetch - - # hace un merge - site.repository.merge(site.usuarie) - site.repository.git_sh("git lfs fetch") - + site.repository.merge(usuarie) end - end \ No newline at end of file +end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 62e4c45e..d2832091 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -45,7 +45,9 @@ class Site # @return [Integer] def fetch if origin.check_connection(:fetch, credentials: credentials) - rugged.fetch(origin, credentials: credentials)[:received_objects] + rugged.fetch(origin, credentials: credentials)[:received_objects].tap do |objects| + git_sh("git", "lfs", "fetch", "origin", default_branch) if objects&.positive? + end else 0 end @@ -75,6 +77,8 @@ class Site # Forzamos el checkout para mover el HEAD al último commit y # escribir los cambios rugged.checkout 'HEAD', strategy: :force + # reemplaza los pointers por los archivos correspondientes + git_sh("git", "lfs", "checkout") commit end From b7dc448daaec35c2e45045ab2272fe0f82ada948 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 21 Jul 2023 17:15:36 -0300 Subject: [PATCH 109/814] fix: fix git_sh method in site.repository.rb #12919 --- app/models/site/repository.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index a900fea2..1ce10ed5 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -162,7 +162,7 @@ class Site # @return [Boolean, nil] def push origin.push(rugged.head.canonical_name, credentials: credentials) - git_sh("git", "lfs", "push", "origin", "default_branch") + git_sh("git", "lfs", "push", "origin", default_branch) end private From ae794322787548a79e6416663c45f3e8dd9cad62 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 21 Jul 2023 17:33:23 -0300 Subject: [PATCH 110/814] fix: renombrar el skel a upstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit si lo mantenemos como origin por defecto, el GitPushJob va a querer enviar cambios a un repositorio común, rompiendo todo. --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..0fddeff5 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -473,7 +473,7 @@ class Site < ApplicationRecord def clone_skel! return if jekyll? - Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path + Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path, remote: 'upstream' end # Elimina el directorio del sitio From b7e93cd8c8e8a9cbccc40d865571e21ecf0abfc3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 26 Jul 2023 14:44:11 -0300 Subject: [PATCH 111/814] feat: controlador para gestionar los webhooks #13903 --- app/controllers/api/v1/webhooks_controller.rb | 17 +++++++++++++++++ app/models/site/repository.rb | 4 ++-- config/locales/en.yml | 3 +++ config/locales/es.yml | 3 +++ config/routes.rb | 2 ++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 app/controllers/api/v1/webhooks_controller.rb diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb new file mode 100644 index 00000000..4811d792 --- /dev/null +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Api + module V1 + # Recibe webhooks y lanza jobs + class WebhooksController < BaseController + def pull + # encontrar el sitio + site = Site.find_by_name(params[:site_id]) + usuarie = GitAuthor.new email: "webhook@#{Site.domain}", name: 'Webhook' + message = I18n.t('webhooks.pull.message') + + GitPullJob.perform_later(site, usuarie, message) + end + end + end +end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 404cde3e..a3487bc5 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -56,7 +56,7 @@ class Site # Incorpora los cambios en el repositorio actual # # @return [Rugged::Commit] - def merge(usuarie) + def merge(usuarie, message) merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos @@ -71,7 +71,7 @@ class Site .create(rugged, update_ref: 'HEAD', parents: [head_commit, remote_head_commit], tree: merge.write_tree(rugged), - message: I18n.t('sites.fetch.merge.message'), + message: message, author: author(usuarie), committer: committer) # Forzamos el checkout para mover el HEAD al último commit y diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..05fcf1e5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -466,6 +466,9 @@ en: success: 'Site upgrade has been completed. Your next build will run this upgrade :)' error: "There was an error when trying to upgrade your site. This could be due to conflicts that couldn't be solved automatically. A report of the issue has already been sent to our admins. Sorry for the inconvenience! :(" message: 'Skeleton upgrade' + webhooks_controller: + pull: + message: 'Webhooks upgrade' footer: powered_by: 'is developed by' i18n: diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..af5a7db7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -474,6 +474,9 @@ es: success: 'Ya se incorporaron los cambios en el sitio, se aplicarán en la próxima compilación que hagas :)' error: 'Hubo un error al incorporar los cambios en el sitio. Esto puede deberse a conflictos entre cambios que no se pueden resolver automáticamente. Hemos enviado un reporte del problema a les administradores de Sutty para que estén al tanto de la situación. ¡Lo sentimos! :(' message: 'Actualización del esqueleto' + webhooks_controller: + pull: + message: 'Actualización desde Webhooks' footer: powered_by: 'es desarrollada por' i18n: diff --git a/config/routes.rb b/config/routes.rb index 3828915c..f2487066 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,6 +17,8 @@ Rails.application.routes.draw do get :'contact/cookie', to: 'invitades#contact_cookie' post :'contact/:form', to: 'contact#receive', as: :contact + + post :'webhooks/pull', to: 'webhooks#pull' end end end From 8947942cb9066f2775faf4b0864e2874a1c39907 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 27 Jul 2023 16:46:32 -0300 Subject: [PATCH 112/814] fix: commit message fixed #13903 --- app/controllers/api/v1/webhooks_controller.rb | 9 ++++++--- app/jobs/git_pull_job.rb | 4 ++-- app/models/site/repository.rb | 2 +- config/locales/en.yml | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 4811d792..40187915 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -4,11 +4,14 @@ module Api module V1 # Recibe webhooks y lanza jobs class WebhooksController < BaseController + # Trae los cambios a partir de un post de Webhooks: + # (Gitlab, Github, Guitea, etc) def pull - # encontrar el sitio - site = Site.find_by_name(params[:site_id]) + site = Site.find_by_name!(params[:site_id]) usuarie = GitAuthor.new email: "webhook@#{Site.domain}", name: 'Webhook' - message = I18n.t('webhooks.pull.message') + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') + end GitPullJob.perform_later(site, usuarie, message) end diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index de263403..5cd86981 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -6,8 +6,8 @@ class GitPullJob < ApplicationJob # @param :site [Site] # @param :usuarie [Usuarie] # @return [nil] - def perform(site, usuarie) + def perform(site, usuarie, message) site.repository.fetch - site.repository.merge(usuarie) + site.repository.merge(usuarie, message) if site.repository.fetch&.positive? end end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index a3487bc5..a864e8b9 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -56,7 +56,7 @@ class Site # Incorpora los cambios en el repositorio actual # # @return [Rugged::Commit] - def merge(usuarie, message) + def merge(usuarie, message= I18n.t('sites.fetch.merge.message')) merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos diff --git a/config/locales/en.yml b/config/locales/en.yml index 05fcf1e5..8ae8cce5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -468,7 +468,7 @@ en: message: 'Skeleton upgrade' webhooks_controller: pull: - message: 'Webhooks upgrade' + message: 'Webhooks pull' footer: powered_by: 'is developed by' i18n: From 9f5364a738825e7dc17b8482ecdd882f069d1ba4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 27 Jul 2023 17:02:48 -0300 Subject: [PATCH 113/814] fix: add documentation to pull job #13903 --- app/jobs/git_pull_job.rb | 2 +- app/models/site/repository.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index 5cd86981..a0c15950 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -5,9 +5,9 @@ class GitPullJob < ApplicationJob # @param :site [Site] # @param :usuarie [Usuarie] + # @param :message [String] # @return [nil] def perform(site, usuarie, message) - site.repository.fetch site.repository.merge(usuarie, message) if site.repository.fetch&.positive? end end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index a864e8b9..c0607d84 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -56,7 +56,7 @@ class Site # Incorpora los cambios en el repositorio actual # # @return [Rugged::Commit] - def merge(usuarie, message= I18n.t('sites.fetch.merge.message')) + def merge(usuarie, message = I18n.t('sites.fetch.merge.message')) merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos From 9f94ee3bc704dfe9a7787ce6be0b8015a2fcb676 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 27 Jul 2023 17:23:40 -0300 Subject: [PATCH 114/814] fix: add response status to pull method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 2 ++ config/locales/es.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 40187915..a538d99f 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -14,6 +14,8 @@ module Api end GitPullJob.perform_later(site, usuarie, message) + + head :ok end end end diff --git a/config/locales/es.yml b/config/locales/es.yml index af5a7db7..b03a222f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -476,7 +476,7 @@ es: message: 'Actualización del esqueleto' webhooks_controller: pull: - message: 'Actualización desde Webhooks' + message: 'Pull de webhooks' footer: powered_by: 'es desarrollada por' i18n: From 9a78c628b4aac8bffe44e4dffb80d0c268be6b83 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 12:29:27 -0300 Subject: [PATCH 115/814] fix: fix typo in es.yml #13864 --- config/locales/es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..eabddcc9 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -693,7 +693,7 @@ es: new: 'Crear' edit: 'Configurar' posts: - new: 'Nuevo %{layout}' + new: 'Agregar %{layout}' edit: 'Editando' usuaries: index: 'Usuaries' From 06ebb63d9389c260e547c73487eb89c108dacb0b Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 14:18:07 -0300 Subject: [PATCH 116/814] =?UTF-8?q?fix:=20movido=20git=20lfs=20a=20m=C3=A9?= =?UTF-8?q?todo=20merge=20en=20repository.rb=20#13903?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/git_pull_job.rb | 4 ++-- app/models/site/repository.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index a0c15950..dc4a285c 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -# Permite traer los cambios cada vez que se -# hace un push al repositorio +# Permite traer los cambios desde webhooks + class GitPullJob < ApplicationJob # @param :site [Site] # @param :usuarie [Usuarie] diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index c0607d84..9c4d873f 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -45,9 +45,7 @@ class Site # @return [Integer] def fetch if origin.check_connection(:fetch, credentials: credentials) - rugged.fetch(origin, credentials: credentials)[:received_objects].tap do |objects| - git_sh("git", "lfs", "fetch", "origin", default_branch) if objects&.positive? - end + rugged.fetch(origin, credentials: credentials)[:received_objects] else 0 end @@ -77,6 +75,8 @@ class Site # Forzamos el checkout para mover el HEAD al último commit y # escribir los cambios rugged.checkout 'HEAD', strategy: :force + + git_sh("git", "lfs", "fetch", "origin", default_branch) # reemplaza los pointers por los archivos correspondientes git_sh("git", "lfs", "checkout") commit From 579e1776842774733c036b6b621ccf087b2b06cc Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 17:32:14 -0300 Subject: [PATCH 117/814] feat: agregada columna token a model rol #13903 --- app/models/rol.rb | 10 ++++++++++ db/migrate/20230731195050_add_token_to_roles.rb | 5 +++++ db/migrate/20230731202003_change_token_name.rb | 5 +++++ 3 files changed, 20 insertions(+) create mode 100644 db/migrate/20230731195050_add_token_to_roles.rb create mode 100644 db/migrate/20230731202003_change_token_name.rb diff --git a/app/models/rol.rb b/app/models/rol.rb index fcd07037..f17bf418 100644 --- a/app/models/rol.rb +++ b/app/models/rol.rb @@ -14,6 +14,9 @@ class Rol < ApplicationRecord validates_inclusion_of :rol, in: ROLES + encrypts :token + before_save :add_token_if_missing! + def invitade? rol == INVITADE end @@ -25,4 +28,11 @@ class Rol < ApplicationRecord def self.role?(rol) ROLES.include? rol end + + private + + # Asegurarse que tenga un token + def add_token_if_missing! + self.token ||= SecureRandom.hex(64) + end end diff --git a/db/migrate/20230731195050_add_token_to_roles.rb b/db/migrate/20230731195050_add_token_to_roles.rb new file mode 100644 index 00000000..635e065c --- /dev/null +++ b/db/migrate/20230731195050_add_token_to_roles.rb @@ -0,0 +1,5 @@ +class AddTokenToRoles < ActiveRecord::Migration[6.1] + def change + add_column :roles, :token, :text + end +end diff --git a/db/migrate/20230731202003_change_token_name.rb b/db/migrate/20230731202003_change_token_name.rb new file mode 100644 index 00000000..50fc0c40 --- /dev/null +++ b/db/migrate/20230731202003_change_token_name.rb @@ -0,0 +1,5 @@ +class ChangeTokenName < ActiveRecord::Migration[6.1] + def change + rename_column :roles, :token, :token_cyphertext + end +end From c19c834f10962e3c58d2b08418ee7790430318c9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 18:46:07 -0300 Subject: [PATCH 118/814] =?UTF-8?q?fix:=20cambio=20nombre=20comuna=20token?= =?UTF-8?q?=5Fcyphertext=20en=20modelo=20rol=20y=20asignaci=C3=B3n=20retro?= =?UTF-8?q?activa=20#13903?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20230731202003_change_token_name.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20230731202003_change_token_name.rb b/db/migrate/20230731202003_change_token_name.rb index 50fc0c40..c3fce3c0 100644 --- a/db/migrate/20230731202003_change_token_name.rb +++ b/db/migrate/20230731202003_change_token_name.rb @@ -1,5 +1,6 @@ class ChangeTokenName < ActiveRecord::Migration[6.1] def change rename_column :roles, :token, :token_cyphertext + Rol.find_each { |m| m.update_column( :token_cyphertext, SecureRandom.hex(64) ) } end end From 705d15c0c1959d3e50b2f8646830a15372c4797e Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 10 Aug 2023 16:05:14 -0300 Subject: [PATCH 119/814] fix: change token attribute from encrypted to normal in Rol model #13903 --- app/controllers/api/v1/webhooks_controller.rb | 22 ++++++++++++++----- app/models/rol.rb | 1 - 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index a538d99f..1933f24e 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -2,19 +2,31 @@ module Api module V1 - # Recibe webhooks y lanza jobs + # Recibe webhooks y lanza un PullJob class WebhooksController < BaseController + rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + + def site + @site ||= Site.find_by_name!(params[:site_id]) + end + + # valida la plataforma del webhook + def usuarie + # Gitlab + token = request.headers["X-Gitlab-Token"] + @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie + end + # Trae los cambios a partir de un post de Webhooks: # (Gitlab, Github, Guitea, etc) def pull - site = Site.find_by_name!(params[:site_id]) - usuarie = GitAuthor.new email: "webhook@#{Site.domain}", name: 'Webhook' message = I18n.with_locale(site.default_locale) do I18n.t('webhooks.pull.message') end - GitPullJob.perform_later(site, usuarie, message) - + end + + def platforms_answer head :ok end end diff --git a/app/models/rol.rb b/app/models/rol.rb index f17bf418..37332400 100644 --- a/app/models/rol.rb +++ b/app/models/rol.rb @@ -14,7 +14,6 @@ class Rol < ApplicationRecord validates_inclusion_of :rol, in: ROLES - encrypts :token before_save :add_token_if_missing! def invitade? From 63fd91ee48f3a9cab4417f6e9bd21be6604440f0 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 10 Aug 2023 16:13:13 -0300 Subject: [PATCH 120/814] feat: add token to existing records #13903 --- db/migrate/20230731195050_add_token_to_roles.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20230731195050_add_token_to_roles.rb b/db/migrate/20230731195050_add_token_to_roles.rb index 635e065c..620c9fef 100644 --- a/db/migrate/20230731195050_add_token_to_roles.rb +++ b/db/migrate/20230731195050_add_token_to_roles.rb @@ -1,5 +1,6 @@ class AddTokenToRoles < ActiveRecord::Migration[6.1] def change add_column :roles, :token, :text + Rol.find_each { |m| m.update_column( :token, SecureRandom.hex(64) ) } end end From 23732bbfe0ed8c4920bd7188b700f63ed5612b51 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 14 Aug 2023 12:50:18 -0300 Subject: [PATCH 121/814] feat: add method to validate token from diff platforms in webhooks controller #13903 --- app/controllers/api/v1/webhooks_controller.rb | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 1933f24e..091d467e 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -10,10 +10,32 @@ module Api @site ||= Site.find_by_name!(params[:site_id]) end - # valida la plataforma del webhook + # valida el token que envía la plataforma del webhook + def token + @token ||= + begin + # Gitlab + if request.headers['X-Gitlab-Token'] + request.headers["X-Gitlab-Token"] + # Github + elsif request.headers['X-HUB-SIGNATURE-256'] + signature(request.env['HTTP_X_HUB_SIGNATURE_256']) + # Guitea + else + signature(request.env['HTTP_X_GITEA_SIGNATURE']) + end + end + end + + def token_from_signature(signature) + payload = request.body.read + site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| + new_signature = hash_mac(OpenSSL::Digest.new('sha256'), token, payload) + @token ||= Rack::Utils.secure_compare(new_signature, signature) + end + end + def usuarie - # Gitlab - token = request.headers["X-Gitlab-Token"] @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie end @@ -23,6 +45,7 @@ module Api message = I18n.with_locale(site.default_locale) do I18n.t('webhooks.pull.message') end + GitPullJob.perform_later(site, usuarie, message) end From f2236bb305573e7a471e1b3a94ab50d486bc0d63 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 14 Aug 2023 16:49:24 -0300 Subject: [PATCH 122/814] feat: move methods to private #13903 --- app/controllers/api/v1/webhooks_controller.rb | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 091d467e..b356d20a 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -6,6 +6,19 @@ module Api class WebhooksController < BaseController rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + # Trae los cambios a partir de un post de Webhooks: + # (Gitlab, Github, Guitea, etc) + def pull + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') + end + + GitPullJob.perform_later(site, usuarie, message) + platforms_answer + end + + private + def site @site ||= Site.find_by_name!(params[:site_id]) end @@ -37,17 +50,7 @@ module Api def usuarie @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end - - # Trae los cambios a partir de un post de Webhooks: - # (Gitlab, Github, Guitea, etc) - def pull - message = I18n.with_locale(site.default_locale) do - I18n.t('webhooks.pull.message') - end - - GitPullJob.perform_later(site, usuarie, message) - end + end def platforms_answer head :ok From a098e1baa7d2e7e96b18bc16be7a21cc413c8f38 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 15 Aug 2023 16:14:34 -0300 Subject: [PATCH 123/814] fix: change migration methods to add token to roles #13903 --- db/migrate/20230731195050_add_token_to_roles.rb | 12 +++++++++--- db/migrate/20230731202003_change_token_name.rb | 6 ------ 2 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 db/migrate/20230731202003_change_token_name.rb diff --git a/db/migrate/20230731195050_add_token_to_roles.rb b/db/migrate/20230731195050_add_token_to_roles.rb index 620c9fef..c38b0526 100644 --- a/db/migrate/20230731195050_add_token_to_roles.rb +++ b/db/migrate/20230731195050_add_token_to_roles.rb @@ -1,6 +1,12 @@ class AddTokenToRoles < ActiveRecord::Migration[6.1] - def change - add_column :roles, :token, :text - Rol.find_each { |m| m.update_column( :token, SecureRandom.hex(64) ) } + def up + add_column :roles, :token, :string + Rol.find_each do |m| + m.update_column( :token, SecureRandom.hex(64) ) + end + end + + def down + remove_column :roles, :token end end diff --git a/db/migrate/20230731202003_change_token_name.rb b/db/migrate/20230731202003_change_token_name.rb deleted file mode 100644 index c3fce3c0..00000000 --- a/db/migrate/20230731202003_change_token_name.rb +++ /dev/null @@ -1,6 +0,0 @@ -class ChangeTokenName < ActiveRecord::Migration[6.1] - def change - rename_column :roles, :token, :token_cyphertext - Rol.find_each { |m| m.update_column( :token_cyphertext, SecureRandom.hex(64) ) } - end -end From c5406acb26221e591804d481ac6547072dd38952 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 15 Aug 2023 16:59:16 -0300 Subject: [PATCH 124/814] fix: add documentation and fix typos #13903 --- app/controllers/api/v1/webhooks_controller.rb | 101 ++++++++++-------- config/locales/es.yml | 2 +- 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index b356d20a..20cc0ddc 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -1,60 +1,69 @@ # frozen_string_literal: true module Api - module V1 - # Recibe webhooks y lanza un PullJob - class WebhooksController < BaseController - rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + module V1 + # Recibe webhooks y lanza un PullJob + class WebhooksController < BaseController + # responde con forbidden si falla la validación del token + rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer - # Trae los cambios a partir de un post de Webhooks: - # (Gitlab, Github, Guitea, etc) - def pull - message = I18n.with_locale(site.default_locale) do - I18n.t('webhooks.pull.message') - end - - GitPullJob.perform_later(site, usuarie, message) - platforms_answer + # Trae los cambios a partir de un post de Webhooks: + # (Gitlab, Github, Gitea, etc) + def pull + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') end - private + GitPullJob.perform_later(site, usuarie, message) + head :ok + end - def site - @site ||= Site.find_by_name!(params[:site_id]) - end + private - # valida el token que envía la plataforma del webhook - def token - @token ||= - begin - # Gitlab - if request.headers['X-Gitlab-Token'] - request.headers["X-Gitlab-Token"] - # Github - elsif request.headers['X-HUB-SIGNATURE-256'] - signature(request.env['HTTP_X_HUB_SIGNATURE_256']) - # Guitea - else - signature(request.env['HTTP_X_GITEA_SIGNATURE']) - end - end - end + # encuentra el sitio a partir de la url + def site + @site ||= Site.find_by_name!(params[:site_id]) + end - def token_from_signature(signature) - payload = request.body.read - site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| - new_signature = hash_mac(OpenSSL::Digest.new('sha256'), token, payload) - @token ||= Rack::Utils.secure_compare(new_signature, signature) - end - end + # valida el token que envía la plataforma del webhook + # + # @return [String] + def token + @token ||= + begin + # Gitlab + if request.headers['X-Gitlab-Token'] + request.headers['X-Gitlab-Token'] + # Github + elsif request.headers['X-HUB-SIGNATURE-256'] + request.env['HTTP_X_HUB_SIGNATURE_256'] + # Gitea + else + request.env['HTTP_X_GITEA_SIGNATURE'] + end + end + end - def usuarie - @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end - - def platforms_answer - head :ok + # valida token a partir de firma de webhook + # + # @return [String] + def token_from_signature(signature) + payload = request.body.read + site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| + new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) + ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) end end + + # encuentra le usuarie + def usuarie + @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie + end + + # respuesta de error a plataformas + def platforms_answer + head :forbidden + end end + end end \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index b03a222f..7a83483f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -476,7 +476,7 @@ es: message: 'Actualización del esqueleto' webhooks_controller: pull: - message: 'Pull de webhooks' + message: 'Traer los cambios a partir de un evento remoto' footer: powered_by: 'es desarrollada por' i18n: From aeb2105dc7273cf603ab8e86f7bc90780f96093f Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 15 Aug 2023 19:25:06 -0300 Subject: [PATCH 125/814] fix: add rescue in token_from_signature method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 20cc0ddc..0ecca9d7 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -9,6 +9,8 @@ module Api # Trae los cambios a partir de un post de Webhooks: # (Gitlab, Github, Gitea, etc) + # + # @return [nil] def pull message = I18n.with_locale(site.default_locale) do I18n.t('webhooks.pull.message') @@ -36,22 +38,27 @@ module Api request.headers['X-Gitlab-Token'] # Github elsif request.headers['X-HUB-SIGNATURE-256'] - request.env['HTTP_X_HUB_SIGNATURE_256'] + token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) # Gitea else - request.env['HTTP_X_GITEA_SIGNATURE'] + token_from_signatureq(request.env['HTTP_X_GITEA_SIGNATURE']) end end end # valida token a partir de firma de webhook # - # @return [String] + # @return [String, Boolean] def token_from_signature(signature) payload = request.body.read site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) + end.tap do |t| + raise ArgumentError, 'token no encontrado' if t.nil? + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) + raise ActiveRecord::RecordNotFound end end From 5ac628b38a0032a26e0f9d29f1c4e1266069360b Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 12:58:14 -0300 Subject: [PATCH 126/814] fix: fix typo and change response to platforms #13903 --- app/controllers/api/v1/webhooks_controller.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 0ecca9d7..40f2f06d 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -40,8 +40,10 @@ module Api elsif request.headers['X-HUB-SIGNATURE-256'] token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) # Gitea + elsif + token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) else - token_from_signatureq(request.env['HTTP_X_GITEA_SIGNATURE']) + raise ActiveRecord::RecordNotFound end end end @@ -55,10 +57,7 @@ module Api new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) end.tap do |t| - raise ArgumentError, 'token no encontrado' if t.nil? - rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) - raise ActiveRecord::RecordNotFound + raise ActiveRecord::RecordNotFound if t.nil? end end @@ -70,6 +69,9 @@ module Api # respuesta de error a plataformas def platforms_answer head :forbidden + raise ArgumentError, 'token no encontrado' + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) end end end From 35dca9d7565f40f2a037b095ea8005cd2a953232 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 13:39:29 -0300 Subject: [PATCH 127/814] fix: fix exception in platforms_answer method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 40f2f06d..13a227ce 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -57,7 +57,7 @@ module Api new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) end.tap do |t| - raise ActiveRecord::RecordNotFound if t.nil? + raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil? end end @@ -67,12 +67,9 @@ module Api end # respuesta de error a plataformas - def platforms_answer + def platforms_answer(exception) head :forbidden - raise ArgumentError, 'token no encontrado' - rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) - end + ExceptionNotifier.notify_exception(exception, data: { params: params.to_h }) end end end \ No newline at end of file From cefd053d1d7f70233f07cd047fd1dc5d321dd8b5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 14:57:01 -0300 Subject: [PATCH 128/814] fix: add condition in elsif in token method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 13a227ce..3af9abee 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -40,7 +40,7 @@ module Api elsif request.headers['X-HUB-SIGNATURE-256'] token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) # Gitea - elsif + elsif request.headers['HTTP_X_GITEA_SIGNATURE'] token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) else raise ActiveRecord::RecordNotFound From 114fe4b2d5dce83874735cf1de97af6e89b925d5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 15:43:57 -0300 Subject: [PATCH 129/814] fix: fix in es.yml & en.yml and missing end #13903 --- app/controllers/api/v1/webhooks_controller.rb | 11 ++++++----- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 3af9abee..8ef943be 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -38,12 +38,12 @@ module Api request.headers['X-Gitlab-Token'] # Github elsif request.headers['X-HUB-SIGNATURE-256'] - token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) + token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256'], 'sha256=') # Gitea elsif request.headers['HTTP_X_GITEA_SIGNATURE'] token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) else - raise ActiveRecord::RecordNotFound + raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end end end @@ -51,10 +51,10 @@ module Api # valida token a partir de firma de webhook # # @return [String, Boolean] - def token_from_signature(signature) + def token_from_signature(signature. prepend = '') payload = request.body.read site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| - new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) + new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) end.tap do |t| raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil? @@ -69,7 +69,8 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) head :forbidden - ExceptionNotifier.notify_exception(exception, data: { params: params.to_h }) + ExceptionNotifier.notify_exception(exception, env: request.env) + end end end end \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 8ae8cce5..c9a723bc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -466,7 +466,7 @@ en: success: 'Site upgrade has been completed. Your next build will run this upgrade :)' error: "There was an error when trying to upgrade your site. This could be due to conflicts that couldn't be solved automatically. A report of the issue has already been sent to our admins. Sorry for the inconvenience! :(" message: 'Skeleton upgrade' - webhooks_controller: + webhooks: pull: message: 'Webhooks pull' footer: diff --git a/config/locales/es.yml b/config/locales/es.yml index 7a83483f..857217ec 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -474,7 +474,7 @@ es: success: 'Ya se incorporaron los cambios en el sitio, se aplicarán en la próxima compilación que hagas :)' error: 'Hubo un error al incorporar los cambios en el sitio. Esto puede deberse a conflictos entre cambios que no se pueden resolver automáticamente. Hemos enviado un reporte del problema a les administradores de Sutty para que estén al tanto de la situación. ¡Lo sentimos! :(' message: 'Actualización del esqueleto' - webhooks_controller: + webhooks: pull: message: 'Traer los cambios a partir de un evento remoto' footer: From 5ef601139fab2f99952dcda124a6a06bd10dc054 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:21:48 -0300 Subject: [PATCH 130/814] fix: eliminar espacio en blanco --- app/controllers/api/v1/webhooks_controller.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 8ef943be..fb4a710c 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -11,7 +11,7 @@ module Api # (Gitlab, Github, Gitea, etc) # # @return [nil] - def pull + def pull message = I18n.with_locale(site.default_locale) do I18n.t('webhooks.pull.message') end @@ -20,17 +20,17 @@ module Api head :ok end - private + private # encuentra el sitio a partir de la url - def site + def site @site ||= Site.find_by_name!(params[:site_id]) end # valida el token que envía la plataforma del webhook # # @return [String] - def token + def token @token ||= begin # Gitlab @@ -45,14 +45,14 @@ module Api else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end - end + end end # valida token a partir de firma de webhook # # @return [String, Boolean] def token_from_signature(signature. prepend = '') - payload = request.body.read + payload = request.body.read site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) @@ -61,10 +61,10 @@ module Api end end - # encuentra le usuarie + # encuentra le usuarie def usuarie @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end + end # respuesta de error a plataformas def platforms_answer(exception) @@ -73,4 +73,4 @@ module Api end end end -end \ No newline at end of file +end From 690efe329c571c0d8c601645735d186b7890a572 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:22:57 -0300 Subject: [PATCH 131/814] fix: llamar a los headers consistentemente --- app/controllers/api/v1/webhooks_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index fb4a710c..1d1258fd 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -37,11 +37,11 @@ module Api if request.headers['X-Gitlab-Token'] request.headers['X-Gitlab-Token'] # Github - elsif request.headers['X-HUB-SIGNATURE-256'] - token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256'], 'sha256=') + elsif request.headers['X-Hub-Signature-256'] + token_from_signature(request.headers['X_Hub_Signature_256'], 'sha256=') # Gitea - elsif request.headers['HTTP_X_GITEA_SIGNATURE'] - token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) + elsif request.headers['X_Gitea_Signature'] + token_from_signature(request.headers['X_Gitea_Signature']) else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end From a99e03ce15d13122f36e2aab976fd5229156300e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:23:39 -0300 Subject: [PATCH 132/814] feat: enviar los headers en el reporte --- app/controllers/api/v1/webhooks_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 1d1258fd..6be6c2dc 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -68,8 +68,9 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) + ExceptionNotifier.notify_exception(exception, env: request.env, data: { headers: request.headers.to_h }) + head :forbidden - ExceptionNotifier.notify_exception(exception, env: request.env) end end end From 42e6a0b6eb5432773d2337ed33ac154defd2c042 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:24:33 -0300 Subject: [PATCH 133/814] fix: typo --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 6be6c2dc..ab2fce6b 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -51,7 +51,7 @@ module Api # valida token a partir de firma de webhook # # @return [String, Boolean] - def token_from_signature(signature. prepend = '') + def token_from_signature(signature, prepend = '') payload = request.body.read site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) From b9083c492cd3e50971bbbca9a549b81c4781efe3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:26:39 -0300 Subject: [PATCH 134/814] fix: presencia --- app/controllers/api/v1/webhooks_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index ab2fce6b..23bfae22 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -34,13 +34,13 @@ module Api @token ||= begin # Gitlab - if request.headers['X-Gitlab-Token'] + if request.headers['X-Gitlab-Token'].present? request.headers['X-Gitlab-Token'] # Github - elsif request.headers['X-Hub-Signature-256'] + elsif request.headers['X-Hub-Signature-256'].present? token_from_signature(request.headers['X_Hub_Signature_256'], 'sha256=') # Gitea - elsif request.headers['X_Gitea_Signature'] + elsif request.headers['X_Gitea_Signature'].present? token_from_signature(request.headers['X_Gitea_Signature']) else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' From a2678c3e81f7943368edf9a51e9de80354af603f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:35:36 -0300 Subject: [PATCH 135/814] fix: no ignorar excepciones como record not found --- config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 4cc1cb39..5e089ff9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -142,7 +142,7 @@ Rails.application.configure do } config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl") } - config.middleware.use ExceptionNotification::Rack, gitlab: {}, ignore_exceptions: (['DeployJob::DeployAlreadyRunningException'] + ExceptionNotifier.ignored_exceptions) + config.middleware.use ExceptionNotification::Rack, gitlab: {}, ignore_exceptions: ['DeployJob::DeployAlreadyRunningException'] Rails.application.routes.default_url_options[:host] = "panel.#{ENV.fetch('SUTTY', 'sutty.nl')}" Rails.application.routes.default_url_options[:protocol] = 'https' From ef8ed271d75dd1e4bdf079c11f8bcaf450af25ac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:46:11 -0300 Subject: [PATCH 136/814] fix: consistencia al llamar a headers --- app/controllers/api/v1/webhooks_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 23bfae22..95439cd4 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -38,10 +38,10 @@ module Api request.headers['X-Gitlab-Token'] # Github elsif request.headers['X-Hub-Signature-256'].present? - token_from_signature(request.headers['X_Hub_Signature_256'], 'sha256=') + token_from_signature(request.headers['X-Hub-Signature-256'], 'sha256=') # Gitea - elsif request.headers['X_Gitea_Signature'].present? - token_from_signature(request.headers['X_Gitea_Signature']) + elsif request.headers['X-Gitea-Signature'].present? + token_from_signature(request.headers['X-Gitea-Signature']) else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end From 4a7ac981e5029ce8c23fa0c54c5ba99268dcb3ee Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 17:04:34 -0300 Subject: [PATCH 137/814] fix: no fallar si la firma es nil closes #14089 --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 95439cd4..1730034e 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -55,7 +55,7 @@ module Api payload = request.body.read site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) - ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) + ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s) end.tap do |t| raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil? end From 6bae3a68f167956a7799d1252833ab2f7b0e694a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 17:35:20 -0300 Subject: [PATCH 138/814] feat: enviar cambios luego de commitearlos --- app/services/post_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/post_service.rb b/app/services/post_service.rb index 7b31867d..601915f8 100644 --- a/app/services/post_service.rb +++ b/app/services/post_service.rb @@ -96,6 +96,8 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do remove: action == :destroyed, message: I18n.t("post_service.#{action}", title: post&.title&.value)) + + GitPushJob.perform_later(site) end # Solo permitir cambiar estos atributos de cada articulo From 5a004b1cad1734af695a37d92d4a271603b818f1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 17:35:33 -0300 Subject: [PATCH 139/814] =?UTF-8?q?feat:=20enviar=20configuraci=C3=B3n=20l?= =?UTF-8?q?uego=20de=20comitearla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/site_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 2c29538c..fc82ae84 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -97,6 +97,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do file: site.config.path, message: I18n.t("site_service.#{action}", name: site.name)) + + GitPushJob.perform_later(site) end def add_role(temporal: true, rol: 'invitade') From 1be1977c343a6d6b6a9a379d9414872db9830f8b Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 23 Aug 2023 14:13:25 -0300 Subject: [PATCH 140/814] fix: fix minima design's link to demostration site #14131 --- db/seeds/designs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/seeds/designs.yml b/db/seeds/designs.yml index a04c99c1..46f1cd0d 100644 --- a/db/seeds/designs.yml +++ b/db/seeds/designs.yml @@ -18,7 +18,7 @@ - name_en: 'Minima' name_es: 'Mínima' gem: 'sutty-minima' - url: 'https://0xacab.org/sutty/jekyll/minima' + url: 'https://minima.sutty.nl/' description_en: "Sutty Minima is based on [Minima](https://jekyll.github.io/minima/), a blog-focused theme for Jekyll." description_es: 'Sutty Mínima es una plantilla para blogs basada en [Mínima](https://jekyll.github.io/minima/).' license: 'https://0xacab.org/sutty/jekyll/minima/-/blob/master/LICENSE.txt' From c09dfc3b67fb19a80971aee6e1f36fa5bde0dbae Mon Sep 17 00:00:00 2001 From: f Date: Fri, 25 Aug 2023 10:11:36 -0300 Subject: [PATCH 141/814] ci: force ci to rebuild assets --- app/assets/stylesheets/application.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 65a207fa..eb953c30 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -525,5 +525,3 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } - -// force ci From ef64dbc049c99b63acdbf918c3c37c4407839c5d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 10:48:54 -0300 Subject: [PATCH 142/814] ci: assets [skip ci] --- .../.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json | 3 +++ ...sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json.br | 3 +++ ...771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js | 3 +++ ...691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.br | 3 +++ ...691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.gz | 3 +++ ...b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css | 3 +++ ...06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.br | 3 +++ ...06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.gz | 3 +++ ...e855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg | 3 +++ ...5d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.br | 3 +++ ...5d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.gz | 3 +++ ...a1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css | 3 +++ ...2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.br | 3 +++ ...2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.gz | 3 +++ ...8656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js | 3 +++ ...6a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.br | 3 +++ ...6a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.gz | 3 +++ ...853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png | 3 +++ ...543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png.br | 3 +++ ...8a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff | 3 +++ ...12c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff.br | 3 +++ ...24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot | 3 +++ ...35f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.br | 3 +++ ...35f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.gz | 3 +++ ...9d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg | 3 +++ ...d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.br | 3 +++ ...d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.gz | 3 +++ ...aebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2 | 3 +++ ...d1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2.br | 3 +++ ...e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf | 3 +++ ...169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.br | 3 +++ ...169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.gz | 3 +++ ...dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css | 3 +++ ...7b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.br | 3 +++ ...7b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.gz | 3 +++ ...287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css | 3 +++ ...b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.br | 3 +++ ...b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.gz | 3 +++ ...9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png | 3 +++ ...0df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png.br | 3 +++ ...54162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png | 3 +++ ...62eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png.br | 3 +++ ...413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png | 3 +++ ...b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png.br | 3 +++ ...0eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png | 3 +++ ...e9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png.br | 3 +++ ...66af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js | 3 +++ ...f0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.br | 3 +++ ...f0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.gz | 3 +++ ...3c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png | 3 +++ ...6cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png.br | 3 +++ ...c4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png | 3 +++ ...a0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png.br | 3 +++ ...a198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png | 3 +++ ...8f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png.br | 3 +++ ...ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2 | 3 +++ ...684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2.br | 3 +++ ...0de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff | 3 +++ ...8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff.br | 3 +++ ...b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2 | 3 +++ ...358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2.br | 3 +++ ...6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff | 3 +++ ...1cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff.br | 3 +++ ...da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg | 3 +++ ...3a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.br | 3 +++ ...3a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.gz | 3 +++ ...70c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png | 3 +++ ...82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png.br | 3 +++ public/packs/css/application-7d15ae94.css | 3 +++ public/packs/css/application-7d15ae94.css.br | 3 +++ public/packs/css/application-7d15ae94.css.br.br | 3 +++ public/packs/css/application-7d15ae94.css.gz | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js | 3 +++ .../packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt | 3 +++ .../js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz | 3 +++ public/packs/manifest.json | 3 +++ public/packs/manifest.json.br | 3 +++ public/packs/manifest.json.br.br | 3 +++ public/packs/manifest.json.gz | 3 +++ public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff | 3 +++ public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br | 3 +++ public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2 | 3 +++ public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br | 3 +++ public/packs/media/fonts/forkawesome-webfont-86541105.svg | 3 +++ public/packs/media/fonts/forkawesome-webfont-86541105.svg.br | 3 +++ .../packs/media/fonts/forkawesome-webfont-86541105.svg.br.br | 3 +++ public/packs/media/fonts/forkawesome-webfont-86541105.svg.gz | 3 +++ public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot | 3 +++ public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br | 3 +++ .../packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br | 3 +++ public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.gz | 3 +++ public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf | 3 +++ public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br | 3 +++ .../packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br | 3 +++ public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.gz | 3 +++ public/packs/media/images/layers-2x-8f2c4d11.png | 3 +++ public/packs/media/images/layers-2x-8f2c4d11.png.br | 3 +++ public/packs/media/images/layers-416d9136.png | 3 +++ public/packs/media/images/layers-416d9136.png.br | 3 +++ public/packs/media/images/marker-icon-2b3e1faf.png | 3 +++ public/packs/media/images/marker-icon-2b3e1faf.png.br | 3 +++ public/packs/media/images/marker-icon-2x-680f69f3.png | 3 +++ public/packs/media/images/marker-icon-2x-680f69f3.png.br | 3 +++ public/packs/media/images/marker-shadow-a0c6cc14.png | 3 +++ public/packs/media/images/marker-shadow-a0c6cc14.png.br | 3 +++ 112 files changed, 336 insertions(+) create mode 100644 public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json create mode 100644 public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json.br create mode 100644 public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js create mode 100644 public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.br create mode 100644 public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.gz create mode 100644 public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css create mode 100644 public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.br create mode 100644 public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.gz create mode 100644 public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg create mode 100644 public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.br create mode 100644 public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.gz create mode 100644 public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css create mode 100644 public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.br create mode 100644 public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.gz create mode 100644 public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js create mode 100644 public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.br create mode 100644 public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.gz create mode 100644 public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png create mode 100644 public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png.br create mode 100644 public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff create mode 100644 public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff.br create mode 100644 public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot create mode 100644 public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.br create mode 100644 public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.gz create mode 100644 public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg create mode 100644 public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.br create mode 100644 public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.gz create mode 100644 public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2 create mode 100644 public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2.br create mode 100644 public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf create mode 100644 public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.br create mode 100644 public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.gz create mode 100644 public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css create mode 100644 public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.br create mode 100644 public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.gz create mode 100644 public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css create mode 100644 public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.br create mode 100644 public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.gz create mode 100644 public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png create mode 100644 public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png.br create mode 100644 public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png create mode 100644 public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png.br create mode 100644 public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png create mode 100644 public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png.br create mode 100644 public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png create mode 100644 public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png.br create mode 100644 public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js create mode 100644 public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.br create mode 100644 public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.gz create mode 100644 public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png create mode 100644 public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png.br create mode 100644 public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png create mode 100644 public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png.br create mode 100644 public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png create mode 100644 public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png.br create mode 100644 public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2 create mode 100644 public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2.br create mode 100644 public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff create mode 100644 public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff.br create mode 100644 public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2 create mode 100644 public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2.br create mode 100644 public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff create mode 100644 public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff.br create mode 100644 public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg create mode 100644 public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.br create mode 100644 public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.gz create mode 100644 public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png create mode 100644 public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png.br create mode 100644 public/packs/css/application-7d15ae94.css create mode 100644 public/packs/css/application-7d15ae94.css.br create mode 100644 public/packs/css/application-7d15ae94.css.br.br create mode 100644 public/packs/css/application-7d15ae94.css.gz create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br create mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz create mode 100644 public/packs/manifest.json create mode 100644 public/packs/manifest.json.br create mode 100644 public/packs/manifest.json.br.br create mode 100644 public/packs/manifest.json.gz create mode 100644 public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff create mode 100644 public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2 create mode 100644 public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-86541105.svg create mode 100644 public/packs/media/fonts/forkawesome-webfont-86541105.svg.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-86541105.svg.gz create mode 100644 public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot create mode 100644 public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.gz create mode 100644 public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf create mode 100644 public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br create mode 100644 public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.gz create mode 100644 public/packs/media/images/layers-2x-8f2c4d11.png create mode 100644 public/packs/media/images/layers-2x-8f2c4d11.png.br create mode 100644 public/packs/media/images/layers-416d9136.png create mode 100644 public/packs/media/images/layers-416d9136.png.br create mode 100644 public/packs/media/images/marker-icon-2b3e1faf.png create mode 100644 public/packs/media/images/marker-icon-2b3e1faf.png.br create mode 100644 public/packs/media/images/marker-icon-2x-680f69f3.png create mode 100644 public/packs/media/images/marker-icon-2x-680f69f3.png.br create mode 100644 public/packs/media/images/marker-shadow-a0c6cc14.png create mode 100644 public/packs/media/images/marker-shadow-a0c6cc14.png.br diff --git a/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json new file mode 100644 index 00000000..862103e6 --- /dev/null +++ b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abb17ebe7d32c8d1bc90cc26c95cd99188a8ea066d8c975834b8299b7297f157 +size 11872 diff --git a/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json.br b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json.br new file mode 100644 index 00000000..98bb90ad --- /dev/null +++ b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e0106b0b4c59585bab8c4f20fcf9026a22ffcd845ce281a3ff6879b905edfe8 +size 4003 diff --git a/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js b/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js new file mode 100644 index 00000000..cbde635a --- /dev/null +++ b/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1aa76e929b6ee4e3bab1734223a46c0d22a1cf2425d2e028c3075528436171dc +size 33422 diff --git a/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.br b/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.br new file mode 100644 index 00000000..89860cb3 --- /dev/null +++ b/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2a65b9d05b5f692ad4199c5aa612e13b165e68b4a1330ee7c60a414fd5a8cbf +size 6541 diff --git a/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.gz b/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.gz new file mode 100644 index 00000000..00389f1a --- /dev/null +++ b/public/assets/activestorage-9f749d32771691cb3104d21c1c9926e52c04c48d8730498df4aaa39b0adfb7ba.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6dcef6c2e458d817696a109d51b14564902cf9c50606b7f8adf522ea6d03bec +size 6899 diff --git a/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css b/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css new file mode 100644 index 00000000..f3f0e72f --- /dev/null +++ b/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45b58cea6de408b3b9e666b149e9cb5aae3f3669d6bd3587def372af51e9ec9c +size 531463 diff --git a/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.br b/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.br new file mode 100644 index 00000000..cfb849ef --- /dev/null +++ b/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:587c4692885409e7bf9eec2ae7a47eb1954b86f14d4e25a42403663d4d59b268 +size 35024 diff --git a/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.gz b/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.gz new file mode 100644 index 00000000..6d8cbce0 --- /dev/null +++ b/public/assets/application-dc5234b33b6c06db79ab79114f5b85952f35482ce5b97061ce9402b2a8a4cd19.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2997bf3c615d602a40238b3ab474034918f4837d88c7f55fec818fda8ea31f17 +size 42896 diff --git a/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg b/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg new file mode 100644 index 00000000..2a7f2458 --- /dev/null +++ b/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92f2db633d3e9611dc07743d7267204c40de2f8d75b9fa7e0646b195541f2d53 +size 571 diff --git a/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.br b/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.br new file mode 100644 index 00000000..fe5ef2ad --- /dev/null +++ b/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66f6cc7289f2ab65e5c05f470dc61b62d3b67dfc6b02111f7ac608da9f371273 +size 323 diff --git a/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.gz b/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.gz new file mode 100644 index 00000000..f5afff36 --- /dev/null +++ b/public/assets/arrows-alt-v-89a34626be855d3b1c3199cd75f62cf6327678eed1e126f74b7cbc6de3502606.svg.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f690800fb0f0e2ce7b86b2564f2b4521030854c3eb13ccad730911181b906a1e +size 359 diff --git a/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css b/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css new file mode 100644 index 00000000..d065b1d6 --- /dev/null +++ b/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbc16a398c527ae16bd978e4c16f5803989f3025be59e35332a0547a57eae668 +size 161257 diff --git a/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.br b/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.br new file mode 100644 index 00000000..1c55ad41 --- /dev/null +++ b/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:669ad50ad737f1d4f996854f4da308c78dee7766e6bbfde1df609fd72502f56b +size 22772 diff --git a/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.gz b/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.gz new file mode 100644 index 00000000..bb2ecb25 --- /dev/null +++ b/public/assets/blazer/application-59c73da0ca1f2fd8dd42765f0a172ae513546920ad9fa0718c15d9b10a4f18dd.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab6c28f79b9b9a72deb9c4d8247f2f481e0e7c769f063d63a195d31c1fc40c37 +size 25170 diff --git a/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js b/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js new file mode 100644 index 00000000..14b3990b --- /dev/null +++ b/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32ff6af566ab140819899b0fea350b80fdf527efbe30aadb14cac437e2bc01fb +size 9 diff --git a/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.br b/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.br new file mode 100644 index 00000000..9e09ad94 --- /dev/null +++ b/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b3fb497058b6fbc2560ef56b4e38cd96fa5537289c45fbbfe090f23c8b1161e +size 14 diff --git a/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.gz b/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.gz new file mode 100644 index 00000000..0a26fc68 --- /dev/null +++ b/public/assets/blazer/application-f14294068656a14630709493ca1bdd375b16209db5d3307d61c4927dd3eff3c5.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8cd6192edf216bb14ad01dcf0d7a164e3c8e759376d51528907fe0bcde2b781 +size 29 diff --git a/public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png b/public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png new file mode 100644 index 00000000..f275a453 --- /dev/null +++ b/public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:392743107d0d14fea5699cff1e80d209db7058ef660e643ff9c9f07e990ac084 +size 320 diff --git a/public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png.br b/public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png.br new file mode 100644 index 00000000..4290fce9 --- /dev/null +++ b/public/assets/blazer/favicon-ccead91b8853543a3542af03c7dde9963359b1c0b9b725220a7f193e1324ecd8.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42f1101a87e305093c8326571f6eba5e2f647183f15922b68b511f13e172908d +size 248 diff --git a/public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff b/public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff new file mode 100644 index 00000000..334f2da2 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a26394f7ede100ca118eff2eda08596275a9839b959c226e15439557a5a80742 +size 23424 diff --git a/public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff.br b/public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff.br new file mode 100644 index 00000000..5acfec3d --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-0703369a358a012c0011843ae337a8a20270c336948a8668df5cb89a8827299b.woff.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ee84e264080ea5f4f7f23ae9c8aa8f138621b4a4dbbb86f3c839da28b0e5a56 +size 23116 diff --git a/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot b/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot new file mode 100644 index 00000000..42ea705f --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13634da87d9e23f8c3ed9108ce1724d183a39ad072e73e1b3d8cbf646d2d0407 +size 20127 diff --git a/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.br b/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.br new file mode 100644 index 00000000..558ceb52 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1a2ea6dc4d0790cede399727cf57dc55dd126e3886e756559cef13f897c6dd0 +size 20012 diff --git a/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.gz b/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.gz new file mode 100644 index 00000000..44d30965 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-0805fb1fe24235f70a639f67514990e4bfb6d2cfb00ca563ad4b553c240ddc33.eot.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:232dfba09dd29cfeff9e075a9ba30ed192f678b5946c1a1ec022e9887cc1dc8f +size 20056 diff --git a/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg b/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg new file mode 100644 index 00000000..781641cc --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42f60659d265c1a3c30f9fa42abcbb56bd4a53af4d83d316d6dd7a36903c43e5 +size 108738 diff --git a/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.br b/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.br new file mode 100644 index 00000000..63ae3b6c --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51506970c9012e0474056ff17ff204bf0f1782c547c6fb3dfb584e1572b1b1c5 +size 24800 diff --git a/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.gz b/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.gz new file mode 100644 index 00000000..49a5ccf2 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-22d0c88a49d7d0ebe45627143a601061a32a46a9b9afd2dc7f457436f5f15f6e.svg.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2879447637c85f780c62c9decfdc9b6847dfddc0c353ecf056a5563afd5d98c0 +size 26508 diff --git a/public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2 b/public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2 new file mode 100644 index 00000000..3336ba11 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe185d11a49676890d47bb783312a0cda5a44c4039214094e7957b4c040ef11c +size 18028 diff --git a/public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2.br b/public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2.br new file mode 100644 index 00000000..2968e5d2 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-403acfcf0cbaebd1c28b404eec442cea53642644b3a73f91c5a4ab46859af772.woff2.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7b1a9608c41733d8a73d73c31348a3ab34df13dd8f69cf5dc6eb918a14f7bd4 +size 18016 diff --git a/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf b/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf new file mode 100644 index 00000000..233386da --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e395044093757d82afcb138957d06a1ea9361bdcf0b442d06a18a8051af57456 +size 45404 diff --git a/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.br b/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.br new file mode 100644 index 00000000..2f238f1e --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83d0181bfdb29d3744dbc122e63263657dcfa359fbd8a4f2cd915b2ee49d3fbe +size 22714 diff --git a/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.gz b/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.gz new file mode 100644 index 00000000..e77b3e37 --- /dev/null +++ b/public/assets/blazer/glyphicons-halflings-regular-7c9caa5f4e16169b0129fdf93c84e85ad14d6c107eb1b0ad60b542daf01ee1f0.ttf.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0668c774700aef315f25dcf8376be7aa88eec8b609b47f37c9ba53bbdb997ee +size 23360 diff --git a/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css b/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css new file mode 100644 index 00000000..377ab667 --- /dev/null +++ b/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0b95902009200f525c963c605b9ffa600ea673860dae9f43f33bc557257182b +size 3562 diff --git a/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.br b/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.br new file mode 100644 index 00000000..df162533 --- /dev/null +++ b/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9700c118f5e2df28e708aa79143d9135e0b7e67874ab3c976cd604d8a3beff9e +size 738 diff --git a/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.gz b/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.gz new file mode 100644 index 00000000..2b210f57 --- /dev/null +++ b/public/assets/editor-6ceecb9d2dc47b39b99575e60bc2c9eec573a495812d521ec5b82dedd4f55807.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0122fcc56f8dc98299e779bd5b3b2960c6d3e3535b0da3265765ca136268a8f +size 846 diff --git a/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css b/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css new file mode 100644 index 00000000..92436ec6 --- /dev/null +++ b/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:053af9006ae009bec81ce6b0403cff779891708d6b446684fb7870ac5bacb462 +size 839 diff --git a/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.br b/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.br new file mode 100644 index 00000000..430e9dd8 --- /dev/null +++ b/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fb27aaf2a70e5353771f5b1a3deb39506c97438f74930dbde35137a3370735c +size 340 diff --git a/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.gz b/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.gz new file mode 100644 index 00000000..2e6771be --- /dev/null +++ b/public/assets/fonts-86ce817a6287b9ff301be232f102b66152dd83f264e13a531098d8dc8b1398da.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e005f190d04b1bccc984df0b54ea772eb13fd97c813075f4b2e9c39fab2cc35 +size 390 diff --git a/public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png b/public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png new file mode 100644 index 00000000..e882b8bc --- /dev/null +++ b/public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a0acd631fd5704e940b9f486d3234aa9ab871881733f48d6edd3cb1f1a09ffc +size 144 diff --git a/public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png.br b/public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png.br new file mode 100644 index 00000000..ca08d316 --- /dev/null +++ b/public/assets/icon_external_link-1af8262ac9c00df26e81bc5a33bcf64350729f954b85f82d5e759fffec4e183a.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c50779d6d93ea71b10be4972af879e611353812b40f566d864f189218129cf9 +size 149 diff --git a/public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png b/public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png new file mode 100644 index 00000000..7b44754c --- /dev/null +++ b/public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dbbe9d028e292f36fcba8f8b3a28d5e8932754fc2215b9ac69e4cdecf5107c6 +size 696 diff --git a/public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png.br b/public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png.br new file mode 100644 index 00000000..21812b3e --- /dev/null +++ b/public/assets/layers-0e356f4d554162eb71f127f50460dbc55d405027189ebe90b20729ef18d13d36.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e255d97d12f227f9d2fabd481fa56d89bf33b47a4d108b031e7b96ddc0fb0066 +size 701 diff --git a/public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png b/public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png new file mode 100644 index 00000000..d3cf7e52 --- /dev/null +++ b/public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:066daca850d8ffbef007af00b06eac0015728dee279c51f3cb6c716df7c42edf +size 1259 diff --git a/public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png.br b/public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png.br new file mode 100644 index 00000000..cda7f53d --- /dev/null +++ b/public/assets/layers-2x-ba8fa601e413b14db27db07285ade3951721e02244c31523284ab2d1ed53c3dc.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47119b2b0eb7d15fa47527efc1fa04713d80990ed6a7f2e2f58f91a8cddd1b03 +size 1264 diff --git a/public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png b/public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png new file mode 100644 index 00000000..be79dc74 --- /dev/null +++ b/public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abab4950f459ebf3f475d376d6fd468e735cab2d86c712222fa586569a273a09 +size 2001 diff --git a/public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png.br b/public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png.br new file mode 100644 index 00000000..5fce7f8e --- /dev/null +++ b/public/assets/logo-e11ab53230eae9497ea201f3ad57549af343ddc1d24ddc78b055627cf14e9d5d.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:348d75dc528dbaff2a18adb6f4a4b66d4610e6dca2f99889b52e7f0c629a8be7 +size 2006 diff --git a/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js b/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js new file mode 100644 index 00000000..7a77a071 --- /dev/null +++ b/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a3cf5192354f71615ac51034b3e97c20eda99643fcaf5bbe6d41ad59bd12167 +size 3 diff --git a/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.br b/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.br new file mode 100644 index 00000000..40a6d1ac --- /dev/null +++ b/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad41782cd73052ce3e59ea9b261ffeeeebfbacaa90924c01c7c47f012674bb15 +size 8 diff --git a/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.gz b/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.gz new file mode 100644 index 00000000..884f1518 --- /dev/null +++ b/public/assets/manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19a332fca5af4a8c3ee68386360b5212428611709c8463c00631d65141b8f5bb +size 23 diff --git a/public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png b/public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png new file mode 100644 index 00000000..09e8445f --- /dev/null +++ b/public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00179c4c1ee830d3a108412ae0d294f55776cfeb085c60129a39aa6fc4ae2528 +size 2464 diff --git a/public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png.br b/public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png.br new file mode 100644 index 00000000..585d2e48 --- /dev/null +++ b/public/assets/marker-icon-2x-091245b393c16cdcefe54920aa7d3994a0683317ca9a58d35cbc5ec65996398c.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4f6ce09c4c3a59cfac5c03a03de02b170d35cfefd7e1247a317dc772c889395 +size 2469 diff --git a/public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png b/public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png new file mode 100644 index 00000000..b1789c76 --- /dev/null +++ b/public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:574c3a5cca85f4114085b6841596d62f00d7c892c7b03f28cbfa301deb1dc437 +size 1466 diff --git a/public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png.br b/public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png.br new file mode 100644 index 00000000..62bba2a0 --- /dev/null +++ b/public/assets/marker-icon-3d253116ec4ba0e1f22a01cdf1ff7f120fa4d89a6cd0933d68f12951d19809b4.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d73a1e81d4d7b880342c1fa48caeb6cdb56cc941ad18000d932dfaec8ba1086 +size 1471 diff --git a/public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png b/public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png new file mode 100644 index 00000000..dc111216 --- /dev/null +++ b/public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:264f5c640339f042dd729062cfc04c17f8ea0f29882b538e3848ed8f10edb4da +size 618 diff --git a/public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png.br b/public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png.br new file mode 100644 index 00000000..940c4d9b --- /dev/null +++ b/public/assets/marker-shadow-a2d94406ba198f61f68a71ed8f9f9c701122c0c33b775d990edceae4aece567f.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8758eb0644225f0a3c8e03fb1dbe319f6427b4116a538084f18ba5a6dcd65eb2 +size 623 diff --git a/public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2 b/public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2 new file mode 100644 index 00000000..580c899c --- /dev/null +++ b/public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ad13d7b01c301feecfb7f760791100710930be2d232fcdf97fb09a1301e4c3e +size 16264 diff --git a/public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2.br b/public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2.br new file mode 100644 index 00000000..ab0b6472 --- /dev/null +++ b/public/assets/saira/v3/SairaBold-subset-0c1968b6a54ea5684d70cc5b51fb1ae3186386fe9363bf3edaf01663ac641341.woff2.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a45bda0673da257af77f89c6d9151c908dd15dae3eeb536911be81383e58e42 +size 16260 diff --git a/public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff b/public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff new file mode 100644 index 00000000..94528fe4 --- /dev/null +++ b/public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd722d9eb3a725f4188615c514c5c0e6b1b82de55a00dca194efa84704257dd2 +size 20120 diff --git a/public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff.br b/public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff.br new file mode 100644 index 00000000..38204fe0 --- /dev/null +++ b/public/assets/saira/v3/SairaBold-subset.zopfli-2d3f8769110de8d5709d5162dbf0dcb9ab8df71e55f63cfd986bdb68ee2ade0b.woff.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d58d08fffad848dc745108c011fe0b71bdfa14d11d17d68d514205970726bd5 +size 20055 diff --git a/public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2 b/public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2 new file mode 100644 index 00000000..7127bebe --- /dev/null +++ b/public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ac4573ca9ed8e08a742d203171057acc3d8f5f49825d9351bd2a22c2d58e669 +size 16388 diff --git a/public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2.br b/public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2.br new file mode 100644 index 00000000..2d4a45ab --- /dev/null +++ b/public/assets/saira/v3/SairaMedium-subset-6d53d976d73b86358489cb76fc34ec0683d57a1b2635c43acbae45be3349d976.woff2.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92f6b5c4fd4dabbbedbc96519088b4896dbe07b393d06bbbb868d82a618d352a +size 16391 diff --git a/public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff b/public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff new file mode 100644 index 00000000..bb8a3825 --- /dev/null +++ b/public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dec398a6c292da28349e76f94646d91d425cf4ddc7f91d749075f72209d0dab +size 20232 diff --git a/public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff.br b/public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff.br new file mode 100644 index 00000000..6da047e7 --- /dev/null +++ b/public/assets/saira/v3/SairaMedium-subset.zopfli-47d24dd6cc6451cd2fb3803333f4de3e11033437aa0c8d3d06edcb19e4e38ecb.woff.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2a22be46135bb21d4984271f8dd42e6762a35152fba61f93ce89edd6478df23 +size 20174 diff --git a/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg b/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg new file mode 100644 index 00000000..68fca50c --- /dev/null +++ b/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb86744bcec2d691c94d431627e412113f3648eb02420f2af86de3e3884c5a6d +size 1956 diff --git a/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.br b/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.br new file mode 100644 index 00000000..bbf3b21e --- /dev/null +++ b/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb20639b4ce178eedfc586c73f7086bef65ef70533c995afdc2eedb3d1fa76c4 +size 894 diff --git a/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.gz b/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.gz new file mode 100644 index 00000000..dffee65e --- /dev/null +++ b/public/assets/sutty-08b30df17da83a32911e3bb4fa0a2c967148a2f98020a63b6c171c17c94bf05d.svg.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19973f783284df5608ec79a4fa46dce362f5626112c218266f04329b01049c43 +size 943 diff --git a/public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png b/public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png new file mode 100644 index 00000000..1b018802 --- /dev/null +++ b/public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56aa311c3c5249e54d70f03b33fc681b593cd93e74b7af5d80316c5b7d1c6a76 +size 6868 diff --git a/public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png.br b/public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png.br new file mode 100644 index 00000000..727045b0 --- /dev/null +++ b/public/assets/sutty_cuadrada-547911cb970c82f2bf8fa2d68b3b32e5e2a1c0ed787dafa6ea1b98b52b96328f.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8af682a97967a339d63b8c22a24ab30065e9423e1775e6c6ccdf662e5081a4f9 +size 6530 diff --git a/public/packs/css/application-7d15ae94.css b/public/packs/css/application-7d15ae94.css new file mode 100644 index 00000000..544ddf74 --- /dev/null +++ b/public/packs/css/application-7d15ae94.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0179eec59d4881001e3d26ec0e25d8ca1257c6e4956d76f18cc97c3325a9625 +size 48029 diff --git a/public/packs/css/application-7d15ae94.css.br b/public/packs/css/application-7d15ae94.css.br new file mode 100644 index 00000000..c0e44938 --- /dev/null +++ b/public/packs/css/application-7d15ae94.css.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f9a030d083e92a55a9a9211539c894371f200778de283958a318c87a825cb4f +size 10934 diff --git a/public/packs/css/application-7d15ae94.css.br.br b/public/packs/css/application-7d15ae94.css.br.br new file mode 100644 index 00000000..bd3a0882 --- /dev/null +++ b/public/packs/css/application-7d15ae94.css.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c61a1f5c9ca9cfc7b2b314046b258a94f707535a34e0c3e7b621d9b7c2cd648 +size 10939 diff --git a/public/packs/css/application-7d15ae94.css.gz b/public/packs/css/application-7d15ae94.css.gz new file mode 100644 index 00000000..306dc931 --- /dev/null +++ b/public/packs/css/application-7d15ae94.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfeb6b9af353618bdc475d6c921197da2b8a9ae7685a91772658d41883843c12 +size 12022 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js new file mode 100644 index 00000000..b6dc46a3 --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0322257341b6d5bcbee0153eb5007363aefe26870b63744de6f1cdf6d1a7065e +size 1134731 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt new file mode 100644 index 00000000..89f0cf4f --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a016dd85be9a400040f4440d2ce1a94524f6e885a3d0e1f2422b46c2397df38f +size 629 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br new file mode 100644 index 00000000..3b0be40c --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46eca40f00a3261e41a1e02d89697deb163a49a56237e72ae2643cb1c28b99c0 +size 307 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br new file mode 100644 index 00000000..6ba2a97b --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b88ebe0dd46c4b22fea0ecccb721afc5b4a88ce4b55950bce19654c2d265f72e +size 302355 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br new file mode 100644 index 00000000..93ce3091 --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ed407a10485f5157d5eb98bc11a158c2565bc417faedaa197bdfcea486ccdcd +size 302363 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz new file mode 100644 index 00000000..a978f9f3 --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ed777e669bf1e81dd7f43ff8d9c2d5d5b4c9d81c68a1fac7b7fdd3d7d578b30 +size 329294 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map new file mode 100644 index 00000000..ab3aa8ef --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02a1682a2421fd6f340241bbc6b07951aa583f2ef2b74f29fb16cf9aaf3956a0 +size 4658473 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br new file mode 100644 index 00000000..ca0133f3 --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3ef78d7fb35e3c0547740d68249462805e7cf65eafd3b6f77b787e7746c1f14 +size 1099488 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br new file mode 100644 index 00000000..dd2dcd4a --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cda688a8dbd865c4720c68f2af7c8e1130cd43a955c737da9f4f38296b2d6d56 +size 1099496 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz new file mode 100644 index 00000000..38ab8f51 --- /dev/null +++ b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f18506f9e0cec6f8a84d2a640646b6bae20eeeea081aba5ba26324028ffae8c2 +size 1222748 diff --git a/public/packs/manifest.json b/public/packs/manifest.json new file mode 100644 index 00000000..f3fcbef3 --- /dev/null +++ b/public/packs/manifest.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:880db5bc10cd865a8cb1a2fc56d69bba8464ef28aa59c31913256c7062528289 +size 1426 diff --git a/public/packs/manifest.json.br b/public/packs/manifest.json.br new file mode 100644 index 00000000..82077c62 --- /dev/null +++ b/public/packs/manifest.json.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8cfa3712c659f01703314a2a9dd306a55d0f52a3456e20d43e080a5d716c8e45 +size 325 diff --git a/public/packs/manifest.json.br.br b/public/packs/manifest.json.br.br new file mode 100644 index 00000000..b8d746ce --- /dev/null +++ b/public/packs/manifest.json.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82c427cf2556c027323f463d5d735bc8dd3b2b22ac1d5eed3e7d77b3f1cc9178 +size 330 diff --git a/public/packs/manifest.json.gz b/public/packs/manifest.json.gz new file mode 100644 index 00000000..dd2dc7c2 --- /dev/null +++ b/public/packs/manifest.json.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aee952354edb8ae47a200f1059beaf3ab588f0fef6e60dcd983de8808ed3351 +size 365 diff --git a/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff b/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff new file mode 100644 index 00000000..8925c5d3 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53ab31062cf740aa76615d2c98aea80b177845d7ed95de45889b3824b0e1597c +size 115148 diff --git a/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br b/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br new file mode 100644 index 00000000..df2c95b5 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90b60c42bcbd106f5658710acd84f60307a00f0de10b921eeb5627590b429858 +size 115153 diff --git a/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2 b/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2 new file mode 100644 index 00000000..52865bdb --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84422de97eb1cf27bcb9bca4f3fbb18f3ebc711647b09c68292f5f43c89d5064 +size 91624 diff --git a/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br b/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br new file mode 100644 index 00000000..1d640da9 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a76b02ceece82f286d306ed0988f8c220066ecce509241a425245950e4e4c839 +size 91629 diff --git a/public/packs/media/fonts/forkawesome-webfont-86541105.svg b/public/packs/media/fonts/forkawesome-webfont-86541105.svg new file mode 100644 index 00000000..af45aadc --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-86541105.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:505e7f9fe61ba6d17d8514b5d0c3a75166dab1b57527e2d3a3baf2047624ba93 +size 480784 diff --git a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br new file mode 100644 index 00000000..bad26711 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7aee80d4013bd5a42f4035b0dc08a2fc903dae87f04182d9a86db53b95c9add +size 143247 diff --git a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br new file mode 100644 index 00000000..344bb103 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e03d221ca2c49b7099c550f8f33462365d285809e5a0b1e000c6c52e6982996a +size 143252 diff --git a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.gz b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.gz new file mode 100644 index 00000000..0676bab5 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49664085aa6a37335724f0288531562f352e81d10fdfeadd4a8ed0764eae2f50 +size 160947 diff --git a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot new file mode 100644 index 00000000..37e93df5 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d96fdd7d6854cf875ce3090e017b0078ae2f7e923763bcbb90748a01c6fb7fd +size 188946 diff --git a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br new file mode 100644 index 00000000..22d6e19f --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4283befabbc5c3bfec093dd89b65ad0063a3581e45bbfbaf9b40a4d178cd5e1 +size 110762 diff --git a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br new file mode 100644 index 00000000..e6ebb6ac --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2adacd487b97dcd4da3bc37328482c809a0d910353990de13b228dd1aa4710a +size 110767 diff --git a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.gz b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.gz new file mode 100644 index 00000000..5bb32cdc --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:413b68fbd4bc71d5aa98410c6f8048f971b55e7d824180d0fab665cc55c3d9a3 +size 115772 diff --git a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf new file mode 100644 index 00000000..e6380d0e --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e4beb40f0cc19ec55f2ab741d42e806fc6155ccf6e40e50965196c0bcc6aba4 +size 188756 diff --git a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br new file mode 100644 index 00000000..87ab54e0 --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e01bc03dc20b0d760488b20f4f5a408dddd0554fb8c23d7ace34ab1698c4c807 +size 110703 diff --git a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br new file mode 100644 index 00000000..e633502b --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3d7e97443577de6e23b5936de2e1a6f35d9e6335b069d8071e6269afc78246 +size 110708 diff --git a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.gz b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.gz new file mode 100644 index 00000000..44d9de5a --- /dev/null +++ b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26c357b09eb784753afcd35a1aa47fe65378a52c95db0496e98dfb999c9ab1b8 +size 115685 diff --git a/public/packs/media/images/layers-2x-8f2c4d11.png b/public/packs/media/images/layers-2x-8f2c4d11.png new file mode 100644 index 00000000..d3cf7e52 --- /dev/null +++ b/public/packs/media/images/layers-2x-8f2c4d11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:066daca850d8ffbef007af00b06eac0015728dee279c51f3cb6c716df7c42edf +size 1259 diff --git a/public/packs/media/images/layers-2x-8f2c4d11.png.br b/public/packs/media/images/layers-2x-8f2c4d11.png.br new file mode 100644 index 00000000..cda7f53d --- /dev/null +++ b/public/packs/media/images/layers-2x-8f2c4d11.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47119b2b0eb7d15fa47527efc1fa04713d80990ed6a7f2e2f58f91a8cddd1b03 +size 1264 diff --git a/public/packs/media/images/layers-416d9136.png b/public/packs/media/images/layers-416d9136.png new file mode 100644 index 00000000..7b44754c --- /dev/null +++ b/public/packs/media/images/layers-416d9136.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dbbe9d028e292f36fcba8f8b3a28d5e8932754fc2215b9ac69e4cdecf5107c6 +size 696 diff --git a/public/packs/media/images/layers-416d9136.png.br b/public/packs/media/images/layers-416d9136.png.br new file mode 100644 index 00000000..21812b3e --- /dev/null +++ b/public/packs/media/images/layers-416d9136.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e255d97d12f227f9d2fabd481fa56d89bf33b47a4d108b031e7b96ddc0fb0066 +size 701 diff --git a/public/packs/media/images/marker-icon-2b3e1faf.png b/public/packs/media/images/marker-icon-2b3e1faf.png new file mode 100644 index 00000000..b1789c76 --- /dev/null +++ b/public/packs/media/images/marker-icon-2b3e1faf.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:574c3a5cca85f4114085b6841596d62f00d7c892c7b03f28cbfa301deb1dc437 +size 1466 diff --git a/public/packs/media/images/marker-icon-2b3e1faf.png.br b/public/packs/media/images/marker-icon-2b3e1faf.png.br new file mode 100644 index 00000000..62bba2a0 --- /dev/null +++ b/public/packs/media/images/marker-icon-2b3e1faf.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d73a1e81d4d7b880342c1fa48caeb6cdb56cc941ad18000d932dfaec8ba1086 +size 1471 diff --git a/public/packs/media/images/marker-icon-2x-680f69f3.png b/public/packs/media/images/marker-icon-2x-680f69f3.png new file mode 100644 index 00000000..09e8445f --- /dev/null +++ b/public/packs/media/images/marker-icon-2x-680f69f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00179c4c1ee830d3a108412ae0d294f55776cfeb085c60129a39aa6fc4ae2528 +size 2464 diff --git a/public/packs/media/images/marker-icon-2x-680f69f3.png.br b/public/packs/media/images/marker-icon-2x-680f69f3.png.br new file mode 100644 index 00000000..585d2e48 --- /dev/null +++ b/public/packs/media/images/marker-icon-2x-680f69f3.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4f6ce09c4c3a59cfac5c03a03de02b170d35cfefd7e1247a317dc772c889395 +size 2469 diff --git a/public/packs/media/images/marker-shadow-a0c6cc14.png b/public/packs/media/images/marker-shadow-a0c6cc14.png new file mode 100644 index 00000000..dc111216 --- /dev/null +++ b/public/packs/media/images/marker-shadow-a0c6cc14.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:264f5c640339f042dd729062cfc04c17f8ea0f29882b538e3848ed8f10edb4da +size 618 diff --git a/public/packs/media/images/marker-shadow-a0c6cc14.png.br b/public/packs/media/images/marker-shadow-a0c6cc14.png.br new file mode 100644 index 00000000..940c4d9b --- /dev/null +++ b/public/packs/media/images/marker-shadow-a0c6cc14.png.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8758eb0644225f0a3c8e03fb1dbe319f6427b4116a538084f18ba5a6dcd65eb2 +size 623 From c6c638fb60edf3d8f7a6eddbc7dab819b01e1d15 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 29 Aug 2023 17:43:19 -0300 Subject: [PATCH 143/814] feat: almacenar la llave privada --- app/models/site.rb | 1 + app/models/site/social_distributed_press.rb | 12 ++++++++++++ ...204127_add_private_key_pem_ciphertext_to_sites.rb | 9 +++++++++ 3 files changed, 22 insertions(+) create mode 100644 app/models/site/social_distributed_press.rb create mode 100644 db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..9ec21561 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -10,6 +10,7 @@ class Site < ApplicationRecord include Site::DeployDependencies include Site::BuildStats include Site::LayoutOrdering + include Site::SocialDistributedPress include Tienda # Cifrar la llave privada que cifra y decifra campos ocultos. Sutty diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb new file mode 100644 index 00000000..9d283103 --- /dev/null +++ b/app/models/site/social_distributed_press.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Site + # Agrega soporte para Social Distributed Press en los sitios + module SocialDistributedPress + extend ActiveSupport::Concern + + included do + encrypts :private_key_pem + end + end +end diff --git a/db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb b/db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb new file mode 100644 index 00000000..9f26f21a --- /dev/null +++ b/db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Almacena las llaves privadas de cada sitio +class AddPrivateKeyPemCiphertextToSites < ActiveRecord::Migration[6.1] + # Agrega la columna cifrada + def change + add_column :sites, :private_key_pem_ciphertext, :text + end +end From 4de3352950f700bd303d2f5e472f5045a06c1810 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 29 Aug 2023 17:49:25 -0300 Subject: [PATCH 144/814] feat: generar la llave privada #14169 --- app/models/site/social_distributed_press.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 9d283103..5d469f03 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -7,6 +7,17 @@ class Site included do encrypts :private_key_pem + + before_save :generate_private_key_pem!, unless: :private_key_pem? + + private + + # Genera la llave privada y la almacena + # + # @return [nil] + def generate_private_key_pem! + self.private_key_pem ||= DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export + end end end end From 8b0b0199f60ad67b733c781fbc3425d5f6546fba Mon Sep 17 00:00:00 2001 From: f Date: Tue, 29 Aug 2023 18:26:03 -0300 Subject: [PATCH 145/814] feat: correr un comando obteniendo la llave dentro de un archivo temporal --- app/models/deploy.rb | 15 +++++++++++++++ app/models/deploy_local.rb | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index a92708c0..77e5b8d8 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -109,6 +109,21 @@ class Deploy < ApplicationRecord private + # Escribe el contenido en un archivo temporal y ejecuta el bloque + # provisto con el archivo como parámetro + # + # @param :content [String] + def with_tempfile(content, &block) + Tempfile.create(SecureRandom.hex) do |file| + file.write content.to_s + file.rewind + file.close + + # @yieldparam :file [File] + yield file + end + end + # @param [String] # @return [String] def readable_cmd(cmd) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 75ea8b1c..e66bb003 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -141,8 +141,12 @@ class DeployLocal < Deploy run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output end + # TODO: Esto significa que todos los sitios van a tener activity pub + # activado def jekyll_build(output: false) - run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}"), output: output + with_tempfile(site.private_key_pem) do |file| + run %(bundle exec jekyll build --trace --profile --key #{file.path} --destination "#{escaped_destination}"), output: output + end end # no debería haber espacios ni caracteres especiales, pero por si From 9ac404ae06286e69e8981c5322c2a9256ff04f99 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 10:47:08 -0300 Subject: [PATCH 146/814] feat: habilitar/deshabilitar activity pub --- .../_deploy_social_distributed_press.haml | 21 +++++++++++++++++++ config/locales/en.yml | 12 +++++++++++ config/locales/es.yml | 12 +++++++++++ 3 files changed, 45 insertions(+) create mode 100644 app/views/deploys/_deploy_social_distributed_press.haml diff --git a/app/views/deploys/_deploy_social_distributed_press.haml b/app/views/deploys/_deploy_social_distributed_press.haml new file mode 100644 index 00000000..5c73b262 --- /dev/null +++ b/app/views/deploys/_deploy_social_distributed_press.haml @@ -0,0 +1,21 @@ +-# Publicar a la web distribuida + +.row + .col + = deploy.hidden_field :id + = deploy.hidden_field :type + .custom-control.custom-switch + -# + El checkbox invierte la lógica de destrucción porque queremos + crear el deploy si está activado y destruirlo si está + desactivado. + = deploy.check_box :_destroy, + { checked: deploy.object.persisted?, class: 'custom-control-input' }, + '0', '1' + = deploy.label :_destroy, class: 'custom-control-label' do + %h3= t('.title') + = sanitize_markdown t('.help'), + tags: %w[p strong em a] + + +%hr/ diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..0dad2e68 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -123,6 +123,10 @@ en: title: Distributed Web success: Success! error: Error + deploy_social_distributed_press: + title: Fediverse + success: Success! + error: Error deploy_reindex: title: Reindex success: Success! @@ -307,6 +311,14 @@ en: indefinitely. [Learn more](https://sutty.nl/learn-more-about-publish-to-dweb-functionality/) + deploy_social_distributed_press: + title: 'Publish on the Fediverse' + help: | + By using the ActivityPub protocol, people on the Fediverse + ([Mastodon](https://joinmastodon.org/servers), + [Pixelfed](https://pixelfed.social/site/about), and + [others](https://fediverse.party/)) can follow your site, + receive news and interact with them. stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..d899b99c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -123,6 +123,10 @@ es: title: Web distribuida success: ¡Éxito! error: Hubo un error + deploy_social_distributed_press: + title: Fediverso + success: ¡Éxito! + error: Hubo un error deploy_reindex: title: Reindexación success: ¡Éxito! @@ -312,6 +316,14 @@ es: copias de tu contenido indefinidamente. [Saber más](https://sutty.nl/saber-mas-sobre-publicar-a-la-web-distribuida/) + deploy_social_distributed_press: + title: 'Publicar al Fediverso' + help: | + Utilizando el protocolo ActivityPub, otras personas en el + Fediverso ([Mastodon](https://joinmastodon.org/servers), + [Pixelfed](https://pixelfed.social/site/about) y + [otros](https://fediverse.party/)) pueden seguir a tu sitio, + recibir novedades e interactuar con ellas. stats: index: title: Estadísticas From f019805314735c813847043fadf051961ad5837a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 10:47:27 -0300 Subject: [PATCH 147/814] =?UTF-8?q?fix:=20generar=20todos=20los=20deploys?= =?UTF-8?q?=20autom=C3=A1ticamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site.rb | 4 ---- app/services/site_service.rb | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index 9ec21561..961831d5 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -19,10 +19,6 @@ class Site < ApplicationRecord # protege de acceso al panel de Sutty! encrypts :private_key - # TODO: Hacer que los diferentes tipos de deploy se auto registren - # @see app/services/site_service.rb - DEPLOYS = %i[local private www zip hidden_service distributed_press].freeze - validates :name, uniqueness: true, hostname: { allow_root_label: true } diff --git a/app/services/site_service.rb b/app/services/site_service.rb index b1df3d10..5bd89888 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -54,9 +54,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Genera los Deploy necesarios para el sitio a menos que ya los tenga. def build_deploys - Site::DEPLOYS.map { |deploy| "Deploy#{deploy.to_s.camelcase}" } - .each do |deploy| - next if site.deploys.find_by type: deploy + Deploy.subclasses.each do |deploy| + next if site.deploys.find_by type: deploy.name site.deploys.build type: deploy end From 4ade0944def7484ddcbee854c63ed184067b0f1c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 10:58:52 -0300 Subject: [PATCH 148/814] =?UTF-8?q?feat:=20los=20deploys=20pueden=20pasar?= =?UTF-8?q?=20opciones=20de=20compilaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy.rb | 5 ++++ app/models/deploy_local.rb | 16 ++++++++++--- app/models/deploy_social_distributed_press.rb | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 app/models/deploy_social_distributed_press.rb diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 77e5b8d8..abf5591f 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -100,6 +100,11 @@ class Deploy < ApplicationRecord @local_env ||= {} end + # Devuelve opciones para jekyll build + # + # @return [String,nil] + def flags_for_build(**args); end + # Trae todas las dependencias # # @return [Array] diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index e66bb003..9228581f 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -141,11 +141,11 @@ class DeployLocal < Deploy run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output end - # TODO: Esto significa que todos los sitios van a tener activity pub - # activado def jekyll_build(output: false) with_tempfile(site.private_key_pem) do |file| - run %(bundle exec jekyll build --trace --profile --key #{file.path} --destination "#{escaped_destination}"), output: output + flags = extra_flags(private_key: file) + + run %(bundle exec jekyll build --trace --profile #{flags} --destination "#{escaped_destination}"), output: output end end @@ -173,4 +173,14 @@ class DeployLocal < Deploy end end end + + # Genera opciones extra desde los otros deploys + # + # @param :args [Hash] + # @return [String] + def extra_flags(**args) + non_local_deploys.map do |deploy| + deploy.flags_for_build(**args) + end.compact.join(' ') + end end diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb new file mode 100644 index 00000000..47464ea9 --- /dev/null +++ b/app/models/deploy_social_distributed_press.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'distributed_press/v1/social/client' + +# Publicar novedades al Fediverso +class DeploySocialDistributedPress < Deploy + # Solo luego de publicar remotamente + DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync] + + # Envía las notificaciones + def deploy(output: false) + with_tempfile(site.private_key_pem) do |file| + run %(bundle exec jekyll notify --trace --key #{file.path} --destination "#{escaped_destination}"), output: output + end + end + + # Genera la opción de llave privada para jekyll build + # + # @params :args [Hash] + # @return [String] + def flags_for_build(**args) + "--key #{Shellwords.escape args[:private_key].path}" + end +end From 26f57a8467241e825b87fefcccdf76c4e9c3561d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 11:09:08 -0300 Subject: [PATCH 149/814] =?UTF-8?q?feat:=20m=C3=A9todos=20de=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_social_distributed_press.rb | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 47464ea9..db555ab7 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -10,10 +10,41 @@ class DeploySocialDistributedPress < Deploy # Envía las notificaciones def deploy(output: false) with_tempfile(site.private_key_pem) do |file| - run %(bundle exec jekyll notify --trace --key #{file.path} --destination "#{escaped_destination}"), output: output + key = Shellwords.escape file.path + dest = Shellwords.escape destination + + run %(bundle exec jekyll notify --trace --key #{key} --destination "#{dest}"), output: output end end + # Igual que DeployLocal + # + # @return [String] + def destination + File.join(Rails.root, '_deploy', site.hostname) + end + + # Solo uno + # + # @return [Integer] + def limit + 1 + end + + # Espacio ocupado, pero no podemos calcularlo + # + # @return [Integer] + def size + 0 + end + + # El perfil de actor + # + # @return [String,nil] + def url + site.data.dig('activity_pub', 'actor') + end + # Genera la opción de llave privada para jekyll build # # @params :args [Hash] From 2a4073178a7b431e6f1ea1b7798fcfc1d7b8a10b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 11:13:49 -0300 Subject: [PATCH 150/814] fix: actualizar la gema --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index dd880219..5ccee727 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' -gem 'distributed-press-api-client', '~> 0.2.3' +gem 'distributed-press-api-client', '~> 0.3.0rc0' gem 'njalla-api-client', '~> 0.2.0' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' diff --git a/Gemfile.lock b/Gemfile.lock index f71053d7..6c3dae96 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -153,7 +153,7 @@ GEM devise_invitable (2.0.8) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.2.4) + distributed-press-api-client (0.3.0rc0) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema @@ -595,7 +595,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.2.3) + distributed-press-api-client (~> 0.3.0rc0) dotenv-rails down ed25519 From c9866a0eecfca61d5c3136ffa412045687728dc3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 15:33:48 -0300 Subject: [PATCH 151/814] =?UTF-8?q?fix:=20mover=20m=C3=A9todos=20a=20deplo?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy.rb | 36 ++++++++++++++++++++++++++++++++++++ app/models/deploy_local.rb | 36 ------------------------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index abf5591f..c01a378f 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -55,6 +55,28 @@ class Deploy < ApplicationRecord @gems_dir ||= Rails.root.join('_storage', 'gems', site.name) end + # Un entorno que solo tiene lo que necesitamos + # + # @return [Hash] + def env + # XXX: This doesn't support Windows paths :B + paths = [File.dirname(`which bundle`), '/usr/local/bin', '/usr/bin', '/bin'] + + # Las variables de entorno extra no pueden superponerse al local. + extra_env.merge({ + 'HOME' => home_dir, + 'PATH' => paths.join(':'), + 'SPREE_API_KEY' => site.tienda_api_key, + 'SPREE_URL' => site.tienda_url, + 'AIRBRAKE_PROJECT_ID' => site.id.to_s, + 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, + 'JEKYLL_ENV' => Rails.env, + 'LANG' => ENV['LANG'], + 'YARN_CACHE_FOLDER' => yarn_cache_dir, + 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] + }) + end + # Corre un comando, lo registra en la base de datos y devuelve el # estado. # @@ -142,4 +164,18 @@ class Deploy < ApplicationRecord def non_local_deploys @non_local_deploys ||= site.deploys.where.not(type: 'DeployLocal') end + + # Consigue todas las variables de entorno configuradas por otros + # deploys. + # + # @deprecated Solo tenía sentido para Distributed Press v0 + # @return [Hash] + def extra_env + @extra_env ||= + non_local_deploys.reduce({}) do |extra_env, deploy| + extra_env.tap do |e| + e.merge! deploy.local_env + end + end + end end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 9228581f..edf85bf5 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -68,28 +68,6 @@ class DeployLocal < Deploy FileUtils.mkdir_p destination end - # Un entorno que solo tiene lo que necesitamos - # - # @return [Hash] - def env - # XXX: This doesn't support Windows paths :B - paths = [File.dirname(`which bundle`), '/usr/local/bin', '/usr/bin', '/bin'] - - # Las variables de entorno extra no pueden superponerse al local. - extra_env.merge({ - 'HOME' => home_dir, - 'PATH' => paths.join(':'), - 'SPREE_API_KEY' => site.tienda_api_key, - 'SPREE_URL' => site.tienda_url, - 'AIRBRAKE_PROJECT_ID' => site.id.to_s, - 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, - 'JEKYLL_ENV' => Rails.env, - 'LANG' => ENV['LANG'], - 'YARN_CACHE_FOLDER' => yarn_cache_dir, - 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] - }) - end - def yarn_cache_dir Rails.root.join('_yarn_cache').to_s end @@ -160,20 +138,6 @@ class DeployLocal < Deploy FileUtils.rm_rf destination end - # Consigue todas las variables de entorno configuradas por otros - # deploys. - # - # @deprecated Solo tenía sentido para Distributed Press v0 - # @return [Hash] - def extra_env - @extra_env ||= - non_local_deploys.reduce({}) do |extra_env, deploy| - extra_env.tap do |e| - e.merge! deploy.local_env - end - end - end - # Genera opciones extra desde los otros deploys # # @param :args [Hash] From f337e4967b1ac422062b696a8fc705f9f49d9e34 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 16:40:33 -0300 Subject: [PATCH 152/814] fix: recolectar variables de entorno --- app/models/deploy.rb | 17 ++--------------- app/models/deploy_local.rb | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index c01a378f..55ec46f6 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -66,14 +66,8 @@ class Deploy < ApplicationRecord extra_env.merge({ 'HOME' => home_dir, 'PATH' => paths.join(':'), - 'SPREE_API_KEY' => site.tienda_api_key, - 'SPREE_URL' => site.tienda_url, - 'AIRBRAKE_PROJECT_ID' => site.id.to_s, - 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, 'JEKYLL_ENV' => Rails.env, 'LANG' => ENV['LANG'], - 'YARN_CACHE_FOLDER' => yarn_cache_dir, - 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] }) end @@ -161,21 +155,14 @@ class Deploy < ApplicationRecord @deploy_local ||= site.deploys.find_by(type: 'DeployLocal') end - def non_local_deploys - @non_local_deploys ||= site.deploys.where.not(type: 'DeployLocal') - end - # Consigue todas las variables de entorno configuradas por otros # deploys. # - # @deprecated Solo tenía sentido para Distributed Press v0 # @return [Hash] def extra_env @extra_env ||= - non_local_deploys.reduce({}) do |extra_env, deploy| - extra_env.tap do |e| - e.merge! deploy.local_env - end + site.deployment_list.reduce({}) do |extra, deploy| + extra.merge deploy.local_env end end end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index edf85bf5..0bb3958f 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -62,6 +62,20 @@ class DeployLocal < Deploy FileUtils.rm_rf(File.join(site.path, '.jekyll-cache')) end + # Opciones necesarias para la compilación del sitio + # + # @return [Hash] + def local_env + @local_env ||= { + 'SPREE_API_KEY' => site.tienda_api_key, + 'SPREE_URL' => site.tienda_url, + 'AIRBRAKE_PROJECT_ID' => site.id.to_s, + 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, + 'YARN_CACHE_FOLDER' => yarn_cache_dir, + 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] + } + end + private def mkdir @@ -143,7 +157,7 @@ class DeployLocal < Deploy # @param :args [Hash] # @return [String] def extra_flags(**args) - non_local_deploys.map do |deploy| + site.deployment_list.map do |deploy| deploy.flags_for_build(**args) end.compact.join(' ') end From cd7c21792063c815adb4886540d6a64fe9c0ecf3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 17:17:04 -0300 Subject: [PATCH 153/814] fix: poder asignar valor por defecto a los campos boolean --- app/models/metadata_boolean.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/metadata_boolean.rb b/app/models/metadata_boolean.rb index 90c002a7..9932c6fd 100644 --- a/app/models/metadata_boolean.rb +++ b/app/models/metadata_boolean.rb @@ -4,8 +4,12 @@ # # Esto es increíblemente difícil de lograr que salga bien! class MetadataBoolean < MetadataTemplate + # El valor por defecto es una versión booleana de lo que diga (o no + # diga) el esquema + # + # @return [Boolean] def default_value - false + !!super end # Los checkboxes son especiales porque la especificación de HTML From d8e21c97e2efcc6ffbfdc294119545b58b538cd0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:41:34 -0300 Subject: [PATCH 154/814] fix: solo vincular urls que tienen protocolo --- app/controllers/build_stats_controller.rb | 7 ++++++- app/jobs/deploy_job.rb | 6 +++++- app/mailers/deploy_mailer.rb | 2 +- app/views/build_stats/index.haml | 2 +- app/views/deploy_mailer/deployed.html.haml | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/controllers/build_stats_controller.rb b/app/controllers/build_stats_controller.rb index 31a4c5d6..6961cf45 100644 --- a/app/controllers/build_stats_controller.rb +++ b/app/controllers/build_stats_controller.rb @@ -22,7 +22,12 @@ class BuildStatsController < ApplicationController @table = site.deployment_list.map do |deploy| type = deploy.class.name.underscore - urls = deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact + urls = (deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact).map do |url| + URI.parse(url) + rescue URI::Error + nil + end.compact + urls = [nil] if urls.empty? build_stat = deploy.build_stats.where(status: true).last seconds = build_stat&.seconds || 0 diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index a5cda360..6f486f29 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -51,7 +51,11 @@ class DeployJob < ApplicationJob status = d.deploy(output: @output) seconds = d.build_stats.last.try(:seconds) || 0 size = d.size - urls = d.respond_to?(:urls) ? d.urls : [d.url].compact + urls = (d.respond_to?(:urls) ? d.urls : [d.url].compact).map do |url| + URI.parse url + rescue URI::Error + nil + end.compact rescue StandardError => e status = false seconds ||= 0 diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index b7b464cb..37748b42 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -52,7 +52,7 @@ class DeployMailer < ApplicationMailer t << (row.map do |k, v| case k when :seconds then v[:human] - when :urls then url + when :urls then url.to_s else v end end) diff --git a/app/views/build_stats/index.haml b/app/views/build_stats/index.haml index 27c063f9..0b0e7755 100644 --- a/app/views/build_stats/index.haml +++ b/app/views/build_stats/index.haml @@ -14,7 +14,7 @@ - row[:urls].each do |url| %tr %th{ scope: 'row' }= row[:title] - %td= link_to_if url.present?, url, url, class: 'word-break-all' + %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s, class: 'word-break-all' %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index f5afe5de..b3463db6 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -13,7 +13,7 @@ %tr %td= row[:title] %td= row[:status] - %td= link_to_if url.present?, url, url + %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From f076838be5137821ca2a2ca18f9e89c53047ea5f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:47:44 -0300 Subject: [PATCH 155/814] fixup! fix: solo vincular urls que tienen protocolo --- app/jobs/deploy_job.rb | 2 +- app/views/deploy_mailer/deployed.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 6f486f29..00ae7585 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -70,7 +70,7 @@ class DeployJob < ApplicationJob status: status, seconds: seconds, size: size, - urls: urls + urls: urls.map(&:to_s) } end diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index b3463db6..762bf4db 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -13,7 +13,7 @@ %tr %td= row[:title] %td= row[:status] - %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s + %td= link_to_if (url.present? && url.scheme.present?), url.to_s, url.to_s %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From a6195fbcccf80e47245429228f6631b9139aced4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:52:49 -0300 Subject: [PATCH 156/814] fix: simplificar --- app/controllers/build_stats_controller.rb | 2 +- app/jobs/deploy_job.rb | 2 +- app/models/deploy.rb | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/build_stats_controller.rb b/app/controllers/build_stats_controller.rb index 6961cf45..339f17f0 100644 --- a/app/controllers/build_stats_controller.rb +++ b/app/controllers/build_stats_controller.rb @@ -22,7 +22,7 @@ class BuildStatsController < ApplicationController @table = site.deployment_list.map do |deploy| type = deploy.class.name.underscore - urls = (deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact).map do |url| + urls = deploy.urls.map do |url| URI.parse(url) rescue URI::Error nil diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 00ae7585..0870b827 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -51,7 +51,7 @@ class DeployJob < ApplicationJob status = d.deploy(output: @output) seconds = d.build_stats.last.try(:seconds) || 0 size = d.size - urls = (d.respond_to?(:urls) ? d.urls : [d.url].compact).map do |url| + urls = d.urls.map do |url| URI.parse url rescue URI::Error nil diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 55ec46f6..811047f1 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -23,6 +23,11 @@ class Deploy < ApplicationRecord raise NotImplementedError end + # @return [Array] + def urls + [url].compact + end + def limit raise NotImplementedError end From 927f92d985e7b1af86424cb332e48f900d988a83 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:56:00 -0300 Subject: [PATCH 157/814] fix: typo --- app/views/build_stats/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/build_stats/index.haml b/app/views/build_stats/index.haml index 0b0e7755..de04d84d 100644 --- a/app/views/build_stats/index.haml +++ b/app/views/build_stats/index.haml @@ -14,7 +14,7 @@ - row[:urls].each do |url| %tr %th{ scope: 'row' }= row[:title] - %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s, class: 'word-break-all' + %td= link_to_if (url.present? && url.scheme.present?), url.to_s, url.to_s, class: 'word-break-all' %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From 3dedd84db78512e017706cd90610318c677879d4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:58:16 -0300 Subject: [PATCH 158/814] fix: enviar urls parseadas --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 0870b827..291991c7 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -70,7 +70,7 @@ class DeployJob < ApplicationJob status: status, seconds: seconds, size: size, - urls: urls.map(&:to_s) + urls: urls } end From 6aa0f7d6cf6a54f4f0cee94d27d3c8206a849c86 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Sep 2023 20:11:46 -0300 Subject: [PATCH 159/814] =?UTF-8?q?feat:=20guardar=20la=20fecha=20de=20cre?= =?UTF-8?q?aci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/post.rb b/app/models/post.rb index 5cc1c5ea..6265a313 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -267,6 +267,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq + yaml['created_at'] ||= Time.now yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 10d958e50aed0f92dfae7140bde7650d371b1d22 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Sep 2023 12:44:57 -0300 Subject: [PATCH 160/814] =?UTF-8?q?fix:=20compartir=20la=20misma=20fecha?= =?UTF-8?q?=20de=20creaci=C3=B3n=20y=20de=20actualizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index 6265a313..f31c33b6 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -267,7 +267,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq - yaml['created_at'] ||= Time.now + yaml['created_at'] ||= modified_at yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 7425428f44e4cafaceb988718a7a30317d4588ee Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 4 Sep 2023 16:30:20 -0300 Subject: [PATCH 161/814] feat: add magazine theme to seeds and fix description text #14128 --- db/seeds/designs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/db/seeds/designs.yml b/db/seeds/designs.yml index a04c99c1..56655322 100644 --- a/db/seeds/designs.yml +++ b/db/seeds/designs.yml @@ -75,6 +75,14 @@ credits_en: 'This template was made in collaboration with Librenauta in 15 hours!' designer_url: 'https://copiona.com/donaunbit/' priority: '70' +- name_en: 'Magazine' + name_es: 'Revista' + gem: 'compost-jekyll-theme' + url: 'https://two.compost.digital/' + description_en: 'A theme to create multimedia publications, based in COMPOST magazine' + description_es: 'Plantilla para crear publicaciones multimedia, basada en COMPOST magazine' + license: 'https://0xacab.org/sutty/jekyll/compost-jekyll-theme/-/blob/no-masters/LICENSE.txt' + priority: '40' - name_en: 'Resource toolkit' name_es: 'Recursero' gem: 'recursero-jekyll-theme' From 8ae5dd597501d81d4e266bedbbf62edbe7778761 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Sep 2023 14:49:17 -0300 Subject: [PATCH 162/814] fix: no compartir la misma instancia sutty/jekyll/jekyll-activitypub#42 --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index f31c33b6..36a0b02e 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -267,7 +267,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq - yaml['created_at'] ||= modified_at + yaml['created_at'] ||= modified_at.dup yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 6b1eccade35aec862160950549123f59be7d1fe7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 17:52:21 -0300 Subject: [PATCH 163/814] =?UTF-8?q?feat:=20fecha=20de=20creaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_created_at.rb | 14 ++++++++++++++ app/models/post.rb | 8 ++++++-- app/views/posts/attribute_ro/_created_at.haml | 4 ++++ app/views/posts/attributes/_created_at.haml | 1 + config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 6 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 app/models/metadata_created_at.rb create mode 100644 app/views/posts/attribute_ro/_created_at.haml create mode 100644 app/views/posts/attributes/_created_at.haml diff --git a/app/models/metadata_created_at.rb b/app/models/metadata_created_at.rb new file mode 100644 index 00000000..2a7c07ed --- /dev/null +++ b/app/models/metadata_created_at.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Fecha y hora de creación +class MetadataCreatedAt < MetadataTemplate + # Por defecto la hora actual + def default_value + Time.now + end + + # Nunca cambia + def value=(new_value) + value + end +end diff --git a/app/models/post.rb b/app/models/post.rb index 36a0b02e..8bd5dab3 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -12,7 +12,7 @@ class Post DEFAULT_ATTRIBUTES = %i[site document layout].freeze # Otros atributos que no vienen en los metadatos PRIVATE_ATTRIBUTES = %i[path slug attributes errors].freeze - PUBLIC_ATTRIBUTES = %i[lang date uuid].freeze + PUBLIC_ATTRIBUTES = %i[lang date uuid created_at].freeze ATTR_SUFFIXES = %w[? =].freeze attr_reader :attributes, :errors, :layout, :site, :document @@ -217,6 +217,11 @@ class Post post: self, required: true) end + # La fecha de creación inmodificable del post + def created_at + @metadata[:created_at] ||= MetadataCreatedAt.new(document: document, site: site, layout: layout, name: :created_at, type: :timestamp, post: self, required: true) + end + # Detecta si es un atributo válido o no, a partir de la tabla de la # plantilla def attribute?(mid) @@ -267,7 +272,6 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq - yaml['created_at'] ||= modified_at.dup yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" diff --git a/app/views/posts/attribute_ro/_created_at.haml b/app/views/posts/attribute_ro/_created_at.haml new file mode 100644 index 00000000..04f6d716 --- /dev/null +++ b/app/views/posts/attribute_ro/_created_at.haml @@ -0,0 +1,4 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ dir: dir, lang: locale } + %time{ datetime: metadata.value.xmlschema }= l metadata.value diff --git a/app/views/posts/attributes/_created_at.haml b/app/views/posts/attributes/_created_at.haml new file mode 100644 index 00000000..0aab9802 --- /dev/null +++ b/app/views/posts/attributes/_created_at.haml @@ -0,0 +1 @@ +-# nada diff --git a/config/locales/en.yml b/config/locales/en.yml index 0dad2e68..5c00701c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -524,6 +524,8 @@ en: feedback: 'This field cannot be empty!' uuid: label: 'Unique identifier' + created_at: + label: 'Created at' geo: uri: 'Open in app' osm: 'Open in web map' diff --git a/config/locales/es.yml b/config/locales/es.yml index d899b99c..0ff7e1c8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -532,6 +532,8 @@ es: feedback: '¡Este campo no puede estar vacío!' uuid: label: 'Identificador único' + created_at: + label: 'Fecha de creación' geo: uri: 'Abrir en aplicación' osm: 'Abrir en mapa web' From 35e8a087163683c77de16fd398006d8b71c5bec8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 17:53:51 -0300 Subject: [PATCH 164/814] =?UTF-8?q?fixup!=20feat:=20fecha=20de=20creaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index 8bd5dab3..73785cad 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -219,7 +219,7 @@ class Post # La fecha de creación inmodificable del post def created_at - @metadata[:created_at] ||= MetadataCreatedAt.new(document: document, site: site, layout: layout, name: :created_at, type: :timestamp, post: self, required: true) + @metadata[:created_at] ||= MetadataCreatedAt.new(document: document, site: site, layout: layout, name: :created_at, type: :created_at, post: self, required: true) end # Detecta si es un atributo válido o no, a partir de la tabla de la From d27717ed3b7a21413361e86030ef59f4c3b84b3c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 17:59:50 -0300 Subject: [PATCH 165/814] fix: agregar created_at al front matter --- app/models/post.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/post.rb b/app/models/post.rb index 73785cad..fab9ab06 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -272,6 +272,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq + yaml['created_at'] = created_at.value yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 99c919e5e6cfca0e6affcd138da52a0565b6fd32 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 18:07:25 -0300 Subject: [PATCH 166/814] fix: retrocompatibilidad --- app/models/metadata_created_at.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/models/metadata_created_at.rb b/app/models/metadata_created_at.rb index 2a7c07ed..d31b3a1c 100644 --- a/app/models/metadata_created_at.rb +++ b/app/models/metadata_created_at.rb @@ -2,9 +2,14 @@ # Fecha y hora de creación class MetadataCreatedAt < MetadataTemplate - # Por defecto la hora actual + # Por defecto la hora actual, pero por retrocompatibilidad, queremos + # la fecha de publicación def default_value - Time.now + if post.date.value.to_date < Time.now.to_date + post.date.value + else + Time.now + end end # Nunca cambia From 21d570ebe8175c4caede327f7775ae56f407c1f3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Sep 2023 15:18:09 -0300 Subject: [PATCH 167/814] =?UTF-8?q?fix:=20no=20renderizar=20liquid=20dentr?= =?UTF-8?q?o=20de=20los=20art=C3=ADculos=20#14323?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index 5cc1c5ea..3e808a51 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -265,7 +265,7 @@ class Post yaml['layout'] = layout.name.to_s yaml['uuid'] = uuid.value # Y que no se procese liquid - yaml['liquid'] = false + yaml['render_with_liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq yaml['last_modified_at'] = modified_at From a2d84bfa96a375bd8c0ce79cda4a2ec20f0f5e9d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 12:25:23 -0300 Subject: [PATCH 168/814] fix: renombrar el remote correctamente --- app/models/site.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 0fddeff5..fa1d7b46 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -473,7 +473,10 @@ class Site < ApplicationRecord def clone_skel! return if jekyll? - Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path, remote: 'upstream' + Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path + + # Necesita un bloque + repository.rugged.remotes.rename('origin', 'upstream') {} end # Elimina el directorio del sitio From 69e1664084cd2b1cfb4fa71dfee745883f546c2d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:02:15 -0300 Subject: [PATCH 169/814] fix: renombrar todos los repositorios remotos --- ...921155401_site_rename_origin_to_upstream.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 db/migrate/20230921155401_site_rename_origin_to_upstream.rb diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb new file mode 100644 index 00000000..c27d7747 --- /dev/null +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Renombrar todos los repositorios que apunten a skel como su origin +class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] + # Renombrar + def up + Site.find_each do |site| + next unless site.repository.origin&.url == ENV['SKEL_SUTTY'] + + site.repository.rugged.remotes.rename('origin', 'upstream') + rescue Rugged::Error => e + Rails.logger.warn "#{site.name}: #{e.message}" + end + end + + # No se puede deshacer + def down; end +end From e4dc6588f925756d9523b6d344668c099f17b382 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:04:25 -0300 Subject: [PATCH 170/814] =?UTF-8?q?fix:=20informar=20qu=C3=A9=20est=C3=A1?= =?UTF-8?q?=20pasando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20230921155401_site_rename_origin_to_upstream.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb index c27d7747..e32ca6fc 100644 --- a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -8,6 +8,7 @@ class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] next unless site.repository.origin&.url == ENV['SKEL_SUTTY'] site.repository.rugged.remotes.rename('origin', 'upstream') + Rails.logger.info "#{site.name}: renamed origin to upstream" rescue Rugged::Error => e Rails.logger.warn "#{site.name}: #{e.message}" end From 7709b9f79803ccdda400526f5b2dfb9f49ad6cc8 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:09:10 -0300 Subject: [PATCH 171/814] =?UTF-8?q?fix:=20capturar=20m=C3=A1s=20errores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20230921155401_site_rename_origin_to_upstream.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb index e32ca6fc..4ad53f1b 100644 --- a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -9,7 +9,7 @@ class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] site.repository.rugged.remotes.rename('origin', 'upstream') Rails.logger.info "#{site.name}: renamed origin to upstream" - rescue Rugged::Error => e + rescue Rugged::Error, Rugged::OSError => e Rails.logger.warn "#{site.name}: #{e.message}" end end From b06b829357a607a9567d75fbf3bded07d7002a53 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:10:26 -0300 Subject: [PATCH 172/814] fix: necesita un bloque --- db/migrate/20230921155401_site_rename_origin_to_upstream.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb index 4ad53f1b..864f4c4a 100644 --- a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -7,8 +7,9 @@ class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] Site.find_each do |site| next unless site.repository.origin&.url == ENV['SKEL_SUTTY'] - site.repository.rugged.remotes.rename('origin', 'upstream') - Rails.logger.info "#{site.name}: renamed origin to upstream" + site.repository.rugged.remotes.rename('origin', 'upstream') do |_| + Rails.logger.info "#{site.name}: renamed origin to upstream" + end rescue Rugged::Error, Rugged::OSError => e Rails.logger.warn "#{site.name}: #{e.message}" end From 4689d10e8dbfb612e03f4fb922d61010fb10f24c Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 21 Sep 2023 16:22:45 -0300 Subject: [PATCH 173/814] feat: instalada gema device_detector #14334 --- Gemfile | 1 + config/initializers/device_detector.rb | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 config/initializers/device_detector.rb diff --git a/Gemfile b/Gemfile index dd880219..7e1beda9 100644 --- a/Gemfile +++ b/Gemfile @@ -78,6 +78,7 @@ gem 'validates_hostname' gem 'webpacker' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' +gem 'device_detector' # database gem 'hairtrigger' diff --git a/config/initializers/device_detector.rb b/config/initializers/device_detector.rb new file mode 100644 index 00000000..95500315 --- /dev/null +++ b/config/initializers/device_detector.rb @@ -0,0 +1,3 @@ +DeviceDetector.configure do |config| + config.max_cache_keys = 5_000 # to check if not too much + end \ No newline at end of file From 84f82cbb0fccde12f51cc69678ccdafe151b96b3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 12:21:55 -0300 Subject: [PATCH 174/814] fix: obtener el usuario del repositorio --- Gemfile | 1 + Gemfile.lock | 4 ++++ app/models/site/repository.rb | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index dd880219..6edeac5a 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,7 @@ gem 'redis-rails' gem 'rollups', git: 'https://github.com/fauno/rollup.git', branch: 'update' gem 'rubyzip' gem 'rugged' +gem 'git_clone_url' gem 'concurrent-ruby-ext' gem 'que' gem 'symbol-fstring', require: 'fstring/all' diff --git a/Gemfile.lock b/Gemfile.lock index f71053d7..9549a51d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -217,6 +217,8 @@ GEM activerecord (>= 4.0.0) get_process_mem (0.2.7) ffi (~> 1.0) + git_clone_url (2.0.0) + uri-ssh_git (>= 2.0) globalid (1.1.0) activesupport (>= 5.0) groupdate (6.2.1) @@ -553,6 +555,7 @@ GEM unf_ext unf_ext (0.0.8.2-x86_64-linux-musl) unicode-display_width (1.8.0) + uri-ssh_git (2.0.0) validates_hostname (1.0.13) activerecord (>= 3.0) activesupport (>= 3.0) @@ -606,6 +609,7 @@ DEPENDENCIES fast_jsonparser (~> 0.5.0) flamegraph friendly_id + git_clone_url hairtrigger haml-lint hamlit-rails diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 74d874c1..d776efa4 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -173,7 +173,21 @@ class Site def credentials return unless File.exist? private_key - @credentials ||= Rugged::Credentials::SshKey.new username: 'git', publickey: public_key, privatekey: private_key + @credentials ||= + begin + username = parse_url(origin.url)&.user || 'git' + + Rugged::Credentials::SshKey.new username: username, publickey: public_key, privatekey: private_key + end + end + + # @param :url [String] + # @return [URI, nil] + def parse_url(url) + GitCloneUrl.parse(url) + rescue URI::Error => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, url: url }) + nil end # @return [String] From 0c7a37a1d82e7035b05cfb4fb96614c36fd38369 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 12:46:32 -0300 Subject: [PATCH 175/814] fix: mantener rugged 1.5.0.1 versiones posteriores se rompen con urls ssh:// https://github.com/libgit2/libgit2/issues/6496 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 6edeac5a..ce776647 100644 --- a/Gemfile +++ b/Gemfile @@ -69,7 +69,7 @@ gem 'redis', '~> 4.0', require: %w[redis redis/connection/hiredis] gem 'redis-rails' gem 'rollups', git: 'https://github.com/fauno/rollup.git', branch: 'update' gem 'rubyzip' -gem 'rugged' +gem 'rugged', '1.5.0.1' gem 'git_clone_url' gem 'concurrent-ruby-ext' gem 'que' diff --git a/Gemfile.lock b/Gemfile.lock index 9549a51d..11561776 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -496,7 +496,7 @@ GEM ruby_parser (3.20.1) sexp_processor (~> 4.16) rubyzip (2.3.2) - rugged (1.6.3-x86_64-linux-musl) + rugged (1.5.0.1-x86_64-linux-musl) safe_yaml (1.0.6) safely_block (0.3.0) errbase (>= 0.1.1) @@ -654,7 +654,7 @@ DEPENDENCIES rollups! rubocop-rails rubyzip - rugged + rugged (= 1.5.0.1) safe_yaml safely_block (~> 0.3.0) sassc-rails From 52e22a53bfd3f8bed30a01820ca522304384b619 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 12:47:18 -0300 Subject: [PATCH 176/814] fix: no sabemos el sitio --- app/models/site/repository.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index d776efa4..128a557a 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -186,7 +186,7 @@ class Site def parse_url(url) GitCloneUrl.parse(url) rescue URI::Error => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, url: url }) + ExceptionNotifier.notify_exception(e, data: { path: path, url: url }) nil end From 7793c5f96d63bad20243b6eb3bb0d8bc79e92e6d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 13:03:28 -0300 Subject: [PATCH 177/814] =?UTF-8?q?fix:=20no=20enviar=20el=20env=20en=20la?= =?UTF-8?q?=20notificaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 1730034e..36e6a6d1 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -68,7 +68,7 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) - ExceptionNotifier.notify_exception(exception, env: request.env, data: { headers: request.headers.to_h }) + ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h } head :forbidden end From c176a8a4b44b5b62ffe01fb7708c39abf4eecbd9 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 13:19:21 -0300 Subject: [PATCH 178/814] feat: poder obtener el usuario de cualquier remoto --- app/models/site/repository.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 128a557a..119a1495 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -173,12 +173,18 @@ class Site def credentials return unless File.exist? private_key - @credentials ||= - begin - username = parse_url(origin.url)&.user || 'git' + Rugged::Credentials::SshKey.new username: username_for(origin), publickey: public_key, privatekey: private_key + end - Rugged::Credentials::SshKey.new username: username, publickey: public_key, privatekey: private_key - end + # Obtiene el nombre de usuario para el repositorio remoto, por + # defecto git + # + # @param :remote [Rugged::Remote] + # @return [String] + def username_for(remote) + username = parse_url(remote.url)&.user if remote.respond_to? :url + + username || 'git' end # @param :url [String] From aeaf72c27036753b52087acac6c2fd523e923f78 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 13:20:20 -0300 Subject: [PATCH 179/814] feat: poder pushear a cualquier remoto --- app/models/site/repository.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 119a1495..2eafb92e 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -158,22 +158,29 @@ class Site # Pushea cambios al repositorio remoto # + # @param :remote [Rugged::Remote] # @return [Boolean, nil] - def push - origin.push(rugged.head.canonical_name, credentials: credentials) - git_sh("git", "lfs", "push", "origin", default_branch) + def push(remote = origin) + remote.push(rugged.head.canonical_name, credentials: credentials_for(remote)) + git_sh('git', 'lfs', 'push', remote.name, default_branch) end private + # @deprecated + def credentials + @credentials ||= credentials_for(origin) + end + # Si Sutty tiene una llave privada de tipo ED25519, devuelve las # credenciales necesarias para trabajar con repositorios remotos. # + # @param :remote [Rugged::Remote] # @return [Nil, Rugged::Credentials::SshKey] - def credentials + def credentials_for(remote) return unless File.exist? private_key - Rugged::Credentials::SshKey.new username: username_for(origin), publickey: public_key, privatekey: private_key + Rugged::Credentials::SshKey.new username: username_for(remote), publickey: public_key, privatekey: private_key end # Obtiene el nombre de usuario para el repositorio remoto, por From 74e371eb36c6b9d4714e0cfba98851ec1a36a65c Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 22 Sep 2023 13:51:36 -0300 Subject: [PATCH 180/814] feat: ignorar reportes de bots con device_detector #14334 --- app/controllers/api/v1/notices_controller.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/notices_controller.rb b/app/controllers/api/v1/notices_controller.rb index 436c78b5..c5b88e28 100644 --- a/app/controllers/api/v1/notices_controller.rb +++ b/app/controllers/api/v1/notices_controller.rb @@ -9,10 +9,11 @@ module Api # Generar un stacktrace en segundo plano y enviarlo por correo # solo si la API key es verificable. Del otro lado siempre # respondemos con lo mismo. - def create - if site&.airbrake_valid? airbrake_token + def create + if site&.airbrake_valid? airbrake_token && !detected_device.bot? BacktraceJob.perform_later site_id: params[:site_id], - params: airbrake_params.to_h + params: airbrake_params.to_h + end end render status: 201, json: { id: 1, url: '' } @@ -34,6 +35,11 @@ module Api def airbrake_token @airbrake_token ||= params[:key] end + + # @return [DeviceDetector] + def detected_device + @detected_device ||= DeviceDetector.new(request.headers) + end end end end From f19a9fa42fcbaa1d37344c852ba9f239448d1f2b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 14:31:53 -0300 Subject: [PATCH 181/814] style: usar .editorconfig sutty/jekyll/sutty-base-jekyll-theme#60 --- .editorconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..b0bc1626 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 2 + +[Makefile] +indent_style = tab From 6866f827f6547655709405ad258783464bb72b06 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 22 Sep 2023 15:10:46 -0300 Subject: [PATCH 182/814] =?UTF-8?q?fix:=20error=20de=20sintaxis=20y=20par?= =?UTF-8?q?=C3=A1metros=20a=20device=5Fdetector=20#14334?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile.lock | 18 ++++++++++-------- app/controllers/api/v1/notices_controller.rb | 5 ++--- config/initializers/device_detector.rb | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f71053d7..5e6d09f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -86,7 +86,7 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.4) + addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) autoprefixer-rails (10.4.13.0) @@ -142,6 +142,7 @@ GEM rake (> 10, < 14) ruby-statistics (>= 2.1) thor (>= 0.19, < 2) + device_detector (1.1.1) devise (4.9.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -166,10 +167,10 @@ GEM railties (>= 3.2) down (5.4.1) addressable (~> 2.8) - dry-configurable (1.0.1) + dry-configurable (1.1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-core (1.0.0) + dry-core (1.0.1) concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) dry-inflector (1.0.0) @@ -178,7 +179,7 @@ GEM concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-schema (1.13.1) + dry-schema (1.13.3) concurrent-ruby (~> 1.0) dry-configurable (~> 1.0, >= 1.0.1) dry-core (~> 1.0, < 2) @@ -344,7 +345,7 @@ GEM method_source (1.0.0) mini_histogram (0.3.1) mini_magick (4.12.0) - mini_mime (1.1.2) + mini_mime (1.1.5) mini_portile2 (2.8.2) minitest (5.18.0) mobility (1.2.9) @@ -461,7 +462,7 @@ GEM responders (3.1.0) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.5) + rexml (3.2.6) rgl (0.6.3) pairing_heap (>= 0.3.0) rexml (~> 3.2, >= 3.2.4) @@ -526,7 +527,7 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - sqlite3 (1.6.3-x86_64-linux-musl) + sqlite3 (1.6.4-x86_64-linux-musl) mini_portile2 (~> 2.8.0) stackprof (0.2.25-x86_64-linux-musl) stream (0.5.5) @@ -575,7 +576,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.8) + zeitwerk (2.6.11) PLATFORMS x86_64-linux-musl @@ -592,6 +593,7 @@ DEPENDENCIES concurrent-ruby-ext database_cleaner derailed_benchmarks + device_detector devise devise-i18n devise_invitable diff --git a/app/controllers/api/v1/notices_controller.rb b/app/controllers/api/v1/notices_controller.rb index c5b88e28..3d74a48f 100644 --- a/app/controllers/api/v1/notices_controller.rb +++ b/app/controllers/api/v1/notices_controller.rb @@ -10,10 +10,9 @@ module Api # solo si la API key es verificable. Del otro lado siempre # respondemos con lo mismo. def create - if site&.airbrake_valid? airbrake_token && !detected_device.bot? + if (site&.airbrake_valid? airbrake_token) && !detected_device.bot? BacktraceJob.perform_later site_id: params[:site_id], params: airbrake_params.to_h - end end render status: 201, json: { id: 1, url: '' } @@ -38,7 +37,7 @@ module Api # @return [DeviceDetector] def detected_device - @detected_device ||= DeviceDetector.new(request.headers) + @detected_device ||= DeviceDetector.new(request.headers['User-Agent'], request.headers) end end end diff --git a/config/initializers/device_detector.rb b/config/initializers/device_detector.rb index 95500315..e6f6118a 100644 --- a/config/initializers/device_detector.rb +++ b/config/initializers/device_detector.rb @@ -1,3 +1,3 @@ DeviceDetector.configure do |config| - config.max_cache_keys = 5_000 # to check if not too much - end \ No newline at end of file + config.max_cache_keys = 5_000 # to check if not too much +end \ No newline at end of file From de59cd9f34b8e346df111643f11482df9647bd15 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:08:37 -0300 Subject: [PATCH 183/814] fix: informar cuando la plantilla no tiene gema #14309 --- config/initializers/core_extensions.rb | 14 ++++++++++++++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 16 insertions(+) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 1516a43a..837fbd18 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -91,6 +91,15 @@ module Jekyll spec.name == name end + unless spec + I18n.with_locale(locale) do + raise ArgumentError, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { theme: name, site: site.path }) + raise + end + end + ruby_version = Gem::Version.new(RUBY_VERSION) ruby_version.canonical_segments[2] = 0 base_path = Rails.root.join('_storage', 'gems', File.basename(site.source), 'ruby', @@ -114,6 +123,11 @@ module Jekyll private def gemspec; end + + # @return [Symbol] + def locale + @locale ||= (site.config['locale'] || site.config['lang'] || I18n.locale).to_sym + end end # No necesitamos los archivos de la plantilla diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..56b8c213 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -191,6 +191,7 @@ en: deploys: deploy_local_presence: 'We need to be build the site!' design_id: + missing_gem: "Site is configured to use %{theme} theme, but the corresponding gem is missing from Gemfile" layout_incompatible: error: "Design can't be changed because there are posts with incompatible layouts" help: "Your site has posts with layouts only compatible with the current design. If you change it, the site won't work as you expect. If you're trying out designs, you can delete posts in the following incompatible layouts:: %{layouts}." diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..b4fde8a3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -191,6 +191,7 @@ es: deploys: deploy_local_presence: '¡Necesitamos poder generar el sitio!' design_id: + missing_gem: "El sitio usa la plantilla %{theme} pero la gema correspondiente no se encuentra en el Gemfile" layout_incompatible: error: 'No se puede cambiar la plantilla porque hay artículos con formatos incompatibles' help: 'En tu sitio hay artículos que solo son compatibles con el diseño actual, si cambias la plantilla el sitio no funcionará como esperas. Si estás probando plantillas, puedes eliminar los artículos en los formatos incompatibles: %{layouts}.' From 01e7436576c1060d38dd47a0ef0e4aca656c02f8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:10:34 -0300 Subject: [PATCH 184/814] fix: obtener el nombre del sitio --- config/initializers/core_extensions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 837fbd18..2e9ed7e1 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -95,7 +95,7 @@ module Jekyll I18n.with_locale(locale) do raise ArgumentError, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { theme: name, site: site.path }) + ExceptionNotifier.notify_exception(e, data: { theme: name, site: File.basename(site.source) }) raise end end From bfd31d051fb002e303ddcd0f253b1e2a7aa50f49 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:15:32 -0300 Subject: [PATCH 185/814] =?UTF-8?q?fix:=20lanzar=20una=20excepci=C3=B3n=20?= =?UTF-8?q?contundente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/initializers/core_extensions.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 2e9ed7e1..d6039e16 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -93,8 +93,8 @@ module Jekyll unless spec I18n.with_locale(locale) do - raise ArgumentError, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) - rescue ArgumentError => e + raise Jekyll::Errors::InvalidThemeName, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) + rescue Jekyll::Errors::InvalidThemeName => e ExceptionNotifier.notify_exception(e, data: { theme: name, site: File.basename(site.source) }) raise end From 5c43214e46a06f125459c89df9568c1986dd01ea Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 25 Sep 2023 14:32:28 -0300 Subject: [PATCH 186/814] fix: arreglados cambios en Gemfile.lock #14334 --- Gemfile.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5e6d09f9..a786e060 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -86,7 +86,7 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.5) + addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) autoprefixer-rails (10.4.13.0) @@ -167,10 +167,10 @@ GEM railties (>= 3.2) down (5.4.1) addressable (~> 2.8) - dry-configurable (1.1.0) + dry-configurable (1.0.1) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-core (1.0.1) + dry-core (1.0.0) concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) dry-inflector (1.0.0) @@ -179,7 +179,7 @@ GEM concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-schema (1.13.3) + dry-schema (1.13.1) concurrent-ruby (~> 1.0) dry-configurable (~> 1.0, >= 1.0.1) dry-core (~> 1.0, < 2) @@ -345,7 +345,7 @@ GEM method_source (1.0.0) mini_histogram (0.3.1) mini_magick (4.12.0) - mini_mime (1.1.5) + mini_mime (1.1.2) mini_portile2 (2.8.2) minitest (5.18.0) mobility (1.2.9) @@ -462,7 +462,7 @@ GEM responders (3.1.0) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.6) + rexml (3.2.5) rgl (0.6.3) pairing_heap (>= 0.3.0) rexml (~> 3.2, >= 3.2.4) @@ -527,7 +527,7 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - sqlite3 (1.6.4-x86_64-linux-musl) + sqlite3 (1.6.3-x86_64-linux-musl) mini_portile2 (~> 2.8.0) stackprof (0.2.25-x86_64-linux-musl) stream (0.5.5) @@ -576,7 +576,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.11) + zeitwerk (2.6.8) PLATFORMS x86_64-linux-musl From d674ccdb0fab626900f41f95305ab5222c7612a0 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:52:59 -0300 Subject: [PATCH 187/814] fix: el gemfile.lock puede modificar luego del gemfile #14352 --- app/models/site.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..2958db9a 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -583,8 +583,11 @@ class Site < ApplicationRecord updated_at < File.mtime(File.join(path, 'Gemfile')) end - # Detecta si el Gemfile.lock fue modificado + # Detecta si el Gemfile.lock fue modificado con respecto al sitio o al + # Gemfile. def gemfile_lock_updated? - updated_at < File.mtime(File.join(path, 'Gemfile.lock')) + [updated_at, File.mtime(File.join(path, 'Gemfile'))].any? do |compare| + compare < File.mtime(File.join(path, 'Gemfile.lock')) + end end end From 65011fb8048da46f8367128f440e7f7d375b9186 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Sep 2023 14:58:24 -0300 Subject: [PATCH 188/814] fix: actualizar la fecha del gemfile --- app/models/site.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 6693c1d2..3e88d628 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -568,6 +568,7 @@ class Site < ApplicationRecord if !gems_installed? || gemfile_updated? || gemfile_lock_updated? deploy_local.bundle touch + File.touch(gemfile_path) end end @@ -588,7 +589,11 @@ class Site < ApplicationRecord # Detecta si el Gemfile fue modificado def gemfile_updated? - updated_at < File.mtime(File.join(path, 'Gemfile')) + updated_at < File.mtime(gemfile_path) + end + + def gemfile_path + @gemfile_path ||= File.join(path, 'Gemfile') end # @return [String] From 59f8f8aabbab3ef93572dacae14e56ea724364c8 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 27 Sep 2023 14:29:28 -0300 Subject: [PATCH 189/814] fix: arreglado typo en breadcrumbs en en.yml #13864 --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..6b73205a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -685,7 +685,7 @@ en: new: 'Create' edit: 'Configure' posts: - new: 'New %{layout}' + new: 'Add %{layout}' edit: 'Editing' usuaries: index: 'Users' From 134d1105f62256b23d64ff4fb88582a880882ec9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 27 Sep 2023 15:48:53 -0300 Subject: [PATCH 190/814] =?UTF-8?q?fix:=20agregada=20la=20fecha=20de=20cre?= =?UTF-8?q?acion=20del=20post=20para=20seleccionar=20posts=20por=20t=C3=AD?= =?UTF-8?q?tulo=20si=20est=C3=A1n=20duplicados=20#14179?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_related_posts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index 092f219a..f20ea85c 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -34,7 +34,7 @@ class MetadataRelatedPosts < MetadataArray end def title(post) - "#{post&.title&.value || post&.slug&.value} (#{post.layout.humanized_name})" + "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.trftime('%F')} (#{post.layout.humanized_name})" end # Encuentra el filtro From 5e05ba7d7b4dcffbb05bf54a2276619ea4de366f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 27 Sep 2023 15:52:33 -0300 Subject: [PATCH 191/814] fix: fix typo #14179 --- app/models/metadata_related_posts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index f20ea85c..25eb3fd1 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -34,7 +34,7 @@ class MetadataRelatedPosts < MetadataArray end def title(post) - "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.trftime('%F')} (#{post.layout.humanized_name})" + "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.strftime('%F')} (#{post.layout.humanized_name})" end # Encuentra el filtro From 8376e663ced7c232d18e3575ce4b6d68abc4af89 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 15:39:12 -0300 Subject: [PATCH 192/814] =?UTF-8?q?feat:=20almacenar=20el=20=C3=BAltimo=20?= =?UTF-8?q?commit=20indexado=20#13780?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20230927153926_add_last_indexed_commit_to_sites.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb diff --git a/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb b/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb new file mode 100644 index 00000000..2d22cbd7 --- /dev/null +++ b/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Almacenar el último commit indexado +class AddLastIndexedCommitToSites < ActiveRecord::Migration[6.1] + def change + add_column :sites, :last_indexed_commit, :string, null: true + end +end From f18d0213dfc4d769ce58fc8ad3d898fd8a65f508 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 15:40:14 -0300 Subject: [PATCH 193/814] =?UTF-8?q?feat:=20guardar=20el=20=C3=BAltimo=20co?= =?UTF-8?q?mmit=20indexado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site/index.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index e11095e3..f728b48b 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -# Indexa todos los artículos de un sitio -# -# TODO: Hacer opcional class Site + # Indexa todos los artículos de un sitio + # + # TODO: Hacer opcional module Index extend ActiveSupport::Concern @@ -15,6 +15,8 @@ class Site def index_posts! Site.transaction do docs.each(&:index!) + + update(last_indexed_commit: repository.head_commit.oid) end end end From 074cb49752fcbbacd8a3ab9424a4210b062ffbc4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 16:20:57 -0300 Subject: [PATCH 194/814] feat: reindexar cambios #13780 --- app/models/site/index.rb | 100 +++++++++++++++++++++++++++++++++++++++ config/locales/en.yml | 3 ++ config/locales/es.yml | 3 ++ 3 files changed, 106 insertions(+) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index f728b48b..ed0932bb 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -12,6 +12,10 @@ class Site after_create :index_posts! has_many :indexed_posts, dependent: :destroy + MODIFIED_STATUSES = %i[added modified].freeze + DELETED_STATUSES = %i[deleted].freeze + LOCALE_FROM_PATH = /\A_/.freeze + def index_posts! Site.transaction do docs.each(&:index!) @@ -19,6 +23,102 @@ class Site update(last_indexed_commit: repository.head_commit.oid) end end + + # Encuentra los artículos modificados entre dos commits y los + # reindexa. + def reindex_changes! + return unless reindexable? + + Site.transaction do + remove_deleted_posts! + reindex_modified_posts! + + update(last_indexed_commit: repository.head_commit.oid) + end + end + + # No hacer nada si el repositorio no cambió o no hubo cambios + # necesarios + def reindexable? + return false if last_indexed_commit.blank? + return false if last_indexed_commit == repository.head_commit.oid + + !indexable_posts.empty? + end + + private + + # Trae el último commit indexado desde el repositorio + # + # @return [Rugged::Commit] + def indexed_commit + @indexed_commit ||= repository.rugged.lookup(last_indexed_commit) + end + + # Calcula la diferencia entre el último commit indexado y el + # actual + # + # XXX: Esto no tiene en cuenta modificaciones en la historia como + # cambio de ramas, reverts y etc, solo asume que se mueve hacia + # adelante en la misma rama o las dos ramas están relacionadas. + # + # @return [Rugged::Diff] + def diff_with_head + @diff_with_head ||= indexed_commit.diff(repository.head_commit) + end + + # Obtiene todos los archivos a reindexar + # + # @return [Array] + def indexable_posts + @indexable_posts ||= + diff_with_head.each_delta.select do |delta| + locales.any? do |locale| + delta.old_file[:path].start_with? "_#{locale}/" + end + end + end + + # Elimina los artículos eliminados o que cambiaron de ubicación + # del índice + def remove_deleted_posts! + indexable_posts.select do |delta| + DELETED_STATUSES.include? delta.status + end.each do |delta| + locale, path = locale_and_path_from(delta.old_file[:path]) + + indexed_posts.destroy_by(locale: locale, path: path).tap do |destroyed_posts| + next unless destroyed_posts.empty? + + Rails.logger.info I18n.t('indexed_posts.deleted', site: name, path: path, records: destroyed_posts.count) + end + end + end + + # Reindexa artículos que cambiaron de ubicación, se agregaron + # o fueron modificados + def reindex_modified_posts! + indexable_posts.select do |delta| + MODIFIED_STATUSES.include? delta.status + end.each do |delta| + locale, path = locale_and_path_from(delta.new_file[:path]) + + site.posts(lang: locale).find(path).index! + end + end + + # Obtiene el idioma y la ruta del post a partir de la ubicación en + # el disco + # + # @return [Array] + def locale_and_path_from(path) + locale, path = path.split(File::SEPARATOR, 2) + + [ + locale.sub(LOCALE_FROM_PATH, ''), + File.basename(path, '.*') + ] + end end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..f2c0d94c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -167,6 +167,7 @@ en: usuarie: User licencia: License design: Design + indexed_post: Indexed post attributes: usuarie: email: 'E-mail address' @@ -709,3 +710,5 @@ en: build_stats: index: title: "Publications" + indexed_posts: + deleted: "Deleted indexed post %{path} from %{site} (records: %{records})" diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..73de7b18 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -167,6 +167,7 @@ es: usuarie: Usuarie licencia: Licencia design: Diseño + indexed_post: Artículo indexado attributes: usuarie: email: 'Correo electrónico' @@ -717,3 +718,5 @@ es: build_stats: index: title: "Publicaciones" + indexed_posts: + deleted: "Eliminado artículo %{path} de %{site} (filas: %{records})" From 1e13985ef82c0dde7068db2bd0e027e8f8419434 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 16:31:23 -0300 Subject: [PATCH 195/814] =?UTF-8?q?fix:=20asumir=20que=20todos=20los=20sit?= =?UTF-8?q?ios=20ya=20est=C3=A1n=20indexados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0230927153926_add_last_indexed_commit_to_sites.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb b/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb index 2d22cbd7..71e08f37 100644 --- a/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb +++ b/db/migrate/20230927153926_add_last_indexed_commit_to_sites.rb @@ -2,7 +2,17 @@ # Almacenar el último commit indexado class AddLastIndexedCommitToSites < ActiveRecord::Migration[6.1] - def change + def up add_column :sites, :last_indexed_commit, :string, null: true + + Site.find_each do |site| + site.update_columns(last_indexed_commit: site.repository.head_commit.oid) + rescue Rugged::Error, Rugged::OSError => e + puts "Falló #{site.name}, ignorando: #{e.message}" + end + end + + def down + remove_column :sites, :last_indexed_commit end end From 997114a89688bb735347f2c12966c24097662a5c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 16:38:19 -0300 Subject: [PATCH 196/814] fix: ya estamos en el contexto del sitio --- app/models/site/index.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index ed0932bb..06c8821b 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -103,7 +103,7 @@ class Site end.each do |delta| locale, path = locale_and_path_from(delta.new_file[:path]) - site.posts(lang: locale).find(path).index! + posts(lang: locale).find(path).index! end end From 85e528e660b2482d6a3b71b39b0f57544135b749 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 16:46:33 -0300 Subject: [PATCH 197/814] fix: solo hacer merge si hubo cambios para traer --- app/jobs/git_pull_job.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index de263403..41a2ec2c 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -3,11 +3,12 @@ # Permite traer los cambios cada vez que se # hace un push al repositorio class GitPullJob < ApplicationJob - # @param :site [Site] - # @param :usuarie [Usuarie] - # @return [nil] - def perform(site, usuarie) - site.repository.fetch - site.repository.merge(usuarie) - end -end \ No newline at end of file + # @param :site [Site] + # @param :usuarie [Usuarie] + # @return [nil] + def perform(site, usuarie) + return unless site.repository.fetch.positive? + + site.repository.merge(usuarie) + end +end From b119cba7e10afcbb4a665c26b4e7ad4d61afff8f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 16:47:00 -0300 Subject: [PATCH 198/814] feat: reindexar los cambios luego de traerlos #13780 --- app/jobs/git_pull_job.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index 41a2ec2c..203e5698 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -10,5 +10,6 @@ class GitPullJob < ApplicationJob return unless site.repository.fetch.positive? site.repository.merge(usuarie) + site.reindex_changes! end end From 0538b3bbfd832a03bf108fd069ba23f442894244 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Sep 2023 16:54:38 -0300 Subject: [PATCH 199/814] fix: no fallar si no hay origin --- app/jobs/git_pull_job.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index 203e5698..949a2cdd 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -7,6 +7,7 @@ class GitPullJob < ApplicationJob # @param :usuarie [Usuarie] # @return [nil] def perform(site, usuarie) + return unless site.repository.origin return unless site.repository.fetch.positive? site.repository.merge(usuarie) From cb2c1b0e7daeab32fdc3f01fca9f7158eaf6918e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 29 Sep 2023 10:10:18 -0300 Subject: [PATCH 200/814] =?UTF-8?q?fix:=20usar=20la=20codificaci=C3=B3n=20?= =?UTF-8?q?correcta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit los archivos con tildes fallaban --- app/models/site/index.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index 06c8821b..6f4714c6 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -108,11 +108,14 @@ class Site end # Obtiene el idioma y la ruta del post a partir de la ubicación en - # el disco + # el disco. + # + # Las rutas vienen en ASCII-9BIT desde Rugged, pero en realidad + # son UTF-8 # # @return [Array] def locale_and_path_from(path) - locale, path = path.split(File::SEPARATOR, 2) + locale, path = path.force_encoding('utf-8').split(File::SEPARATOR, 2) [ locale.sub(LOCALE_FROM_PATH, ''), From 86436aafd70ba21b385e40b5b07a4001552adf64 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 2 Oct 2023 14:36:36 -0300 Subject: [PATCH 201/814] fix: typo en metadata_related_posts.rb #14179 --- app/models/metadata_related_posts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index 25eb3fd1..42d1381b 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -34,7 +34,7 @@ class MetadataRelatedPosts < MetadataArray end def title(post) - "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.strftime('%F')} (#{post.layout.humanized_name})" + "#{post&.title&.value || post&.slug&.value} #{post&.date&.value.strftime('%F')} (#{post.layout.humanized_name})" end # Encuentra el filtro From b67193fbca8533ee0b798f63ac1b2721484ae790 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Nov 2023 17:02:32 -0300 Subject: [PATCH 202/814] feat: soportar varias instancias de distributed press #14540 --- app/models/deploy_distributed_press.rb | 10 ++++++---- ...6_add_default_to_distributed_press_publisher.rb | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 2c892b55..69c162aa 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -101,12 +101,14 @@ class DeployDistributedPress < Deploy # El cliente de la API # - # TODO: cuando soportemos más, tiene que haber una relación entre - # DeployDistributedPress y DistributedPressPublisher. - # # @return [DistributedPressPublisher] def publisher - @publisher ||= DistributedPressPublisher.last + @publisher ||= + if distributed_press_publisher_id + DistributedPressPublisher.find(distributed_press_publisher_id) + else + DistributedPressPublisher.find_by_default(true) + end end # El cliente para actualizar el sitio diff --git a/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb b/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb new file mode 100644 index 00000000..ada9392f --- /dev/null +++ b/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Una instancia es la instancia por defecto +class AddDefaultToDistributedPressPublisher < ActiveRecord::Migration[6.1] + def up + add_column :distributed_press_publishers, :default, :boolean, default: false + + DistributedPressPublisher.last.update(default: true) + end + + def down + remove_column :distributed_press_publishers, :default + end +end From 5540232b7e46aa3ecaa3114d3d2d05079caf4abf Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Nov 2023 17:09:32 -0300 Subject: [PATCH 203/814] fix: la instancia puede repetirse --- app/models/distributed_press_publisher.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/distributed_press_publisher.rb b/app/models/distributed_press_publisher.rb index 6139db93..4c3293e3 100644 --- a/app/models/distributed_press_publisher.rb +++ b/app/models/distributed_press_publisher.rb @@ -13,8 +13,8 @@ class DistributedPressPublisher < ApplicationRecord # @return [IO] attr_reader :logger_out - # La instancia es única - validates_uniqueness_of :instance + # La instancia es necesaria pero no única + validates_presence_of :instance # El token es necesario validates_presence_of :token From f5af85a66eaf822c1f6d3b4e987b9e3a909a4d60 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 1 Nov 2023 17:11:31 -0300 Subject: [PATCH 204/814] fix: guardar el id como JSON --- app/models/deploy_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 69c162aa..58fea294 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -13,7 +13,7 @@ require 'njalla/v1' # Al ser publicado, envía los archivos en un tarball y actualiza la # información. class DeployDistributedPress < Deploy - store :values, accessors: %i[hostname remote_site_id remote_info], coder: JSON + store :values, accessors: %i[hostname remote_site_id remote_info distributed_press_publisher_id], coder: JSON before_create :create_remote_site!, :create_njalla_records! before_destroy :delete_remote_site!, :delete_njalla_records! From 9709f419ca6756d21ba21bb41cad6fce0cb0bb08 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Nov 2023 18:19:13 -0300 Subject: [PATCH 205/814] =?UTF-8?q?fix:=20notificar=20cuando=20falla=20la?= =?UTF-8?q?=20=C3=BAltima=20compilaci=C3=B3n=20#14555?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/deploy_job.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 291991c7..adba1815 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -56,6 +56,10 @@ class DeployJob < ApplicationJob rescue URI::Error nil end.compact + + unless d == @site.deployment_list.last && !status + raise DeployException, 'Falló la compilación' + end rescue StandardError => e status = false seconds ||= 0 From c8e1d502324f427382e74dc97b7b227fccb7c493 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Nov 2023 18:40:34 -0300 Subject: [PATCH 206/814] fix: reversed logic --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index adba1815..3044b59f 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -57,7 +57,7 @@ class DeployJob < ApplicationJob nil end.compact - unless d == @site.deployment_list.last && !status + if d == @site.deployment_list.last && !status raise DeployException, 'Falló la compilación' end rescue StandardError => e From 32fdb4e7967d1f192a035fa31e790c92273b3a53 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 21 Nov 2023 15:45:42 +0100 Subject: [PATCH 207/814] fix: cambiado metodo blob_for para lanzar excepcion y disk_controller_decorator.rb para devolver not_found si no encuentra el blob #14378 --- app/controllers/active_storage/disk_controller_decorator.rb | 3 ++- app/lib/active_storage/service/jekyll_service.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/active_storage/disk_controller_decorator.rb b/app/controllers/active_storage/disk_controller_decorator.rb index 14366a15..aaaa9357 100644 --- a/app/controllers/active_storage/disk_controller_decorator.rb +++ b/app/controllers/active_storage/disk_controller_decorator.rb @@ -6,6 +6,7 @@ module ActiveStorage extend ActiveSupport::Concern included do + rescue_from ActiveRecord::RecordNotFound, with: :page_not_found # Asociar el archivo subido al sitio correspondiente. Cada sitio # tiene su propio servicio de subida de archivos. def update @@ -13,7 +14,7 @@ module ActiveStorage if acceptable_content?(token) named_disk_service(token[:service_name]).upload token[:key], request.body, checksum: token[:checksum] - blob = ActiveStorage::Blob.find_by_key token[:key] + blob = ActiveStorage::Blob.find_by! token[:key] site = Site.find_by_name token[:service_name] site.static_files.attach(blob) diff --git a/app/lib/active_storage/service/jekyll_service.rb b/app/lib/active_storage/service/jekyll_service.rb index e6c5fda6..b33ccf4d 100644 --- a/app/lib/active_storage/service/jekyll_service.rb +++ b/app/lib/active_storage/service/jekyll_service.rb @@ -96,7 +96,7 @@ module ActiveStorage end def blob_for(key) - ActiveStorage::Blob.find_by(key: key, service_name: name) + ActiveStorage::Blob.find_by!(key: key, service_name: name) end end end From c86507e62806e565890ae3746dd398bcafdefb7f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 22 Nov 2023 15:15:49 +0100 Subject: [PATCH 208/814] fix: agregado metodo page_not_found en disk_controller_decorator.rb #14378 --- .../active_storage/disk_controller_decorator.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/active_storage/disk_controller_decorator.rb b/app/controllers/active_storage/disk_controller_decorator.rb index aaaa9357..0ec76c28 100644 --- a/app/controllers/active_storage/disk_controller_decorator.rb +++ b/app/controllers/active_storage/disk_controller_decorator.rb @@ -14,7 +14,7 @@ module ActiveStorage if acceptable_content?(token) named_disk_service(token[:service_name]).upload token[:key], request.body, checksum: token[:checksum] - blob = ActiveStorage::Blob.find_by! token[:key] + blob = ActiveStorage::Blob.find_by_key! token[:key] site = Site.find_by_name token[:service_name] site.static_files.attach(blob) @@ -27,6 +27,12 @@ module ActiveStorage rescue ActiveStorage::IntegrityError head :unprocessable_entity end + + private + def page_not_found(exception) + head :not_found + ExceptionNotifier.notify_exception(exception, data: {params: params.to_hash}) + end end end end From aaf2ca8757e32cc4d0cd567105ecfd46abf18388 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Nov 2023 18:41:49 -0300 Subject: [PATCH 209/814] fix: deshabilitar njalla #14696 --- Gemfile | 1 - Gemfile.lock | 4 -- app/models/deploy_distributed_press.rb | 60 +------------------------- 3 files changed, 2 insertions(+), 63 deletions(-) diff --git a/Gemfile b/Gemfile index 972560b4..bf9e875c 100644 --- a/Gemfile +++ b/Gemfile @@ -40,7 +40,6 @@ gem 'devise' gem 'devise-i18n' gem 'devise_invitable' gem 'distributed-press-api-client', '~> 0.3.0rc0' -gem 'njalla-api-client', '~> 0.2.0' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 39394a8c..3faad5e8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -366,9 +366,6 @@ GEM net-ssh (7.1.0) netaddr (2.0.6) nio4r (2.5.9-x86_64-linux-musl) - njalla-api-client (0.2.0) - dry-schema - httparty (~> 0.18) nokogiri (1.15.4-x86_64-linux-musl) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -636,7 +633,6 @@ DEPENDENCIES mini_magick mobility net-ssh - njalla-api-client (~> 0.2.0) nokogiri pg pg_search diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 2c892b55..da8fe209 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'distributed_press/v1/client/site' -require 'njalla/v1' # Soportar Distributed Press APIv1 # @@ -15,8 +14,8 @@ require 'njalla/v1' class DeployDistributedPress < Deploy store :values, accessors: %i[hostname remote_site_id remote_info], coder: JSON - before_create :create_remote_site!, :create_njalla_records! - before_destroy :delete_remote_site!, :delete_njalla_records! + before_create :create_remote_site! + before_destroy :delete_remote_site! DEPENDENCIES = %i[deploy_local] @@ -31,17 +30,12 @@ class DeployDistributedPress < Deploy time_start create_remote_site! if remote_site_id.blank? - create_njalla_records! save if remote_site_id.blank? raise DeployJob::DeployException, 'El sitio no se creó en Distributed Press' end - if create_njalla_records? && remote_info[:njalla].blank? - raise DeployJob::DeployException, 'No se pudieron crear los registros necesarios en Njalla' - end - site_client.tap do |c| stdout = Thread.new(publisher.logger_out) do |io| until io.eof? @@ -145,29 +139,6 @@ class DeployDistributedPress < Deploy nil end - # Crea los registros en Njalla - # - # XXX: Esto depende de nuestro DNS actual, cuando lo migremos hay - # que eliminarlo. - # - # @return [nil] - def create_njalla_records! - return unless create_njalla_records? - - self.remote_info ||= {} - self.remote_info[:njalla] ||= {} - self.remote_info[:njalla][:a] ||= njalla.add_record(name: site.name, type: 'CNAME', content: "#{Site.domain}.").to_h - self.remote_info[:njalla][:cname] ||= njalla.add_record(name: "www.#{site.name}", type: 'CNAME', content: "#{Site.domain}.").to_h - self.remote_info[:njalla][:ns] ||= njalla.add_record(name: "_dnslink.#{site.name}", type: 'NS', content: "#{publisher.hostname}.").to_h - - nil - rescue HTTParty::Error => e - ExceptionNotifier.notify_exception(e, data: { site: site.name }) - self.remote_info.delete :njalla - ensure - nil - end - # Registra lo que sucedió # # @param status [Bool] @@ -185,31 +156,4 @@ class DeployDistributedPress < Deploy ExceptionNotifier.notify_exception(e, data: { site: site.name }) nil end - - def delete_njalla_records! - return unless create_njalla_records? - - %w[a ns cname].each do |type| - next if (id = remote_info.dig('njalla', type, 'id')).blank? - - njalla.remove_record(id: id.to_i) - end - end - - # Actualizar registros en Njalla - # - # @return [Njalla::V1::Domain] - def njalla - @njalla ||= - begin - client = Njalla::V1::Client.new(token: Rails.application.credentials.njalla) - - Njalla::V1::Domain.new(domain: Site.domain, client: client) - end - end - - # Detecta si tenemos que crear registros en Njalla - def create_njalla_records? - !site.name.end_with?('.') - end end From 72d8171c3696e7eb6a19ea5cd993d590ecc4855d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Nov 2023 18:20:20 -0300 Subject: [PATCH 210/814] fix: img-fluid sutty/editor#99 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2974a8b3..8bb4e91f 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", - "@suttyweb/editor": "^0.1.24", + "@suttyweb/editor": "^0.1.25", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From 89063d50c02a3627da5b1e820764dabe9dfe5e7f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Dec 2023 17:50:53 -0300 Subject: [PATCH 211/814] fix: no cambiar el nombre de dominio #14746 --- app/models/site.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index a8c5e376..c40dd6f9 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -501,8 +501,8 @@ class Site < ApplicationRecord config.theme = design.gem unless design.no_theme? config.description = description config.title = title - config.url = url(slash: false) - config.hostname = hostname + config.url ||= url(slash: false) + config.hostname ||= hostname config.locales = locales.map(&:to_s) end From 96bc688e2d926fb650ef8840c092bab7e6b590b5 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Dec 2023 18:24:38 -0300 Subject: [PATCH 212/814] fix: permitir cargar tiempo #14763 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jekyll-activity-pub podría establecer una fecha de creación del sitio --- app/models/site/config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site/config.rb b/app/models/site/config.rb index fb9175c1..b300b40e 100644 --- a/app/models/site/config.rb +++ b/app/models/site/config.rb @@ -21,7 +21,7 @@ class Site # Leer el archivo de configuración y setear los atributos en el # objeto actual, creando los metodos de ostruct def read - data = YAML.safe_load(File.read(path)) + data = YAML.safe_load(File.read(path), permitted_classes: [Time]) @hash = data.hash data.each do |key, value| From e889f29d17b616bb62e5f4ee94bcde68a6d07668 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 7 Dec 2023 15:37:46 +0100 Subject: [PATCH 213/814] fix: modificado metodo Reload en site.rb #14700 --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index a8c5e376..10a5e27b 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -396,7 +396,7 @@ class Site < ApplicationRecord def reload super - reload_jekyll! + site.self end def configuration From 61e20a3a133304615b9fdeb81be68f4c2d2aaeaa Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 7 Dec 2023 16:05:20 +0100 Subject: [PATCH 214/814] fix: corregido metodo Reload en site.rb #14700 --- app/models/site.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index 10a5e27b..507b51ec 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -395,8 +395,10 @@ class Site < ApplicationRecord end def reload - super - site.self + super.tap do |s| + reload_jekyll! + end + self end def configuration From c66a7660c10c551bba8c6981a201530feb853317 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 7 Dec 2023 17:24:04 +0100 Subject: [PATCH 215/814] fix: modificado metodo Gateways_urls para que devuelva solamente links en deploy_distributed_press.rb #14550 --- app/models/deploy_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index da8fe209..bfa43441 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -87,7 +87,7 @@ class DeployDistributedPress < Deploy # @return [Array] def gateway_urls remote_info.dig(:distributed_press, :links)&.values&.map do |protocol| - [ protocol[:link], protocol[:gateway] ] + [ protocol[:link]] end&.flatten&.compact&.select do |link| link.include? '://' end || [] From 2c99820f35c3dcca563c7155efef2cdd0ccc0e4c Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 12 Dec 2023 18:15:23 +0100 Subject: [PATCH 216/814] feat: agregado metodo de limpieza de git-lfs en cleanup_service.rb #8521 --- app/services/cleanup_service.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/services/cleanup_service.rb b/app/services/cleanup_service.rb index ad87cf9a..c03858bd 100644 --- a/app/services/cleanup_service.rb +++ b/app/services/cleanup_service.rb @@ -29,6 +29,7 @@ class CleanupService site.deploys.find_each(&:cleanup!) site.repository.gc + lfs_cleanup site.touch end end @@ -41,7 +42,14 @@ class CleanupService next unless File.directory? site.path site.repository.gc + lfs_cleanup site.touch end end + + private + def lfs_cleanup + site.repository.git_sh("git", "lfs", "prune") + site.repository.git_sh("git", "lfs", "dedup") + end end From e3b721320af2a3a5091fa674b6d43eefae0d4da5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 12 Dec 2023 19:02:53 +0100 Subject: [PATCH 217/814] feat: agregado formulario seguimiento automatico del fediverso #14779 --- config/locales/en.yml | 3 +++ config/locales/es.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 53dd25c6..4b420dd7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -325,6 +325,9 @@ en: [Pixelfed](https://pixelfed.social/site/about), and [others](https://fediverse.party/)) can follow your site, receive news and interact with them. + Also there is the possibility that Sutty advertises your content and/or Fediverse user + automatically to attract followers. You can do it with this + [Form](https://cryptpad.fr/form/#/2/form/view/XorL4I-nC17rcEwtol3ghsRDsivfg6g5685MK+TFZ-8/) stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index 7a8ac738..2147f349 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -330,6 +330,9 @@ es: [Pixelfed](https://pixelfed.social/site/about) y [otros](https://fediverse.party/)) pueden seguir a tu sitio, recibir novedades e interactuar con ellas. + También existe la posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse + en forma automática para atraer seguidorxs. Podés hacerlo con este + [Formulario](https://cryptpad.fr/form/#/2/form/view/XorL4I-nC17rcEwtol3ghsRDsivfg6g5685MK+TFZ-8/) stats: index: title: Estadísticas From d60ec0cf11c1e2506e41ae8a73d066b666dd97aa Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 13 Dec 2023 14:34:26 +0100 Subject: [PATCH 218/814] fix: corregido enlace a formulario en en.yml #14779 --- config/locales/en.yml | 7 ++++--- config/locales/es.yml | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 4b420dd7..a8bea116 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -325,9 +325,10 @@ en: [Pixelfed](https://pixelfed.social/site/about), and [others](https://fediverse.party/)) can follow your site, receive news and interact with them. - Also there is the possibility that Sutty advertises your content and/or Fediverse user - automatically to attract followers. You can do it with this - [Form](https://cryptpad.fr/form/#/2/form/view/XorL4I-nC17rcEwtol3ghsRDsivfg6g5685MK+TFZ-8/) + + There is also the possibility that Sutty advertises your content and/or Fediverse + user automatically to attract followers. You can do it with this + [form](https://cryptpad.fr/form/#/2/form/view/yp1KZwQjgU2RG-zhdQCyw4M8QhftNCVu8e+IJG2iN7Y/) stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index 2147f349..61b49969 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -330,6 +330,7 @@ es: [Pixelfed](https://pixelfed.social/site/about) y [otros](https://fediverse.party/)) pueden seguir a tu sitio, recibir novedades e interactuar con ellas. + También existe la posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. Podés hacerlo con este [Formulario](https://cryptpad.fr/form/#/2/form/view/XorL4I-nC17rcEwtol3ghsRDsivfg6g5685MK+TFZ-8/) From 1a3c6a77ce931371eb18d7a0563790f3285cc386 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Dec 2023 14:33:17 -0300 Subject: [PATCH 219/814] fix: correr psql dentro de hain --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5d6c066b..7b40d941 100644 --- a/Makefile +++ b/Makefile @@ -76,7 +76,7 @@ copy-table: ssh $(delegate) docker exec postgresql pg_dump -U sutty -d sutty -t $(table) | $(psql) psql: - $(psql) + $(hain) $(psql) rubocop: ## Yutea el código que está por ser commiteado git status --porcelain \ From c5cece436dc63f6340d6310d61ae4e8c26bc127a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Dec 2023 14:36:47 -0300 Subject: [PATCH 220/814] fix: usar la url de la base de datos en psql --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7b40d941..f295a3e0 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ rake: ## Corre rake dentro del entorno de desarrollo (pasar argumentos con args= bundle: ## Corre bundle dentro del entorno de desarrollo (pasar argumentos con args=). $(hain) 'bundle $(args)' -psql := psql -h $(PG_HOST) -U $(PG_USER) -p $(PG_PORT) -d sutty +psql := psql $(DATABASE_URL) copy-table: test -n "$(table)" echo "truncate $(table) $(cascade);" | $(psql) From c007f3b0e3c0864aeb6360bde92e4c0bcb11cacf Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Jul 2022 13:50:30 -0300 Subject: [PATCH 221/814] no actualizar al cargar el listado de sitios hace que todo tarde demasiado tiempo (cherry picked from commit 15454596f21fe2a0059e71d573a84fbc937a6a36) --- app/views/sites/index.haml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index 56178775..b7231292 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -54,10 +54,4 @@ text: t('usuaries.index.title'), type: 'info', link: site_usuaries_path(site) - - if policy(site).pull? && site.repository.needs_pull? - = render 'layouts/btn_with_tooltip', - tooltip: t('help.sites.pull'), - text: t('.pull'), - type: 'info', - link: site_pull_path(site) = render 'sites/build', site: site From c1874af5bf1bca3d762e904ec419eaf9660ad687 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 2 Jan 2024 15:00:43 -0300 Subject: [PATCH 222/814] Revert "fix: deshabilitar el modo oscuro #12994" This reverts commit e504501678096249dea3f170ccede64c7f191cd2. --- app/assets/stylesheets/application.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 06c0f8df..bba48558 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -46,6 +46,14 @@ $sizes: ( --color: #{$magenta}; } +@media (prefers-color-scheme: dark) { + :root { + --foreground: #{$white}; + --background: #{$black}; + --color: #{$cyan}; + } +} + // TODO: Encontrar la forma de generar esto desde los locales de Rails $custom-file-text: ( en: 'Browse', From c1187943e32f0b34d0982f2cbcdcc8160e9cc7a8 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 2 Jan 2024 15:15:37 -0300 Subject: [PATCH 223/814] BREAKING CHANGE: deprecar jekyll-data --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index 5f1f6268..4c7cab37 100644 --- a/Gemfile +++ b/Gemfile @@ -53,7 +53,6 @@ gem 'inline_svg' gem 'httparty' gem 'safe_yaml' gem 'jekyll', '~> 4.2.0' -gem 'jekyll-data' gem 'jekyll-commonmark' gem 'jekyll-images' gem 'jekyll-include-cache' From b478d91d0242ce8a9dd7ef3e9cb23bb95f26361e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 13:59:44 -0300 Subject: [PATCH 224/814] ci: assets [skip ci] --- .../.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json | 4 ++-- ...74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js | 3 +++ ...0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz | 3 +++ ...e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css | 3 +++ ...8768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz | 3 +++ ...fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css | 3 +++ ...016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz | 3 +++ ...9a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js | 3 +++ ...95c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz | 3 +++ ...cd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css | 3 +++ ...cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz | 3 +++ ...34efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css | 3 +++ ...fdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz | 3 +++ ...91bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js | 0 ...b910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz | 3 +++ ...1a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css | 3 +++ ...d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz | 3 +++ 17 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js create mode 100644 public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz create mode 100644 public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css create mode 100644 public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz create mode 100644 public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css create mode 100644 public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz create mode 100644 public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js create mode 100644 public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz create mode 100644 public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css create mode 100644 public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz create mode 100644 public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css create mode 100644 public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz create mode 100644 public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js create mode 100644 public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz create mode 100644 public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css create mode 100644 public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz diff --git a/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json index 862103e6..efff86d9 100644 --- a/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json +++ b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abb17ebe7d32c8d1bc90cc26c95cd99188a8ea066d8c975834b8299b7297f157 -size 11872 +oid sha256:70db348a921487a61c0bf1006f8ecfc38e44905b4b9d8e3527a5783a6275734e +size 10242 diff --git a/public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js b/public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js new file mode 100644 index 00000000..00eb1f78 --- /dev/null +++ b/public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:180d06e627b032f75d76aba6172b3aa58d171fb0a0f1142f29448d10fc5ec5a9 +size 16449 diff --git a/public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz b/public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz new file mode 100644 index 00000000..bcf59744 --- /dev/null +++ b/public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c491d95b7e2535cb55d8ba4a77a5045976300025ceb4c52f1c587e2e894538a +size 5157 diff --git a/public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css b/public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css new file mode 100644 index 00000000..37581324 --- /dev/null +++ b/public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1097893171f39792c842be23ad64b1d37080c3ab988bf4d94fa95897e5a592e +size 235889 diff --git a/public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz b/public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz new file mode 100644 index 00000000..e8eaa95c --- /dev/null +++ b/public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:382d60f2ae3ec6916daa7b4dfbd008afdd3657339f29f00f0ed8bce584488dd0 +size 32779 diff --git a/public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css b/public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css new file mode 100644 index 00000000..6ec43dde --- /dev/null +++ b/public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea293694663cf946057fdb9573bac081112128fe87f2405f0fe668141ee37b2b +size 134244 diff --git a/public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz b/public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz new file mode 100644 index 00000000..e4e580e4 --- /dev/null +++ b/public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:442a323c02cbf67b1d0c973441f2ecee8bb78e6df8518bec35a95e4c0d2c3eda +size 23302 diff --git a/public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js b/public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js new file mode 100644 index 00000000..5ea9b7f1 --- /dev/null +++ b/public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7425badb1fcf60b27d22aed3d4ff8a68c9f65770127234714db354a6dddbd37 +size 1974293 diff --git a/public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz b/public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz new file mode 100644 index 00000000..cb1be13e --- /dev/null +++ b/public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71813e15686111989234a533a7c639cbcd64c1ec9a4999ac31b279300b9848cb +size 378607 diff --git a/public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css b/public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css new file mode 100644 index 00000000..6a5c5339 --- /dev/null +++ b/public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2667cb03c8e57b2f19bb68f06f479054f73c61e2c355113230d5177a7029eed2 +size 64 diff --git a/public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz b/public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz new file mode 100644 index 00000000..6b720779 --- /dev/null +++ b/public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:166171efdf9e62a561adbdb3e9fb92a5849d8c6ae83d638f0ab6b9ba221dbd23 +size 75 diff --git a/public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css b/public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css new file mode 100644 index 00000000..16758e87 --- /dev/null +++ b/public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c30e9a9afbc33c17d773933cc2a0e07c0bfc7f39547bd304c7e0ce6cd459414 +size 2233 diff --git a/public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz b/public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz new file mode 100644 index 00000000..52f3fcad --- /dev/null +++ b/public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f83d57dc7bfdc6e3640f36eb5c53bd32bfd301c2d136ed565964cee5e25badc +size 678 diff --git a/public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js b/public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js new file mode 100644 index 00000000..e69de29b diff --git a/public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz b/public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz new file mode 100644 index 00000000..d673f46c --- /dev/null +++ b/public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d669538fdf855979be9c4089f9469a7f2ee433ce58a19ac633f478afcffc6e1e +size 20 diff --git a/public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css b/public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css new file mode 100644 index 00000000..56ae4aa9 --- /dev/null +++ b/public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8d681a496901b8002289244aed10757942ed7a9397e731adaf2b21e4b05c888 +size 249 diff --git a/public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz b/public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz new file mode 100644 index 00000000..b8804da9 --- /dev/null +++ b/public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f886217faf0cc7c1ec6a115c1bfea6f71d016784230989d5fad9129c3cec64de +size 143 From 156a801e7d368ee6be8c72f0e1c35c56dc90290f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:17:48 -0300 Subject: [PATCH 225/814] feat: taskfile --- Makefile | 9 --------- Taskfile.yaml | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 Taskfile.yaml diff --git a/Makefile b/Makefile index f295a3e0..f29bfa47 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,6 @@ SHELL := /bin/bash .DEFAULT_GOAL := help -# Copiar el archivo de configuración y avisar cuando hay que -# actualizarlo. -.env: .env.example - @test -f $@ || cp -v $< $@ - @test -f $@ && echo "Revisa $@ para actualizarlo con respecto a $<" - @test -f $@ && diff -auN --color $@ $< - -include .env - export # XXX: El espacio antes del comentario cuenta como espacio diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 00000000..8e2b2310 --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,20 @@ +--- +version: "3" +vars: + CURRENT_BRANCH: + sh: "git rev-parse --abbrev-ref HEAD" +shopt: +- "globstar" +dotenv: +- ".env" +tasks: + env: + desc: "Install the .env file" + cmds: + - ": Environment vars have changed, please review and edit" + - "cp --no-clobber .env.example .env" + - "diff -auN --color .env.example .env" + sources: + - ".env.example" + generates: + - ".env" From 497124bf275c4376fc1c74ad00ee723fd07b74f9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:26:32 -0300 Subject: [PATCH 226/814] fix: panel --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index f3cf48d9..c7322d1a 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ # pwgen -1 32 RAILS_MASTER_KEY=11111111111111111111111111111111 RAILS_GROUPS=assets -DELEGATE=athshe.sutty.nl +DELEGATE=panel.sutty.nl HAINISH=../haini.sh/haini.sh DATABASE_URL=postgres://suttier@postgresql.sutty.local/sutty RAILS_ENV=development From 936c3f83c1108798b102ff42beccab600eb687a5 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:38:21 -0300 Subject: [PATCH 227/814] =?UTF-8?q?fix:=20m=C3=A1s=20visible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Taskfile.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 8e2b2310..2a3b9709 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -11,8 +11,8 @@ tasks: env: desc: "Install the .env file" cmds: - - ": Environment vars have changed, please review and edit" - "cp --no-clobber .env.example .env" + - ": == Environment vars have changed, please review and edit ==" - "diff -auN --color .env.example .env" sources: - ".env.example" From 39b536dab7f3bb6058aa1d640f053676fc6129de Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:38:44 -0300 Subject: [PATCH 228/814] feat: install gems --- Taskfile.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index 2a3b9709..85b636ab 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -18,3 +18,11 @@ tasks: - ".env.example" generates: - ".env" + gems: + desc: "Install gems" + cmds: + - "haini.sh bundle" + sources: + - "Gemfile" + generates: + - "Gemfile.lock" From 42c80f8749878f714ae028c4b993f0cf05d582e3 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:40:05 -0300 Subject: [PATCH 229/814] feat: clean --- Makefile | 3 --- Taskfile.yaml | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f29bfa47..541d072b 100644 --- a/Makefile +++ b/Makefile @@ -86,9 +86,6 @@ brakeman: ## Busca posibles vulnerabilidades en Sutty yarn: ## Tareas de yarn $(hain) 'yarn $(args)' -clean: ## Limpieza - rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage - build: Gemfile.lock ## Generar la imagen Docker time docker build --build-arg="BRANCH=$(branch)" --build-arg="RAILS_MASTER_KEY=`cat config/master.key`" -t sutty/$(container) . docker tag sutty/$(container):latest sutty:keep diff --git a/Taskfile.yaml b/Taskfile.yaml index 85b636ab..26f3901d 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -26,3 +26,7 @@ tasks: - "Gemfile" generates: - "Gemfile.lock" + clean: + desc: "Clean" + cmds: + - "rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage" From d86a4b340405c91eac5a69f6a51e49c72ca8e1cd Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:47:10 -0300 Subject: [PATCH 230/814] fix: actualizar webpacker ya no es necesario python2 --- package.json | 2 +- yarn.lock | 2412 ++++++++++++++++++++++++++++---------------------- 2 files changed, 1363 insertions(+), 1051 deletions(-) diff --git a/package.json b/package.json index 8bb4e91f..7901ad41 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@rails/actiontext": "^6.0.0", "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", - "@rails/webpacker": "5.2.1", + "@rails/webpacker": "5.4.4", "@suttyweb/editor": "^0.1.25", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", diff --git a/yarn.lock b/yarn.lock index c68ca2b0..0c52b9d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,6 +14,14 @@ promise-polyfill "^8.1.3" tdigest "^0.1.1" +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.8.3": version "7.12.13" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz" @@ -21,31 +29,23 @@ dependencies: "@babel/highlight" "^7.12.13" +"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + "@babel/compat-data@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.13.tgz" integrity sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg== -"@babel/core@^7.11.1": - version "7.12.16" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.12.16.tgz" - integrity sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.12.15" - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helpers" "^7.12.13" - "@babel/parser" "^7.12.16" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - semver "^5.4.1" - source-map "^0.5.0" +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.3", "@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@^7.12.17": version "7.12.17" @@ -68,7 +68,28 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.13", "@babel/generator@^7.12.15": +"@babel/core@^7.15.0": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.7.tgz#4d8016e06a14b5f92530a13ed0561730b5c6483f" + integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.7" + "@babel/parser" "^7.23.6" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.12.13": version "7.12.15" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz" integrity sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ== @@ -86,6 +107,16 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz" @@ -93,6 +124,13 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz" @@ -101,15 +139,12 @@ "@babel/helper-explode-assignable-expression" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.12.16": - version "7.12.16" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.16.tgz" - integrity sha512-dBHNEEaZx7F3KoUYqagIhRIeqyyuI65xMndMZ3WwGwEBI609I4TleYQHcrS627vbKyNTXqShoN+fvYD9HuQxAg== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== dependencies: - "@babel/compat-data" "^7.12.13" - "@babel/helper-validator-option" "^7.12.16" - browserslist "^4.14.5" - semver "^5.5.0" + "@babel/types" "^7.22.15" "@babel/helper-compilation-targets@^7.12.17": version "7.12.17" @@ -121,6 +156,17 @@ browserslist "^4.14.5" semver "^5.5.0" +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.12.13": version "7.12.16" resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.16.tgz" @@ -143,6 +189,21 @@ "@babel/helper-replace-supers" "^7.12.13" "@babel/helper-split-export-declaration" "^7.12.13" +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.15": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz#b2e6826e0e20d337143655198b79d58fdc9bd43d" + integrity sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.12.13": version "7.12.16" resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.16.tgz" @@ -151,6 +212,31 @@ "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz#64df615451cb30e94b59a9696022cffac9a10088" + integrity sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-explode-assignable-expression@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz" @@ -167,6 +253,14 @@ "@babel/template" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz" @@ -181,6 +275,13 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-member-expression-to-functions@^7.12.13", "@babel/helper-member-expression-to-functions@^7.12.16": version "7.12.16" resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz" @@ -195,6 +296,13 @@ dependencies: "@babel/types" "^7.12.17" +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + "@babel/helper-module-imports@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz" @@ -202,6 +310,13 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-module-transforms@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz" @@ -232,6 +347,17 @@ "@babel/types" "^7.12.17" lodash "^4.17.19" +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz" @@ -239,11 +365,23 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz" integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA== +"@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + "@babel/helper-remap-async-to-generator@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz" @@ -253,6 +391,15 @@ "@babel/helper-wrap-function" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/helper-remap-async-to-generator@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + "@babel/helper-replace-supers@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz" @@ -263,6 +410,15 @@ "@babel/traverse" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/helper-replace-supers@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-simple-access@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz" @@ -270,6 +426,13 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz" @@ -277,6 +440,13 @@ dependencies: "@babel/types" "^7.12.1" +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-split-export-declaration@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz" @@ -284,21 +454,38 @@ dependencies: "@babel/types" "^7.12.13" +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + "@babel/helper-validator-identifier@^7.12.11": version "7.12.11" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== -"@babel/helper-validator-option@^7.12.16": - version "7.12.16" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz" - integrity sha512-uCgsDBPUQDvzr11ePPo4TVEocxj8RXjUVSC/Y8N1YpVAI/XDdUwGJu78xmlGhTxj2ntaWM7n9LQdRtyhOzT2YQ== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== "@babel/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + "@babel/helper-wrap-function@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz" @@ -309,14 +496,14 @@ "@babel/traverse" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helpers@^7.12.13": - version "7.12.13" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.13.tgz" - integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ== +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== dependencies: - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" "@babel/helpers@^7.12.17": version "7.12.17" @@ -327,6 +514,15 @@ "@babel/traverse" "^7.12.17" "@babel/types" "^7.12.17" +"@babel/helpers@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.7.tgz#eb543c36f81da2873e47b76ee032343ac83bba60" + integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + "@babel/highlight@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz" @@ -336,7 +532,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.12.13", "@babel/parser@^7.12.16": +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.12.13": version "7.12.16" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz" integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw== @@ -346,6 +551,35 @@ resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz" integrity sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" + integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" + integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" + integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.23.3" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz#516462a95d10a9618f197d39ad291a9b47ae1d7b" + integrity sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-proposal-async-generator-functions@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz" @@ -355,7 +589,7 @@ "@babel/helper-remap-async-to-generator" "^7.12.13" "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.12.13": +"@babel/plugin-proposal-class-properties@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz" integrity sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA== @@ -363,13 +597,13 @@ "@babel/helper-create-class-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-proposal-dynamic-import@^7.12.16": - version "7.12.16" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.16.tgz" - integrity sha512-yiDkYFapVxNOCcBfLnsb/qdsliroM+vc3LHiZwS4gh7pFjo5Xq3BDhYBNn3H3ao+hWPvqeeTdU+s+FIvokov+w== +"@babel/plugin-proposal-class-properties@^7.14.5": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-dynamic-import@^7.12.17": version "7.12.17" @@ -419,7 +653,7 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.10.1", "@babel/plugin-proposal-object-rest-spread@^7.12.13": +"@babel/plugin-proposal-object-rest-spread@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz" integrity sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg== @@ -428,6 +662,17 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-transform-parameters" "^7.12.13" +"@babel/plugin-proposal-object-rest-spread@^7.14.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== + dependencies: + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.20.7" + "@babel/plugin-proposal-optional-catch-binding@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz" @@ -436,15 +681,6 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.12.16": - version "7.12.16" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.16.tgz" - integrity sha512-O3ohPwOhkwji5Mckb7F/PJpJVJY3DpPsrt/F0Bk40+QMk9QpAIqeGusHWqu/mYqsM8oBa6TziL/2mbERWsUZjg== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-proposal-optional-chaining@^7.12.17": version "7.12.17" resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.17.tgz" @@ -462,6 +698,11 @@ "@babel/helper-create-class-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz" @@ -470,7 +711,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-async-generators@^7.8.0": +"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== @@ -484,6 +725,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" @@ -498,7 +746,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-json-strings@^7.8.0": +"@babel/plugin-syntax-import-assertions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== @@ -512,7 +781,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== @@ -526,27 +795,34 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": +"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0": +"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-top-level-await@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz" @@ -554,6 +830,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-typescript@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz" @@ -561,6 +844,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-arrow-functions@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz" @@ -568,6 +859,23 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-arrow-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-async-generator-functions@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz#3aa0b4f2fa3788b5226ef9346cf6d16ec61f99cd" + integrity sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-transform-async-to-generator@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.13.tgz" @@ -577,6 +885,15 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-remap-async-to-generator" "^7.12.13" +"@babel/plugin-transform-async-to-generator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== + dependencies: + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-transform-block-scoped-functions@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz" @@ -584,6 +901,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-block-scoped-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-block-scoping@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz" @@ -591,6 +915,30 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-block-scoping@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" + integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-transform-classes@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz" @@ -604,6 +952,21 @@ "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" +"@babel/plugin-transform-classes@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz#e7a75f815e0c534cc4c9a39c56636c84fc0d64f2" + integrity sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + "@babel/plugin-transform-computed-properties@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz" @@ -611,13 +974,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-destructuring@^7.10.1", "@babel/plugin-transform-destructuring@^7.12.13": +"@babel/plugin-transform-computed-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.15" + +"@babel/plugin-transform-destructuring@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz" integrity sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-destructuring@^7.14.7", "@babel/plugin-transform-destructuring@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz" @@ -626,6 +1004,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-dotall-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" + integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-duplicate-keys@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz" @@ -633,6 +1019,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-duplicate-keys@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" + integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dynamic-import@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" + integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz" @@ -641,6 +1042,22 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-exponentiation-operator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" + integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-export-namespace-from@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" + integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-transform-for-of@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz" @@ -648,6 +1065,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-for-of@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz#81c37e24171b37b370ba6aaffa7ac86bcb46f94e" + integrity sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-function-name@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz" @@ -656,6 +1081,23 @@ "@babel/helper-function-name" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-function-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-json-strings@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" + integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-transform-literals@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz" @@ -663,6 +1105,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-logical-assignment-operators@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" + integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-transform-member-expression-literals@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz" @@ -670,6 +1127,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-member-expression-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-modules-amd@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz" @@ -679,6 +1143,14 @@ "@babel/helper-plugin-utils" "^7.12.13" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-amd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" + integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-modules-commonjs@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz" @@ -689,6 +1161,15 @@ "@babel/helper-simple-access" "^7.12.13" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-commonjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/plugin-transform-modules-systemjs@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz" @@ -700,6 +1181,16 @@ "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-systemjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz#fa7e62248931cb15b9404f8052581c302dd9de81" + integrity sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + "@babel/plugin-transform-modules-umd@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz" @@ -708,6 +1199,14 @@ "@babel/helper-module-transforms" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-modules-umd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" + integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz" @@ -715,6 +1214,14 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-new-target@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz" @@ -722,6 +1229,40 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-new-target@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" + integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" + integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" + integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" + integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== + dependencies: + "@babel/compat-data" "^7.23.3" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-object-super@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz" @@ -730,6 +1271,31 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-replace-supers" "^7.12.13" +"@babel/plugin-transform-object-super@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + +"@babel/plugin-transform-optional-catch-binding@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" + integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" + integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-transform-parameters@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz" @@ -737,6 +1303,31 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" + integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" + integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-transform-property-literals@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz" @@ -744,13 +1335,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-regenerator@^7.10.1", "@babel/plugin-transform-regenerator@^7.12.13": +"@babel/plugin-transform-property-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz" integrity sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA== dependencies: regenerator-transform "^0.14.2" +"@babel/plugin-transform-regenerator@^7.14.5", "@babel/plugin-transform-regenerator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" + integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + "@babel/plugin-transform-reserved-words@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz" @@ -758,14 +1364,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-runtime@^7.11.0": - version "7.12.15" - resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.15.tgz" - integrity sha512-OwptMSRnRWJo+tJ9v9wgAf72ydXWfYSXWhnQjZing8nGZSDFqU1MBleKM3+DriKkcbv7RagA8gVeB0A1PNlNow== +"@babel/plugin-transform-reserved-words@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" + integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - semver "^5.5.1" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-runtime@^7.12.17": version "7.12.17" @@ -776,6 +1380,18 @@ "@babel/helper-plugin-utils" "^7.12.13" semver "^5.5.1" +"@babel/plugin-transform-runtime@^7.15.0": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.7.tgz#52bbd20054855beb9deae3bee9ceb05289c343e6" + integrity sha512-fa0hnfmiXc9fq/weK34MUV0drz2pOL/vfKWvN7Qw127hiUPabFCUMgAbYWcchRzMJit4o5ARsK/s+5h0249pLw== + dependencies: + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.7" + babel-plugin-polyfill-corejs3 "^0.8.7" + babel-plugin-polyfill-regenerator "^0.5.4" + semver "^6.3.1" + "@babel/plugin-transform-shorthand-properties@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz" @@ -783,6 +1399,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-shorthand-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-spread@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz" @@ -791,6 +1414,14 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" +"@babel/plugin-transform-spread@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-sticky-regex@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz" @@ -798,6 +1429,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-sticky-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-template-literals@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz" @@ -805,6 +1443,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-template-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-typeof-symbol@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz" @@ -812,6 +1457,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-typeof-symbol@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" + integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-typescript@^7.12.17": version "7.12.17" resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.17.tgz" @@ -828,6 +1480,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-unicode-escapes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" + integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" + integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-unicode-regex@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz" @@ -836,77 +1503,21 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/preset-env@^7.11.0": - version "7.12.16" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.16.tgz" - integrity sha512-BXCAXy8RE/TzX416pD2hsVdkWo0G+tYd16pwnRV4Sc0fRwTLRS/Ssv8G5RLXUGQv7g4FG7TXkdDJxCjQ5I+Zjg== +"@babel/plugin-transform-unicode-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== dependencies: - "@babel/compat-data" "^7.12.13" - "@babel/helper-compilation-targets" "^7.12.16" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-validator-option" "^7.12.16" - "@babel/plugin-proposal-async-generator-functions" "^7.12.13" - "@babel/plugin-proposal-class-properties" "^7.12.13" - "@babel/plugin-proposal-dynamic-import" "^7.12.16" - "@babel/plugin-proposal-export-namespace-from" "^7.12.13" - "@babel/plugin-proposal-json-strings" "^7.12.13" - "@babel/plugin-proposal-logical-assignment-operators" "^7.12.13" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.13" - "@babel/plugin-proposal-numeric-separator" "^7.12.13" - "@babel/plugin-proposal-object-rest-spread" "^7.12.13" - "@babel/plugin-proposal-optional-catch-binding" "^7.12.13" - "@babel/plugin-proposal-optional-chaining" "^7.12.16" - "@babel/plugin-proposal-private-methods" "^7.12.13" - "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.12.13" - "@babel/plugin-transform-arrow-functions" "^7.12.13" - "@babel/plugin-transform-async-to-generator" "^7.12.13" - "@babel/plugin-transform-block-scoped-functions" "^7.12.13" - "@babel/plugin-transform-block-scoping" "^7.12.13" - "@babel/plugin-transform-classes" "^7.12.13" - "@babel/plugin-transform-computed-properties" "^7.12.13" - "@babel/plugin-transform-destructuring" "^7.12.13" - "@babel/plugin-transform-dotall-regex" "^7.12.13" - "@babel/plugin-transform-duplicate-keys" "^7.12.13" - "@babel/plugin-transform-exponentiation-operator" "^7.12.13" - "@babel/plugin-transform-for-of" "^7.12.13" - "@babel/plugin-transform-function-name" "^7.12.13" - "@babel/plugin-transform-literals" "^7.12.13" - "@babel/plugin-transform-member-expression-literals" "^7.12.13" - "@babel/plugin-transform-modules-amd" "^7.12.13" - "@babel/plugin-transform-modules-commonjs" "^7.12.13" - "@babel/plugin-transform-modules-systemjs" "^7.12.13" - "@babel/plugin-transform-modules-umd" "^7.12.13" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" - "@babel/plugin-transform-new-target" "^7.12.13" - "@babel/plugin-transform-object-super" "^7.12.13" - "@babel/plugin-transform-parameters" "^7.12.13" - "@babel/plugin-transform-property-literals" "^7.12.13" - "@babel/plugin-transform-regenerator" "^7.12.13" - "@babel/plugin-transform-reserved-words" "^7.12.13" - "@babel/plugin-transform-shorthand-properties" "^7.12.13" - "@babel/plugin-transform-spread" "^7.12.13" - "@babel/plugin-transform-sticky-regex" "^7.12.13" - "@babel/plugin-transform-template-literals" "^7.12.13" - "@babel/plugin-transform-typeof-symbol" "^7.12.13" - "@babel/plugin-transform-unicode-escapes" "^7.12.13" - "@babel/plugin-transform-unicode-regex" "^7.12.13" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.13" - core-js-compat "^3.8.0" - semver "^5.5.0" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.12.17": version "7.12.17" @@ -980,6 +1591,101 @@ core-js-compat "^3.8.0" semver "^5.5.0" +"@babel/preset-env@^7.15.0": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.7.tgz#e5d69b9f14db8a13bae4d8e5ce7f360973626241" + integrity sha512-SY27X/GtTz/L4UryMNJ6p4fH4nsgWbz84y9FE0bQeWJP6O5BhgVCt53CotQKHCOeXJel8VyhlhujhlltKms/CA== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.7" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.23.3" + "@babel/plugin-syntax-import-attributes" "^7.23.3" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.23.3" + "@babel/plugin-transform-async-generator-functions" "^7.23.7" + "@babel/plugin-transform-async-to-generator" "^7.23.3" + "@babel/plugin-transform-block-scoped-functions" "^7.23.3" + "@babel/plugin-transform-block-scoping" "^7.23.4" + "@babel/plugin-transform-class-properties" "^7.23.3" + "@babel/plugin-transform-class-static-block" "^7.23.4" + "@babel/plugin-transform-classes" "^7.23.5" + "@babel/plugin-transform-computed-properties" "^7.23.3" + "@babel/plugin-transform-destructuring" "^7.23.3" + "@babel/plugin-transform-dotall-regex" "^7.23.3" + "@babel/plugin-transform-duplicate-keys" "^7.23.3" + "@babel/plugin-transform-dynamic-import" "^7.23.4" + "@babel/plugin-transform-exponentiation-operator" "^7.23.3" + "@babel/plugin-transform-export-namespace-from" "^7.23.4" + "@babel/plugin-transform-for-of" "^7.23.6" + "@babel/plugin-transform-function-name" "^7.23.3" + "@babel/plugin-transform-json-strings" "^7.23.4" + "@babel/plugin-transform-literals" "^7.23.3" + "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" + "@babel/plugin-transform-member-expression-literals" "^7.23.3" + "@babel/plugin-transform-modules-amd" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-modules-systemjs" "^7.23.3" + "@babel/plugin-transform-modules-umd" "^7.23.3" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.23.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" + "@babel/plugin-transform-numeric-separator" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.23.4" + "@babel/plugin-transform-object-super" "^7.23.3" + "@babel/plugin-transform-optional-catch-binding" "^7.23.4" + "@babel/plugin-transform-optional-chaining" "^7.23.4" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-private-methods" "^7.23.3" + "@babel/plugin-transform-private-property-in-object" "^7.23.4" + "@babel/plugin-transform-property-literals" "^7.23.3" + "@babel/plugin-transform-regenerator" "^7.23.3" + "@babel/plugin-transform-reserved-words" "^7.23.3" + "@babel/plugin-transform-shorthand-properties" "^7.23.3" + "@babel/plugin-transform-spread" "^7.23.3" + "@babel/plugin-transform-sticky-regex" "^7.23.3" + "@babel/plugin-transform-template-literals" "^7.23.3" + "@babel/plugin-transform-typeof-symbol" "^7.23.3" + "@babel/plugin-transform-unicode-escapes" "^7.23.3" + "@babel/plugin-transform-unicode-property-regex" "^7.23.3" + "@babel/plugin-transform-unicode-regex" "^7.23.3" + "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.7" + babel-plugin-polyfill-corejs3 "^0.8.7" + babel-plugin-polyfill-regenerator "^0.5.4" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + "@babel/preset-modules@^0.1.3": version "0.1.4" resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz" @@ -1000,7 +1706,19 @@ "@babel/helper-validator-option" "^7.12.17" "@babel/plugin-transform-typescript" "^7.12.17" -"@babel/runtime@^7.11.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.15.3": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.7.tgz#dd7c88deeb218a0f8bd34d5db1aa242e0f203193" + integrity sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": version "7.12.13" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.13.tgz" integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== @@ -1016,6 +1734,15 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + "@babel/traverse@^7.12.13": version "7.12.13" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz" @@ -1046,6 +1773,22 @@ globals "^11.1.0" lodash "^4.17.19" +"@babel/traverse@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" + integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.6" + "@babel/types" "^7.23.6" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.4.4": version "7.12.13" resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz" @@ -1064,11 +1807,52 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" + integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@csstools/convert-colors@^1.4.0": version "1.4.0" resolved "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz" integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@npmcli/move-file@^1.0.1": version "1.1.2" resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz" @@ -1103,46 +1887,46 @@ resolved "https://registry.npmjs.org/@rails/ujs/-/ujs-6.1.3-1.tgz" integrity sha512-mygePdimLMOQ2nr9YclG1UIyKgaNfb2dMhsjhTs18j6DvlKR9VRz1j/Mbd2E7VL7HX7hlMBD1cltDrQsTZPjEw== -"@rails/webpacker@5.2.1": - version "5.2.1" - resolved "https://registry.npmjs.org/@rails/webpacker/-/webpacker-5.2.1.tgz" - integrity sha512-rO0kOv0o4ESB8ZnKX+b54ZKogNJGWSMULGmsJacREfm9SahKEQwXBeHNsqSGtS9NAPsU6YUFhGKRd4i/kbMNrQ== +"@rails/webpacker@5.4.4": + version "5.4.4" + resolved "https://registry.yarnpkg.com/@rails/webpacker/-/webpacker-5.4.4.tgz#971a41b987c096c908ce4088accd57c1a9a7e2f7" + integrity sha512-hp9myb2MChYFPfE5Fd/3gF4q2m4wpxC+WWCkxcg6My3HYCptWuqMVXRwrBZ5EJHYiL/WRyMLvVNWwlFV47xhUw== dependencies: - "@babel/core" "^7.11.1" - "@babel/plugin-proposal-class-properties" "^7.10.4" - "@babel/plugin-proposal-object-rest-spread" "^7.10.1" + "@babel/core" "^7.15.0" + "@babel/plugin-proposal-class-properties" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.14.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-destructuring" "^7.10.1" - "@babel/plugin-transform-regenerator" "^7.10.1" - "@babel/plugin-transform-runtime" "^7.11.0" - "@babel/preset-env" "^7.11.0" - "@babel/runtime" "^7.11.2" - babel-loader "^8.1.0" + "@babel/plugin-transform-destructuring" "^7.14.7" + "@babel/plugin-transform-regenerator" "^7.14.5" + "@babel/plugin-transform-runtime" "^7.15.0" + "@babel/preset-env" "^7.15.0" + "@babel/runtime" "^7.15.3" + babel-loader "^8.2.2" babel-plugin-dynamic-import-node "^2.3.3" babel-plugin-macros "^2.8.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - compression-webpack-plugin "^4.0.0" - core-js "^3.6.5" - css-loader "^3.5.3" - file-loader "^6.0.0" - flatted "^3.0.4" - glob "^7.1.6" - js-yaml "^3.14.0" + case-sensitive-paths-webpack-plugin "^2.4.0" + compression-webpack-plugin "^4.0.1" + core-js "^3.16.2" + css-loader "^3.6.0" + file-loader "^6.2.0" + flatted "^3.2.2" + glob "^7.1.7" + js-yaml "^3.14.1" mini-css-extract-plugin "^0.9.0" - node-sass "^4.14.1" - optimize-css-assets-webpack-plugin "^5.0.3" + optimize-css-assets-webpack-plugin "^5.0.8" path-complete-extname "^1.0.0" - pnp-webpack-plugin "^1.6.4" + pnp-webpack-plugin "^1.7.0" postcss-flexbugs-fixes "^4.2.1" postcss-import "^12.0.1" postcss-loader "^3.0.0" postcss-preset-env "^6.7.0" postcss-safe-parser "^4.0.2" - regenerator-runtime "^0.13.7" - sass-loader "^8.0.2" - style-loader "^1.2.1" - terser-webpack-plugin "^4.0.0" - webpack "^4.44.1" + regenerator-runtime "^0.13.9" + sass "^1.38.0" + sass-loader "10.1.1" + style-loader "^1.3.0" + terser-webpack-plugin "^4.2.3" + webpack "^4.46.0" webpack-assets-manifest "^3.1.1" webpack-cli "^3.3.12" webpack-sources "^1.4.3" @@ -1171,10 +1955,12 @@ resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.14": - version "0.1.14" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.14.tgz#a0f6c1d0e2347e2da05f1f8be4d1cc0ddf2e8e71" - integrity sha512-BnGY7hvZg9XRaVpO1imeQ2+62f3dYkJ6mOG8UamZEbsqKOlsCis8PUGTy8yb6Pl2lyDq+El730N98hOpcIWgmw== +"@suttyweb/editor@^0.1.25": + version "0.1.25" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.25.tgz#37b38560642a49b24383473543c28be943695f9f" + integrity sha512-fxOO9LpdntWzgNZch4cZB6QL0u+jEw0NqsNahKcGBbiJaS0GNGLRrT2LUd/Djc6O8HWkQguPLcquVT5eHq2h9g== + dependencies: + prosemirror-svelte-nodeview "^1.0.2" "@types/caseless@*": version "0.12.2" @@ -1394,11 +2180,6 @@ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz" @@ -1430,7 +2211,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1445,11 +2226,6 @@ alphanum-sort@^1.0.0: resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - ansi-colors@^3.0.0: version "3.2.4" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz" @@ -1465,21 +2241,11 @@ ansi-regex@^2.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" @@ -1510,19 +2276,19 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.0.3, aproba@^1.1.1: +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.1.1: version "1.2.0" resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" @@ -1545,11 +2311,6 @@ arr-union@^3.1.0: resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" @@ -1587,18 +2348,6 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - assert@^1.1.1: version "1.5.0" resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" @@ -1617,11 +2366,6 @@ async-each@^1.0.1: resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-foreach@^0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz" - integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= - async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" @@ -1662,17 +2406,7 @@ autoprefixer@^9.6.1: postcss "^7.0.32" postcss-value-parser "^4.1.0" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -babel-loader@^8.1.0, babel-loader@^8.2.2: +babel-loader@^8.2.2: version "8.2.2" resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz" integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== @@ -1698,6 +2432,30 @@ babel-plugin-macros@^2.8.0: cosmiconfig "^6.0.0" resolve "^1.12.0" +babel-plugin-polyfill-corejs2@^0.4.7: + version "0.4.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz#679d1b94bf3360f7682e11f2cb2708828a24fe8c" + integrity sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.4" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.8.7: + version "0.8.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz#941855aa7fdaac06ed24c730a93450d2b2b76d04" + integrity sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.4" + core-js-compat "^3.33.1" + +babel-plugin-polyfill-regenerator@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz#c6fc8eab610d3a11eb475391e52584bacfc020f4" + integrity sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.4" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" @@ -1726,13 +2484,6 @@ batch@0.6.1: resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - big.js@^5.2.2: version "5.2.2" resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" @@ -1760,13 +2511,6 @@ bintrees@1.0.1: resolved "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz" integrity sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ= -block-stream@*: - version "0.0.9" - resolved "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz" - integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= - dependencies: - inherits "~2.0.0" - bluebird@^3.5.5: version "3.7.2" resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" @@ -1923,6 +2667,16 @@ browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4 escalade "^3.1.1" node-releases "^1.1.70" +browserslist@^4.22.2: + version "4.22.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz" @@ -2053,19 +2807,6 @@ callsites@^3.0.0: resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" @@ -2086,26 +2827,15 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, can resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz" integrity sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA== -case-sensitive-paths-webpack-plugin@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz" - integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== +caniuse-lite@^1.0.30001565: + version "1.0.30001576" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz#893be772cf8ee6056d6c1e2d07df365b9ec0a5c4" + integrity sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" +case-sensitive-paths-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" @@ -2143,6 +2873,21 @@ chartkick@^4.0.5: chartjs-adapter-date-fns ">=2.0.0" date-fns ">=2.0.0" +"chokidar@>=3.0.0 <4.0.0": + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz" @@ -2231,14 +2976,10 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" +clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== coa@^2.0.2: version "2.0.2" @@ -2249,11 +2990,6 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" @@ -2307,7 +3043,7 @@ colorette@^1.2.1: resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2346,9 +3082,9 @@ compressible@~2.0.16: dependencies: mime-db ">= 1.43.0 < 2" -compression-webpack-plugin@^4.0.0: +compression-webpack-plugin@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-4.0.1.tgz#33eda97f1170dd38c5556771de10f34245aa0274" integrity sha512-0mg6PgwTsUe5LEcUrOu3ob32vraDx2VdbMGAT1PARcOV+UJWDYZFdkSo6RbHoGQ061mmmkC7XpRKOlvwm/gzJQ== dependencies: cacache "^15.0.5" @@ -2395,11 +3131,6 @@ console-browserify@^1.1.0: resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz" @@ -2424,6 +3155,11 @@ convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" @@ -2451,6 +3187,13 @@ copy-descriptor@^0.1.0: resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +core-js-compat@^3.31.0, core-js-compat@^3.33.1: + version "3.35.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.35.0.tgz#c149a3d1ab51e743bc1da61e39cb51f461a41873" + integrity sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw== + dependencies: + browserslist "^4.22.2" + core-js-compat@^3.8.0: version "3.8.3" resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz" @@ -2459,12 +3202,12 @@ core-js-compat@^3.8.0: browserslist "^4.16.1" semver "7.0.0" -core-js@^3.6.5: - version "3.8.3" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz" - integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q== +core-js@^3.16.2: + version "3.35.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.35.0.tgz#58e651688484f83c34196ca13f099574ee53d6b4" + integrity sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -2533,14 +3276,6 @@ cross-fetch@^3.0.4: dependencies: node-fetch "2.6.1" -cross-spawn@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz" - integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" @@ -2597,9 +3332,9 @@ css-has-pseudo@^0.10.0: postcss "^7.0.6" postcss-selector-parser "^5.0.0-rc.4" -css-loader@^3.5.3: +css-loader@^3.6.0: version "3.6.0" - resolved "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== dependencies: camelcase "^5.3.1" @@ -2749,25 +3484,11 @@ csso@^4.0.2: dependencies: css-tree "^1.1.2" -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" - cyclist@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - date-fns@>=2.0.0: version "2.24.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.24.0.tgz" @@ -2794,7 +3515,14 @@ debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" -decamelize@^1.1.2, decamelize@^1.2.0: +debug@^4.3.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2876,11 +3604,6 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" @@ -2986,14 +3709,6 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -3004,6 +3719,11 @@ electron-to-chromium@^1.3.649: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.663.tgz" integrity sha512-xkVkzHj6k3oRRGlmdgUCCLSLhtFYHDCTH7SeK+LJdJjnsLcrdbpr8EYmfMQhez3V/KPO5UScSpzQ0feYX6Qoyw== +electron-to-chromium@^1.4.601: + version "1.4.623" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz#0f7400114ac3425500e9244d2b0e9c3107c331cb" + integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== + elliptic@^6.5.3: version "6.5.4" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" @@ -3065,7 +3785,7 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -3135,7 +3855,7 @@ escape-html@~1.0.3: resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -3289,11 +4009,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - extglob@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" @@ -3308,16 +4023,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -3340,9 +4045,9 @@ figgy-pudding@^3.5.1: resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== -file-loader@^6.0.0: +file-loader@^6.2.0: version "6.2.0" - resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: loader-utils "^2.0.0" @@ -3401,14 +4106,6 @@ find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" @@ -3434,10 +4131,10 @@ findup-sync@^3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" -flatted@^3.0.4: - version "3.1.1" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== +flatted@^3.2.2: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== flatten@^1.0.2: version "1.0.3" @@ -3462,11 +4159,6 @@ for-in@^1.0.2: resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - fork-awesome@^1.1.7: version "1.1.7" resolved "https://registry.npmjs.org/fork-awesome/-/fork-awesome-1.1.7.tgz" @@ -3499,15 +4191,6 @@ form-data@^2.5.0: combined-stream "^1.0.6" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - forwarded@~0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz" @@ -3583,43 +4266,22 @@ fsevents@~2.3.1: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fstream@^1.0.0, fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -gaze@^1.0.0: - version "1.1.3" - resolved "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz" - integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== - dependencies: - globule "^1.0.0" - -gensync@^1.0.0-beta.1: +gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -3638,11 +4300,6 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.1" -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= - get-stream@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" @@ -3655,13 +4312,6 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" @@ -3677,7 +4327,14 @@ glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.1.1: +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -3689,6 +4346,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, gl once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-modules@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz" @@ -3741,15 +4410,6 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globule@^1.0.0: - version "1.3.2" - resolved "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz" - integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== - dependencies: - glob "~7.1.1" - lodash "~4.17.10" - minimatch "~3.0.2" - graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.6" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" @@ -3760,26 +4420,6 @@ handle-thing@^2.0.0: resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" @@ -3795,11 +4435,6 @@ has-symbols@^1.0.1: resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" @@ -3855,6 +4490,13 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + hex-color-regex@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz" @@ -3876,11 +4518,6 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" @@ -3972,15 +4609,6 @@ http-proxy@^1.17.0: follow-redirects "^1.0.0" requires-port "^1.0.0" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz" @@ -4010,6 +4638,11 @@ iferr@^0.1.5: resolved "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= +immutable@^4.0.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz" @@ -4053,18 +4686,6 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -in-publish@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz" - integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" @@ -4088,7 +4709,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4221,6 +4842,13 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + is-core-module@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz" @@ -4287,18 +4915,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" @@ -4403,16 +5019,6 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" @@ -4445,11 +5051,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - jest-worker@^26.5.0: version "26.6.2" resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz" @@ -4459,17 +5060,12 @@ jest-worker@^26.5.0: merge-stream "^2.0.0" supports-color "^7.0.0" -js-base64@^2.1.8: - version "2.6.4" - resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz" - integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== - js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1, js-yaml@^3.14.0: +js-yaml@^3.13.1, js-yaml@^3.14.1: version "3.14.1" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -4477,11 +5073,6 @@ js-yaml@^3.13.1, js-yaml@^3.14.0: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" @@ -4507,16 +5098,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - json3@^3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz" @@ -4536,6 +5117,11 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" @@ -4545,16 +5131,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - killable@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz" @@ -4584,6 +5160,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klona@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + last-call-webpack-plugin@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz" @@ -4609,17 +5190,6 @@ linkify-it@^2.0.0: dependencies: uc.micro "^1.0.1" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz" @@ -4663,6 +5233,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.get@^4.0: version "4.4.2" resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" @@ -4698,37 +5273,21 @@ lodash.uniq@^4.5.0: resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.0.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.5, lodash@~4.17.10: - version "4.17.20" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - lodash@^4.17.11, lodash@^4.17.14: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lodash@^4.17.19, lodash@^4.17.5: + version "4.17.20" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + loglevel@^1.6.8: version "1.7.1" resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -4763,11 +5322,6 @@ map-cache@^0.2.2: resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - map-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" @@ -4838,22 +5392,6 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -meow@^3.7.0: - version "3.7.0" - resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" @@ -4906,7 +5444,7 @@ mime-db@1.46.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz" integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== -mime-types@^2.1.12, mime-types@~2.1.19: +mime-types@^2.1.12: version "2.1.28" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz" integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== @@ -4950,14 +5488,21 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.4, minimatch@~3.0.2: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist@>=1.2.2, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@>=1.2.2, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -5022,7 +5567,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -"mkdirp@>=0.5 0", mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: +mkdirp@^0.5, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -5084,11 +5629,6 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== -nan@^2.13.2: - version "2.14.2" - resolved "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz" - integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" @@ -5111,7 +5651,7 @@ negotiator@0.6.2: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.5.0, neo-async@^2.6.1: +neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -5131,24 +5671,6 @@ node-forge@^0.10.0: resolved "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-gyp@^3.8.0: - version "3.8.0" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz" - integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3 || 4" - osenv "0" - request "^2.87.0" - rimraf "2" - semver "~5.3.0" - tar "^2.0.0" - which "1" - node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz" @@ -5183,45 +5705,10 @@ node-releases@^1.1.70: resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz" integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== -node-sass@^4.14.1: - version "4.14.1" - resolved "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz" - integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== - dependencies: - async-foreach "^0.1.3" - chalk "^1.1.1" - cross-spawn "^3.0.0" - gaze "^1.0.0" - get-stdin "^4.0.1" - glob "^7.0.3" - in-publish "^2.0.0" - lodash "^4.17.15" - meow "^3.7.0" - mkdirp "^0.5.1" - nan "^2.13.2" - node-gyp "^3.8.0" - npmlog "^4.0.0" - request "^2.88.0" - sass-graph "2.2.5" - stdout-stream "^1.4.0" - "true-case-path" "^1.0.2" - -"nopt@2 || 3": - version "3.0.6" - resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.5.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== normalize-path@^2.1.1: version "2.1.1" @@ -5262,16 +5749,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - nth-check@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz" @@ -5284,16 +5761,6 @@ num2fraction@^1.2.2: resolved "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -5400,10 +5867,10 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -optimize-css-assets-webpack-plugin@^5.0.3: - version "5.0.4" - resolved "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz" - integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A== +optimize-css-assets-webpack-plugin@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz#cbccdcf5a6ef61d4f8cc78cf083a67446e5f402a" + integrity sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q== dependencies: cssnano "^4.1.10" last-call-webpack-plugin "^3.0.0" @@ -5413,6 +5880,11 @@ orderedmap@^1.1.0: resolved "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz" integrity sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ== +orderedmap@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2" + integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g== + original@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/original/-/original-1.0.2.tgz" @@ -5425,24 +5897,6 @@ os-browserify@^0.3.0: resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@0: - version "0.1.5" - resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" @@ -5532,13 +5986,6 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" @@ -5587,13 +6034,6 @@ path-dirname@^1.0.0: resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -5624,20 +6064,16 @@ path-parse@^1.0.6: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" @@ -5654,10 +6090,10 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" @@ -5700,10 +6136,10 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" -pnp-webpack-plugin@^1.6.4: - version "1.6.4" - resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz" - integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== +pnp-webpack-plugin@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9" + integrity sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg== dependencies: ts-pnp "^1.1.6" @@ -6484,6 +6920,13 @@ prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.2.0: dependencies: orderedmap "^1.1.0" +prosemirror-model@^1.16.0: + version "1.19.4" + resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.19.4.tgz#e45e84480c97dd3922095dbe579e1c98c86c0704" + integrity sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ== + dependencies: + orderedmap "^2.0.0" + prosemirror-schema-basic@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz" @@ -6507,6 +6950,23 @@ prosemirror-state@^1.0.0, prosemirror-state@^1.2.2: prosemirror-model "^1.0.0" prosemirror-transform "^1.0.0" +prosemirror-state@^1.3.4: + version "1.4.3" + resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080" + integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q== + dependencies: + prosemirror-model "^1.0.0" + prosemirror-transform "^1.0.0" + prosemirror-view "^1.27.0" + +prosemirror-svelte-nodeview@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/prosemirror-svelte-nodeview/-/prosemirror-svelte-nodeview-1.0.2.tgz#a5759cccd0390fd39f3a99b9a862fca47512ed75" + integrity sha512-JzNT8q0Sd1u9OFiTz7rt0rSURyTjxuT5Nhvp5F0t7PdQGLGtBBrzfaCDaFXppf2m/IyeDJJyV/IJw5yNiT2OTg== + dependencies: + clone "^2.1.2" + prosemirror-state "^1.3.4" + prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0: version "1.2.11" resolved "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.2.11.tgz" @@ -6523,6 +6983,15 @@ prosemirror-view@^1.0.0, prosemirror-view@^1.1.0: prosemirror-state "^1.0.0" prosemirror-transform "^1.1.0" +prosemirror-view@^1.27.0: + version "1.32.7" + resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.32.7.tgz#b9c4e8471daeba79489befa59eaeaeb4cd2e2653" + integrity sha512-pvxiOoD4shW41X5bYDjRQk3DSG4fMqxh36yPMt7VYgU3dWRmqFzWJM/R6zeo1KtC8nyk717ZbQND3CC9VNeptw== + dependencies: + prosemirror-model "^1.16.0" + prosemirror-state "^1.0.0" + prosemirror-transform "^1.1.0" + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz" @@ -6536,16 +7005,6 @@ prr@~1.0.1: resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" @@ -6593,7 +7052,7 @@ punycode@^1.2.4: resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0: version "2.1.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -6608,11 +7067,6 @@ qs@6.7.0: resolved "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - query-string@^4.1.0: version "4.3.4" resolved "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz" @@ -6673,24 +7127,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -6728,13 +7165,19 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" + picomatch "^2.2.1" + +regenerate-unicode-properties@^10.1.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== + dependencies: + regenerate "^1.4.2" regenerate-unicode-properties@^8.2.0: version "8.2.0" @@ -6743,16 +7186,26 @@ regenerate-unicode-properties@^8.2.0: dependencies: regenerate "^1.4.0" -regenerate@^1.4.0: +regenerate@^1.4.0, regenerate@^1.4.2: version "1.4.2" resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: +regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== +regenerator-runtime@^0.13.9: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regenerator-transform@^0.14.2: version "0.14.5" resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz" @@ -6760,6 +7213,13 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" @@ -6788,6 +7248,18 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + regjsgen@^0.5.1: version "0.5.2" resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz" @@ -6800,6 +7272,13 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" @@ -6815,39 +7294,6 @@ repeat-string@^1.6.1: resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -request@^2.87.0, request@^2.88.0: - version "2.88.2" - resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -6893,7 +7339,7 @@ resolve-url@^0.2.1: resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0: +resolve@^1.1.7, resolve@^1.12.0: version "1.20.0" resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -6901,6 +7347,15 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0: is-core-module "^2.2.0" path-parse "^1.0.6" +resolve@^1.14.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + ret@~0.1.10: version "0.1.15" resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" @@ -6921,7 +7376,7 @@ rgba-regex@^1.0.0: resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -6972,31 +7427,30 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-graph@2.2.5: - version "2.2.5" - resolved "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz" - integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== +sass-loader@10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" + integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw== dependencies: - glob "^7.0.0" - lodash "^4.0.0" - scss-tokenizer "^0.2.3" - yargs "^13.3.2" + klona "^2.0.4" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + semver "^7.3.2" -sass-loader@^8.0.2: - version "8.0.2" - resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz" - integrity sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ== +sass@^1.38.0: + version "1.69.7" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.7.tgz#6e7e1c8f51e8162faec3e9619babc7da780af3b7" + integrity sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ== dependencies: - clone-deep "^4.0.1" - loader-utils "^1.2.3" - neo-async "^2.6.1" - schema-utils "^2.6.1" - semver "^6.3.0" + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" sax@~1.2.4: version "1.2.4" @@ -7021,7 +7475,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.7.0: +schema-utils@^2.6.5, schema-utils@^2.7.0: version "2.7.1" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -7039,14 +7493,6 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -scss-tokenizer@^0.2.3: - version "0.2.3" - resolved "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz" - integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= - dependencies: - js-base64 "^2.1.8" - source-map "^0.4.2" - select-hose@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" @@ -7059,21 +7505,26 @@ selfsigned@^1.10.8: dependencies: node-forge "^0.10.0" -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + semver@^7.3.2: version "7.3.4" resolved "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz" @@ -7081,11 +7532,6 @@ semver@^7.3.2: dependencies: lru-cache "^6.0.0" -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" - integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= - send@0.17.1: version "0.17.1" resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz" @@ -7142,7 +7588,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -7180,13 +7626,6 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" @@ -7274,6 +7713,11 @@ source-list-map@^2.0.0: resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +"source-map-js@>=0.6.2 <2.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" @@ -7298,13 +7742,6 @@ source-map-url@^0.4.0: resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== -source-map@^0.4.2: - version "0.4.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz" - integrity sha1-66T12pwNyZneaAMti092FzZSA2s= - dependencies: - amdefine ">=0.0.4" - source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" @@ -7325,32 +7762,6 @@ spark-md5@^3.0.0: resolved "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz" integrity sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig== -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz" - integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== - spdy-transport@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" @@ -7386,21 +7797,6 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz" @@ -7438,13 +7834,6 @@ static-extend@^0.1.1: resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stdout-stream@^1.4.0: - version "1.4.1" - resolved "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz" - integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== - dependencies: - readable-stream "^2.0.1" - stimulus@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/stimulus/-/stimulus-1.1.1.tgz" @@ -7490,23 +7879,6 @@ strict-uri-encode@^1.0.0: resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" @@ -7551,20 +7923,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: +strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" @@ -7572,28 +7937,14 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - -style-loader@^1.2.1: +style-loader@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: loader-utils "^2.0.0" @@ -7608,11 +7959,6 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" @@ -7634,6 +7980,11 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + svgo@^1.0.0: version "1.3.2" resolved "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz" @@ -7658,15 +8009,6 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^2.0.0: - version "2.2.2" - resolved "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz" - integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - tar@^6.0.2: version "6.1.0" resolved "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz" @@ -7701,9 +8043,9 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^4.0.0: +terser-webpack-plugin@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== dependencies: cacache "^15.0.5" @@ -7806,26 +8148,6 @@ toidentifier@1.0.0: resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= - -"true-case-path@^1.0.2": - version "1.0.3" - resolved "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz" - integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== - dependencies: - glob "^7.1.2" - ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz" @@ -7841,23 +8163,11 @@ tty-browserify@0.0.0: resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - turbolinks@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/turbolinks/-/turbolinks-5.2.0.tgz" integrity sha512-pMiez3tyBo6uRHFNNZoYMmrES/IaGgMhQQM+VFF36keryjb5ms0XkVpmKHkfW/4Vy96qiGW3K9bz0tF5sK9bBw== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" @@ -7886,6 +8196,11 @@ unicode-canonical-property-names-ecmascript@^1.0.4: resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz" integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + unicode-match-property-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz" @@ -7894,16 +8209,34 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz" integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + unicode-property-aliases-ecmascript@^1.0.4: version "1.1.0" resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + union-value@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" @@ -7966,6 +8299,14 @@ upath@^1.1.1: resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" @@ -8043,14 +8384,6 @@ v8-compile-cache@^2.1.1: resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz" integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" @@ -8061,15 +8394,6 @@ vendors@^1.0.0: resolved "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz" @@ -8201,10 +8525,10 @@ webpack-sources@^1.0.0, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack- source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.44.1: - version "4.46.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz" - integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== +webpack@^4.46.0: + version "4.47.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.47.0.tgz#8b8a02152d7076aeb03b61b47dad2eeed9810ebc" + integrity sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ== dependencies: "@webassemblyjs/ast" "1.9.0" "@webassemblyjs/helper-module-context" "1.9.0" @@ -8249,20 +8573,13 @@ which-module@^2.0.0: resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1: +which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz" @@ -8301,11 +8618,6 @@ y18n@^4.0.0: resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz" integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - yallist@^3.0.2: version "3.1.1" resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" From 3469cd5bbd02f5e4cdd584a968b6d5c77e07af63 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:58:19 -0300 Subject: [PATCH 231/814] fix: solo copiar una vez --- Taskfile.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 26f3901d..0622138e 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -11,7 +11,7 @@ tasks: env: desc: "Install the .env file" cmds: - - "cp --no-clobber .env.example .env" + - "test -f .env || cp .env.example .env" - ": == Environment vars have changed, please review and edit ==" - "diff -auN --color .env.example .env" sources: From dbd35e658971622b391f331227e53c8ffb535c42 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 14:58:48 -0300 Subject: [PATCH 232/814] feat: instalar node modules --- .env.example | 1 + Taskfile.yaml | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/.env.example b/.env.example index c7322d1a..cf59f77e 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ +NODE_OPTIONS=--openssl-legacy-provider # pwgen -1 32 RAILS_MASTER_KEY=11111111111111111111111111111111 RAILS_GROUPS=assets diff --git a/Taskfile.yaml b/Taskfile.yaml index 0622138e..96299f12 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -30,3 +30,12 @@ tasks: desc: "Clean" cmds: - "rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage" + node-modules: + desc: "Install Node modules" + cmds: + - "haini.sh yarn" + sources: + - "package.json" + - "yarn.lock" + status: + - "test -d node_modules" From 6ae3c2a29d8f636c860fc067f2233b90c420f9cd Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:06:07 -0300 Subject: [PATCH 233/814] feat: copiar credentials --- Taskfile.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index 96299f12..1204b1a5 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,6 +8,14 @@ shopt: dotenv: - ".env" tasks: + credentials: + desc: "Generate credentials file" + cmds: + - "cp --no-clobber config/credentials.yml.enc.ci config/credentials.yml.enc" + sources: + - "config/credentials.yml.enc.ci" + generates: + - "config/credentials.yml.enc" env: desc: "Install the .env file" cmds: @@ -20,6 +28,9 @@ tasks: - ".env" gems: desc: "Install gems" + deps: + - "env" + - "credentials" cmds: - "haini.sh bundle" sources: From a03c549c3f1d4c32dcc84fe7aa0738f7b005cf3d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:07:59 -0300 Subject: [PATCH 234/814] feat: generar assets --- .gitlab-ci.yml | 18 ++---------------- Makefile | 8 -------- Taskfile.yaml | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f8994356..2c576305 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,27 +7,13 @@ cache: - "vendor/ruby" assets: stage: "build" - rules: - - if: "$CI_COMMIT_BRANCH == \"panel.sutty.nl\"" - - if: "$CI_COMMIT_BRANCH" - changes: - compare_to: "refs/heads/rails" - paths: - - "package.json" - - "app/javascript/**/*" - - "app/assets/**/*" before_script: - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" - - "apk add python2 dotenv brotli" - - "mv config/credentials.yml.enc.ci config/credentials.yml.enc" - - "cp .env.example .env" - - "dotenv bundle install --path=vendor" + - "apk add dotenv brotli go-task" script: - - "dotenv RAILS_ENV=production bundle exec rails webpacker:clobber" - - "dotenv RAILS_ENV=production bundle exec rails assets:precompile" - - "dotenv RAILS_ENV=production bundle exec rails assets:clean" + - "go-task assets" after_script: - "git add public && git commit -m \"ci: assets [skip ci]\"" - "git push -o ci.skip" diff --git a/Makefile b/Makefile index 541d072b..9a70a1af 100644 --- a/Makefile +++ b/Makefile @@ -117,12 +117,4 @@ $(tests): always @grep -q " panel.$(SUTTY)$$" $@ || echo -e "127.0.0.1 panel.$(SUTTY)\n::1 panel.$(SUTTY)" | sudo tee -a $@ @grep -q " postgresql.$(SUTTY)$$" $@ || echo -e "127.0.0.1 postgresql.$(SUTTY)\n::1 postgresql.$(SUTTY)" | sudo tee -a $@ -# Instala las dependencias de Javascript -node_modules: package.json - $(MAKE) yarn - -# Instala las dependencias de Rails -Gemfile.lock: Gemfile - $(MAKE) bundle args=install - .PHONY: always diff --git a/Taskfile.yaml b/Taskfile.yaml index 1204b1a5..4f524707 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -50,3 +50,21 @@ tasks: - "yarn.lock" status: - "test -d node_modules" + assets: + desc: "Generate assets" + deps: + - "node-modules" + - "gems" + cmds: + - "git lfs fetch" + - "git lfs checkout" + - "haini.sh RAILS_ENV=production bundle exec rails webpacker:clobber" + - "haini.sh RAILS_ENV=production bundle exec rails assets:precompile" + - "haini.sh RAILS_ENV=production bundle exec rails assets:clean" + sources: + - "package.json" + - "yarn.lock" + - "app/assets/**/*" + - "app/javascript/**/*" + generates: + - "public/packs/manifest.json" From 167c1289275847f02d391f6e4fbd215545d1f8e3 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:10:55 -0300 Subject: [PATCH 235/814] BREAKING CHANGE: deprecar alpine 3.14 --- .woodpecker.yml | 50 ------------------------------------------------- Dockerfile | 6 +++--- 2 files changed, 3 insertions(+), 53 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index b5806bf3..aff0af52 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -19,7 +19,6 @@ pipeline: when: branch: - "rails" - - "panel.sutty.nl" - "17.3.alpine.panel.sutty.nl" event: "push" path: @@ -27,57 +26,8 @@ pipeline: - "Dockerfile" - ".dockerignore" - ".woodpecker.yml" - assets: - image: "gitea.nulo.in/sutty/panel:3.14.10-2.7.8" - commands: - - "apk add python2 dotenv openssh-client brotli" - - "install -d -m 700 ~/.ssh/" - - "echo \"$${KNOWN_HOSTS}\" | base64 -d >> ~/.ssh/known_hosts" - - "chmod 600 ~/.ssh/known_hosts" - - "eval $(ssh-agent -s)" - - "echo \"$${SSH_KEY}\" | base64 -d | ssh-add -" - - "ssh $${ORIGIN%:*}" - - "git config user.name Woodpecker" - - "git config user.email ci@sutty.coop.ar" - - "git remote add upstream $${ORIGIN}" - - "git checkout -B ${CI_COMMIT_BRANCH}" - - "mv config/credentials.yml.enc.ci config/credentials.yml.enc" - - "yarn" - - "cp .env.example .env" - - "dotenv bundle install --path=vendor" - - "dotenv RAILS_ENV=production bundle exec rails webpacker:clobber" - - "dotenv RAILS_ENV=production bundle exec rails assets:precompile" - - "dotenv RAILS_ENV=production bundle exec rails assets:clean" - - "find public -type f -print0 | xargs -r0 brotli -k9f" - - "git add public && git commit -m \"ci: assets [skip ci]\"" - - "git pull upstream ${CI_COMMIT_BRANCH}" - - "git push upstream ${CI_COMMIT_BRANCH}" - environment: - - "RUBY_VERSION=${RUBY_VERSION}" - - "GEMS_SOURCE=https://14.3.alpine.gems.sutty.nl" - secrets: - - "SSH_KEY" - - "KNOWN_HOSTS" - - "ORIGIN" - when: - branch: - - "rails" - - "panel.sutty.nl" - path: - include: - - "app/assets/**/*" - - "app/javascript/**/*" - - "package.json" - - "yarn.lock" - matrix: - ALPINE_VERSION: "3.14.10" - RUBY_VERSION: "2.7" - RUBY_PATCH: "8" matrix: include: - ALPINE_VERSION: "3.17.3" RUBY_VERSION: "3.1" RUBY_PATCH: "4" - - ALPINE_VERSION: "3.14.10" - RUBY_VERSION: "2.7" - RUBY_PATCH: "8" diff --git a/Dockerfile b/Dockerfile index e0f1dc9f..394a81e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -ARG RUBY_VERSION=2.7 -ARG RUBY_PATCH=6 -ARG ALPINE_VERSION=3.13.10 +ARG RUBY_VERSION=3.1 +ARG RUBY_PATCH=4 +ARG ALPINE_VERSION=3.17.3 ARG BASE_IMAGE=registry.nulo.in/sutty/rails FROM ${BASE_IMAGE}:${ALPINE_VERSION}-${RUBY_VERSION}.${RUBY_PATCH} ARG PANDOC_VERSION=2.18 From 1956d8c88606dd154a6e5ff8b9b48d6753d31245 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:11:37 -0300 Subject: [PATCH 236/814] =?UTF-8?q?fix:=20compilar=20assets=20a=20partir?= =?UTF-8?q?=20de=20contenedor=20de=20producci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c576305..6e834e6e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: "gitea.nulo.in/sutty/panel:3.14.10-2.7.8-panel.sutty.nl" +image: "gitea.nulo.in/sutty/panel:3.17.3-3.1.4-rails" variables: RAILS_ENV: "production" LC_ALL: "C.UTF-8" From 2296c82f0bcdfcaeee71dd039ab61c4546bc16bd Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:12:29 -0300 Subject: [PATCH 237/814] fix: cachear node modules y tasks --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e834e6e..3c71b8af 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,8 @@ variables: cache: paths: - "vendor/ruby" + - "node_modules" + - ".task" assets: stage: "build" before_script: From 8ce1aceb3f9a79b6e65bfd46b67f958e958f9806 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:26:19 -0300 Subject: [PATCH 238/814] fix: no es necesario usar hainish en un contenedor --- .gitlab-ci.yml | 1 + Taskfile.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c71b8af..a42d473b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,7 @@ image: "gitea.nulo.in/sutty/panel:3.17.3-3.1.4-rails" variables: RAILS_ENV: "production" LC_ALL: "C.UTF-8" + HAINISH: "" cache: paths: - "vendor/ruby" diff --git a/Taskfile.yaml b/Taskfile.yaml index 4f524707..3bbe6c15 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -32,7 +32,7 @@ tasks: - "env" - "credentials" cmds: - - "haini.sh bundle" + - "{{.HAINISH}} bundle" sources: - "Gemfile" generates: @@ -44,7 +44,7 @@ tasks: node-modules: desc: "Install Node modules" cmds: - - "haini.sh yarn" + - "{{.HAINISH}} yarn" sources: - "package.json" - "yarn.lock" @@ -58,9 +58,9 @@ tasks: cmds: - "git lfs fetch" - "git lfs checkout" - - "haini.sh RAILS_ENV=production bundle exec rails webpacker:clobber" - - "haini.sh RAILS_ENV=production bundle exec rails assets:precompile" - - "haini.sh RAILS_ENV=production bundle exec rails assets:clean" + - "{{.HAINISH}} RAILS_ENV=production bundle exec rails webpacker:clobber" + - "{{.HAINISH}} RAILS_ENV=production bundle exec rails assets:precompile" + - "{{.HAINISH}} RAILS_ENV=production bundle exec rails assets:clean" sources: - "package.json" - "yarn.lock" From ee7d1599e896f82accac69288edc6ff450a53c83 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 9 Jan 2024 18:27:02 -0300 Subject: [PATCH 239/814] fix: limitar el nombre del archivo #14946 --- app/models/metadata_path.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/models/metadata_path.rb b/app/models/metadata_path.rb index 95fc7dbb..17085e07 100644 --- a/app/models/metadata_path.rb +++ b/app/models/metadata_path.rb @@ -6,7 +6,7 @@ class MetadataPath < MetadataTemplate # # @return [String] def default_value - File.join(site.path, "_#{lang}", "#{date}-#{slug}#{ext}") + File.join(site.path, "_#{lang}", "#{limited_name}#{ext}") end # La ruta del archivo según Jekyll @@ -46,4 +46,12 @@ class MetadataPath < MetadataTemplate def date post.date.value.strftime('%F') end + + # Limita el nombre de archivo a 255 bytes, de forma que siempre + # podemos guardarlo + # + # @return [String] + def limited_name + "#{date}-#{slug}".mb_chars.limit(255 - ext.length) + end end From c2534578400e416d5560ed1344e58a87d1cc6092 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 11:39:07 -0300 Subject: [PATCH 240/814] fix: env para desarrollo --- .env.development | 1 + 1 file changed, 1 insertion(+) create mode 100644 .env.development diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..df2788b0 --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +HAINISH=../haini.sh/haini.sh From 3d86ad1fbefe69fcd25aefd86b4103632d3cc709 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 10 Jan 2024 15:36:02 -0300 Subject: [PATCH 241/814] fix: quitado espacio sobrante en array #14550 --- app/models/deploy_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index bfa43441..c74a342f 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -87,7 +87,7 @@ class DeployDistributedPress < Deploy # @return [Array] def gateway_urls remote_info.dig(:distributed_press, :links)&.values&.map do |protocol| - [ protocol[:link]] + [protocol[:link]] end&.flatten&.compact&.select do |link| link.include? '://' end || [] From 61703dea2395629e433c929bd1d86a734706dac3 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:28:28 -0300 Subject: [PATCH 242/814] fix: dependencias --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a42d473b..1726eb19 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,7 @@ assets: - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" - - "apk add dotenv brotli go-task" + - "apk add brotli go-task diffutils" script: - "go-task assets" after_script: From 29e6e28479e17c8d80d2380a12121bfbb39d890c Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:34:25 -0300 Subject: [PATCH 243/814] ci: assets [skip ci] --- .../.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json | 2 +- public/packs/css/application-1224e21e.css | 3 +++ public/packs/css/application-1224e21e.css.br | 3 +++ public/packs/css/application-1224e21e.css.gz | 3 +++ public/packs/css/application-7d15ae94.css | 3 --- public/packs/css/application-7d15ae94.css.br | 3 --- public/packs/css/application-7d15ae94.css.br.br | 3 --- public/packs/css/application-7d15ae94.css.gz | 3 --- public/packs/js/application-d4a959210a82d3d1b10f.js | 3 +++ .../packs/js/application-d4a959210a82d3d1b10f.js.LICENSE.txt | 3 +++ public/packs/js/application-d4a959210a82d3d1b10f.js.br | 3 +++ public/packs/js/application-d4a959210a82d3d1b10f.js.gz | 3 +++ public/packs/js/application-d4a959210a82d3d1b10f.js.map | 3 +++ public/packs/js/application-d4a959210a82d3d1b10f.js.map.br | 3 +++ public/packs/js/application-d4a959210a82d3d1b10f.js.map.gz | 3 +++ public/packs/js/application-fd20cd4c95f90c1a3ecd.js | 3 --- .../packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt | 3 --- .../js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br | 3 --- public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz | 3 --- public/packs/manifest.json | 2 +- public/packs/manifest.json.br | 4 ++-- public/packs/manifest.json.br.br | 3 --- public/packs/manifest.json.gz | 2 +- public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br | 3 --- .../packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br | 3 --- public/packs/media/fonts/forkawesome-webfont-86541105.svg.br | 4 ++-- .../packs/media/fonts/forkawesome-webfont-86541105.svg.br.br | 3 --- public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br | 4 ++-- .../packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br | 3 --- public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br | 4 ++-- .../packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br | 3 --- public/packs/media/images/layers-2x-8f2c4d11.png.br | 3 --- public/packs/media/images/layers-416d9136.png.br | 3 --- public/packs/media/images/marker-icon-2b3e1faf.png.br | 3 --- public/packs/media/images/marker-icon-2x-680f69f3.png.br | 3 --- public/packs/media/images/marker-shadow-a0c6cc14.png.br | 3 --- 42 files changed, 41 insertions(+), 86 deletions(-) create mode 100644 public/packs/css/application-1224e21e.css create mode 100644 public/packs/css/application-1224e21e.css.br create mode 100644 public/packs/css/application-1224e21e.css.gz delete mode 100644 public/packs/css/application-7d15ae94.css delete mode 100644 public/packs/css/application-7d15ae94.css.br delete mode 100644 public/packs/css/application-7d15ae94.css.br.br delete mode 100644 public/packs/css/application-7d15ae94.css.gz create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js.LICENSE.txt create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js.br create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js.gz create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js.map create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js.map.br create mode 100644 public/packs/js/application-d4a959210a82d3d1b10f.js.map.gz delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br delete mode 100644 public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz delete mode 100644 public/packs/manifest.json.br.br delete mode 100644 public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br delete mode 100644 public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br delete mode 100644 public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br delete mode 100644 public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br delete mode 100644 public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br delete mode 100644 public/packs/media/images/layers-2x-8f2c4d11.png.br delete mode 100644 public/packs/media/images/layers-416d9136.png.br delete mode 100644 public/packs/media/images/marker-icon-2b3e1faf.png.br delete mode 100644 public/packs/media/images/marker-icon-2x-680f69f3.png.br delete mode 100644 public/packs/media/images/marker-shadow-a0c6cc14.png.br diff --git a/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json index efff86d9..ecd1aee3 100644 --- a/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json +++ b/public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70db348a921487a61c0bf1006f8ecfc38e44905b4b9d8e3527a5783a6275734e +oid sha256:53b13d54381374696503351fd6661242b1e22ea6f2078678bc560dfcfb701c8a size 10242 diff --git a/public/packs/css/application-1224e21e.css b/public/packs/css/application-1224e21e.css new file mode 100644 index 00000000..390ac1f2 --- /dev/null +++ b/public/packs/css/application-1224e21e.css @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7ffc74f9219623a13902d9ac806b9e71cfdabc2428e1f6ae4015da56cb7c7d9 +size 49314 diff --git a/public/packs/css/application-1224e21e.css.br b/public/packs/css/application-1224e21e.css.br new file mode 100644 index 00000000..1f5776e2 --- /dev/null +++ b/public/packs/css/application-1224e21e.css.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68809099d5fd771490c8eee922fe59c2be223a7b3ea6bec6889bc26380dcc788 +size 10017 diff --git a/public/packs/css/application-1224e21e.css.gz b/public/packs/css/application-1224e21e.css.gz new file mode 100644 index 00000000..3784a199 --- /dev/null +++ b/public/packs/css/application-1224e21e.css.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8058f9e1c5cfdf8de6d896fe9dd138b527e2409e1c467f79b376f75fa0c24b76 +size 12355 diff --git a/public/packs/css/application-7d15ae94.css b/public/packs/css/application-7d15ae94.css deleted file mode 100644 index 544ddf74..00000000 --- a/public/packs/css/application-7d15ae94.css +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e0179eec59d4881001e3d26ec0e25d8ca1257c6e4956d76f18cc97c3325a9625 -size 48029 diff --git a/public/packs/css/application-7d15ae94.css.br b/public/packs/css/application-7d15ae94.css.br deleted file mode 100644 index c0e44938..00000000 --- a/public/packs/css/application-7d15ae94.css.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f9a030d083e92a55a9a9211539c894371f200778de283958a318c87a825cb4f -size 10934 diff --git a/public/packs/css/application-7d15ae94.css.br.br b/public/packs/css/application-7d15ae94.css.br.br deleted file mode 100644 index bd3a0882..00000000 --- a/public/packs/css/application-7d15ae94.css.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7c61a1f5c9ca9cfc7b2b314046b258a94f707535a34e0c3e7b621d9b7c2cd648 -size 10939 diff --git a/public/packs/css/application-7d15ae94.css.gz b/public/packs/css/application-7d15ae94.css.gz deleted file mode 100644 index 306dc931..00000000 --- a/public/packs/css/application-7d15ae94.css.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfeb6b9af353618bdc475d6c921197da2b8a9ae7685a91772658d41883843c12 -size 12022 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js b/public/packs/js/application-d4a959210a82d3d1b10f.js new file mode 100644 index 00000000..ae056684 --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d178fb353afcf2dedc8bba8ce4b978f0bc93f679479a7f67c0473e25324a72c +size 1516360 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js.LICENSE.txt b/public/packs/js/application-d4a959210a82d3d1b10f.js.LICENSE.txt new file mode 100644 index 00000000..979d1ab9 --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js.LICENSE.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3b9ae1697c4b8a404afe77afe035de28b7f4880e9f52caac82620bb8d8ed495 +size 854 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js.br b/public/packs/js/application-d4a959210a82d3d1b10f.js.br new file mode 100644 index 00000000..b7a543a0 --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f37b681c0c2989dba2d59695f7d3d38c9357edab713b2b5899bf2c20dbed1f11 +size 333228 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js.gz b/public/packs/js/application-d4a959210a82d3d1b10f.js.gz new file mode 100644 index 00000000..f800b3fd --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a34e726274558a688517e19a1761f028072b7a6f614b4d1ec6f8609e61443bb4 +size 441095 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js.map b/public/packs/js/application-d4a959210a82d3d1b10f.js.map new file mode 100644 index 00000000..76a8fd29 --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js.map @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5c9c622b3d7a39cf332a95f1877dc8d5cbec844fa99cb55c75e45dfed5531dd +size 5988200 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js.map.br b/public/packs/js/application-d4a959210a82d3d1b10f.js.map.br new file mode 100644 index 00000000..a9d2dce3 --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js.map.br @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5242fa25b04407204920fb98a250ea9af7de4d3575ea1dcb79801f2c002fb8f +size 1279231 diff --git a/public/packs/js/application-d4a959210a82d3d1b10f.js.map.gz b/public/packs/js/application-d4a959210a82d3d1b10f.js.map.gz new file mode 100644 index 00000000..ffbbaff0 --- /dev/null +++ b/public/packs/js/application-d4a959210a82d3d1b10f.js.map.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d70208139d5de996bc6a01daacf3fc7e07edf975296795cae487e71e2c198e07 +size 1583975 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js deleted file mode 100644 index b6dc46a3..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0322257341b6d5bcbee0153eb5007363aefe26870b63744de6f1cdf6d1a7065e -size 1134731 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt deleted file mode 100644 index 89f0cf4f..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a016dd85be9a400040f4440d2ce1a94524f6e885a3d0e1f2422b46c2397df38f -size 629 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br deleted file mode 100644 index 3b0be40c..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:46eca40f00a3261e41a1e02d89697deb163a49a56237e72ae2643cb1c28b99c0 -size 307 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br deleted file mode 100644 index 6ba2a97b..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b88ebe0dd46c4b22fea0ecccb721afc5b4a88ce4b55950bce19654c2d265f72e -size 302355 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br deleted file mode 100644 index 93ce3091..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8ed407a10485f5157d5eb98bc11a158c2565bc417faedaa197bdfcea486ccdcd -size 302363 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz deleted file mode 100644 index a978f9f3..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ed777e669bf1e81dd7f43ff8d9c2d5d5b4c9d81c68a1fac7b7fdd3d7d578b30 -size 329294 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map deleted file mode 100644 index ab3aa8ef..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02a1682a2421fd6f340241bbc6b07951aa583f2ef2b74f29fb16cf9aaf3956a0 -size 4658473 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br deleted file mode 100644 index ca0133f3..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f3ef78d7fb35e3c0547740d68249462805e7cf65eafd3b6f77b787e7746c1f14 -size 1099488 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br deleted file mode 100644 index dd2dcd4a..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cda688a8dbd865c4720c68f2af7c8e1130cd43a955c737da9f4f38296b2d6d56 -size 1099496 diff --git a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz b/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz deleted file mode 100644 index 38ab8f51..00000000 --- a/public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f18506f9e0cec6f8a84d2a640646b6bae20eeeea081aba5ba26324028ffae8c2 -size 1222748 diff --git a/public/packs/manifest.json b/public/packs/manifest.json index f3fcbef3..d0f77c7e 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:880db5bc10cd865a8cb1a2fc56d69bba8464ef28aa59c31913256c7062528289 +oid sha256:0e5e2ddeee2bb351e8f9e0b16d28fcebd7314227abdffa65e02e83755db591d6 size 1426 diff --git a/public/packs/manifest.json.br b/public/packs/manifest.json.br index 82077c62..76978873 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:8cfa3712c659f01703314a2a9dd306a55d0f52a3456e20d43e080a5d716c8e45 -size 325 +oid sha256:a7c9ab4526ce1ce929b4d0c242dee97cacc9f79fac73948c42a4167494e251e1 +size 321 diff --git a/public/packs/manifest.json.br.br b/public/packs/manifest.json.br.br deleted file mode 100644 index b8d746ce..00000000 --- a/public/packs/manifest.json.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:82c427cf2556c027323f463d5d735bc8dd3b2b22ac1d5eed3e7d77b3f1cc9178 -size 330 diff --git a/public/packs/manifest.json.gz b/public/packs/manifest.json.gz index dd2dc7c2..c691abe7 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:9aee952354edb8ae47a200f1059beaf3ab588f0fef6e60dcd983de8808ed3351 +oid sha256:caf56db4d1167dd81eadb2da3a1fb6d14bf9f668381d4aa8295f333bcd649f00 size 365 diff --git a/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br b/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br deleted file mode 100644 index df2c95b5..00000000 --- a/public/packs/media/fonts/forkawesome-webfont-2dfb5f36.woff.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90b60c42bcbd106f5658710acd84f60307a00f0de10b921eeb5627590b429858 -size 115153 diff --git a/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br b/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br deleted file mode 100644 index 1d640da9..00000000 --- a/public/packs/media/fonts/forkawesome-webfont-7c20758e.woff2.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a76b02ceece82f286d306ed0988f8c220066ecce509241a425245950e4e4c839 -size 91629 diff --git a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br index bad26711..827ed0bc 100644 --- a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br +++ b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f7aee80d4013bd5a42f4035b0dc08a2fc903dae87f04182d9a86db53b95c9add -size 143247 +oid sha256:4df44c3056ab68d2e1cf1970189876295b62db1640e6ed885c78d8c46f94e66f +size 126249 diff --git a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br b/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br deleted file mode 100644 index 344bb103..00000000 --- a/public/packs/media/fonts/forkawesome-webfont-86541105.svg.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e03d221ca2c49b7099c550f8f33462365d285809e5a0b1e000c6c52e6982996a -size 143252 diff --git a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br index 22d6e19f..01f63da2 100644 --- a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br +++ b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4283befabbc5c3bfec093dd89b65ad0063a3581e45bbfbaf9b40a4d178cd5e1 -size 110762 +oid sha256:36cb46345792080af5dbe8bd742dc632a3821276fff76e57877c93c0e8afb00a +size 107072 diff --git a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br b/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br deleted file mode 100644 index e6ebb6ac..00000000 --- a/public/packs/media/fonts/forkawesome-webfont-e182ad6d.eot.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d2adacd487b97dcd4da3bc37328482c809a0d910353990de13b228dd1aa4710a -size 110767 diff --git a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br index 87ab54e0..c35abc27 100644 --- a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br +++ b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e01bc03dc20b0d760488b20f4f5a408dddd0554fb8c23d7ace34ab1698c4c807 -size 110703 +oid sha256:de3e4f20e5341214cc1292a61d0f49d833187e862fb1fbfeb746d25f0465ee6b +size 106884 diff --git a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br b/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br deleted file mode 100644 index e633502b..00000000 --- a/public/packs/media/fonts/forkawesome-webfont-ee4d8bfd.ttf.br.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba3d7e97443577de6e23b5936de2e1a6f35d9e6335b069d8071e6269afc78246 -size 110708 diff --git a/public/packs/media/images/layers-2x-8f2c4d11.png.br b/public/packs/media/images/layers-2x-8f2c4d11.png.br deleted file mode 100644 index cda7f53d..00000000 --- a/public/packs/media/images/layers-2x-8f2c4d11.png.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:47119b2b0eb7d15fa47527efc1fa04713d80990ed6a7f2e2f58f91a8cddd1b03 -size 1264 diff --git a/public/packs/media/images/layers-416d9136.png.br b/public/packs/media/images/layers-416d9136.png.br deleted file mode 100644 index 21812b3e..00000000 --- a/public/packs/media/images/layers-416d9136.png.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e255d97d12f227f9d2fabd481fa56d89bf33b47a4d108b031e7b96ddc0fb0066 -size 701 diff --git a/public/packs/media/images/marker-icon-2b3e1faf.png.br b/public/packs/media/images/marker-icon-2b3e1faf.png.br deleted file mode 100644 index 62bba2a0..00000000 --- a/public/packs/media/images/marker-icon-2b3e1faf.png.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4d73a1e81d4d7b880342c1fa48caeb6cdb56cc941ad18000d932dfaec8ba1086 -size 1471 diff --git a/public/packs/media/images/marker-icon-2x-680f69f3.png.br b/public/packs/media/images/marker-icon-2x-680f69f3.png.br deleted file mode 100644 index 585d2e48..00000000 --- a/public/packs/media/images/marker-icon-2x-680f69f3.png.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4f6ce09c4c3a59cfac5c03a03de02b170d35cfefd7e1247a317dc772c889395 -size 2469 diff --git a/public/packs/media/images/marker-shadow-a0c6cc14.png.br b/public/packs/media/images/marker-shadow-a0c6cc14.png.br deleted file mode 100644 index 940c4d9b..00000000 --- a/public/packs/media/images/marker-shadow-a0c6cc14.png.br +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8758eb0644225f0a3c8e03fb1dbe319f6427b4116a538084f18ba5a6dcd65eb2 -size 623 From 064da6cf13d3fa33eee67397cddc7dfaaa542d2d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:34:44 -0300 Subject: [PATCH 244/814] fix: ignorar task --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e6f2adbb..18d02ded 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ yarn-debug.log* /yarn-error.log yarn-debug.log* .yarn-integrity + +/.task From 416607df9cd960065e86bad6605c3e5aa1db5c4a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:39:32 -0300 Subject: [PATCH 245/814] feat: agregar hosts --- Makefile | 14 +++----------- Taskfile.yaml | 8 ++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 9a70a1af..90907142 100644 --- a/Makefile +++ b/Makefile @@ -42,13 +42,13 @@ help: always ## Ayuda test: always ## Ejecutar los tests $(MAKE) rake args="test RAILS_ENV=test $(args)" -postgresql: /etc/hosts ## Iniciar la base de datos +postgresql: ## Iniciar la base de datos pgrep postgres >/dev/null || $(hain) postgresql -serve-js: /etc/hosts node_modules ## Iniciar el servidor de desarrollo de Javascript +serve-js: node_modules ## Iniciar el servidor de desarrollo de Javascript $(hain) 'bundle exec ./bin/webpack-dev-server' -serve: /etc/hosts postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails +serve: postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails $(MAKE) rails args=server rails: ## Corre rails dentro del entorno de desarrollo (pasar argumentos con args=). @@ -109,12 +109,4 @@ tests := $(shell find test/ -name "*_test.rb") $(tests): always $(MAKE) test args="TEST=$@" -# Agrega las direcciones locales al sistema -/etc/hosts: always - @echo "Chequeando si es necesario agregar el dominio local $(SUTTY)" - @grep -q " $(SUTTY)$$" $@ || echo -e "127.0.0.1 $(SUTTY)\n::1 $(SUTTY)" | sudo tee -a $@ - @grep -q " api.$(SUTTY)$$" $@ || echo -e "127.0.0.1 api.$(SUTTY)\n::1 api.$(SUTTY)" | sudo tee -a $@ - @grep -q " panel.$(SUTTY)$$" $@ || echo -e "127.0.0.1 panel.$(SUTTY)\n::1 panel.$(SUTTY)" | sudo tee -a $@ - @grep -q " postgresql.$(SUTTY)$$" $@ || echo -e "127.0.0.1 postgresql.$(SUTTY)\n::1 postgresql.$(SUTTY)" | sudo tee -a $@ - .PHONY: always diff --git a/Taskfile.yaml b/Taskfile.yaml index 3bbe6c15..ca2a1ad1 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -68,3 +68,11 @@ tasks: - "app/javascript/**/*" generates: - "public/packs/manifest.json" + hosts: + desc: "Local DNS resolution for hostnames" + interactive: true + cmds: + - "echo -e \"127.0.0.1 panel.{{.SUTTY}} api.{{.SUTTY}} postgresql.{{.SUTTY}}\" | sudo tee -a /etc/hosts" + - "echo -e \"::1 panel.{{.SUTTY}} api.{{.SUTTY}} postgresql.{{.SUTTY}}\" | sudo tee -a /etc/hosts" + status: + - "grep -q \" panel.{{.SUTTY}} \" /etc/hosts" From 49e97ca7b007a4922c67bc27ebcc2f7779f95023 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 15:42:57 -0300 Subject: [PATCH 246/814] BREAKING CHANGE: deprecar tareas de makefile --- Makefile | 56 +------------------------------------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/Makefile b/Makefile index 90907142..d6ee991d 100644 --- a/Makefile +++ b/Makefile @@ -1,51 +1,17 @@ SHELL := /bin/bash -.DEFAULT_GOAL := help - -export # XXX: El espacio antes del comentario cuenta como espacio args ?=## Argumentos para Hain -commit ?= origin/rails## Commit desde el que actualizar -env ?= staging## Entorno del nodo delegado -sutty ?= $(SUTTY)## Dirección local delegate ?= $(DELEGATE)## Cambia el nodo delegado hain ?= ENV_FILE=.env $(HAINISH)## Ubicación de Hainish -# El nodo delegado tiene dos entornos, production y staging. -# Dependiendo del entorno que elijamos, se van a generar los assets y el -# contenedor y subirse a un servidor u otro. No utilizamos CI/CD (aún). -# -# Production es el entorno de panel.sutty.nl -ifeq ($(env),production) -container ?= panel -## TODO: Cambiar a otra cosa -branch ?= rails -public ?= public -endif - -# Staging es el entorno de panel.staging.sutty.nl -ifeq ($(env),staging) -container := staging -branch := staging -public := staging -endif - -help: always ## Ayuda - @echo -e "Sutty\n" | sed -re "s/^.*/\x1B[38;5;197m&\x1B[0m/" - @echo -e "Servidor: https://panel.$(SUTTY_WITH_PORT)/\n" - @echo -e "Uso: make TAREA args=\"ARGUMENTOS\"\n" - @echo -e "Tareas:\n" - @grep -E "^[a-z\-]+:.*##" Makefile | sed -re "s/(.*):.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" - @echo -e "\nArgumentos:\n" - @grep -E "^[a-z\-]+ \?=.*##" Makefile | sed -re "s/(.*) \?=.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" - test: always ## Ejecutar los tests $(MAKE) rake args="test RAILS_ENV=test $(args)" postgresql: ## Iniciar la base de datos pgrep postgres >/dev/null || $(hain) postgresql -serve-js: node_modules ## Iniciar el servidor de desarrollo de Javascript +serve-js: ## Iniciar el servidor de desarrollo de Javascript $(hain) 'bundle exec ./bin/webpack-dev-server' serve: postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails @@ -83,26 +49,6 @@ audit: ## Encuentra dependencias con vulnerabilidades brakeman: ## Busca posibles vulnerabilidades en Sutty $(MAKE) bundle args='exec brakeman' -yarn: ## Tareas de yarn - $(hain) 'yarn $(args)' - -build: Gemfile.lock ## Generar la imagen Docker - time docker build --build-arg="BRANCH=$(branch)" --build-arg="RAILS_MASTER_KEY=`cat config/master.key`" -t sutty/$(container) . - docker tag sutty/$(container):latest sutty:keep - @echo -e "\a" - -save: ## Subir la imagen Docker al nodo delegado - time docker save sutty/$(container):latest | ssh root@$(delegate) docker load - date +%F | xargs -I {} git tag -f $(container)-{} - @echo -e "\a" - -ota: ## Actualizar Rails en el nodo delegado - git push - ssh $(delegate) git -C /srv/sutty/srv/http/panel.sutty.nl pull - ssh $(delegate) git -C /srv/sutty/srv/http/panel.sutty.nl lfs prune - ssh $(delegate) chown -R 1000:82 /srv/sutty/srv/http/panel.sutty.nl - ssh $(delegate) docker exec $(container) rails reload - # Correr un test en particular por ejemplo # `make test/models/usuarie_test.rb` tests := $(shell find test/ -name "*_test.rb") From 27f3aff40324a7e99e0f3030919e8513e51c2502 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 16:21:22 -0300 Subject: [PATCH 247/814] feat: database --- .env.example | 2 ++ Taskfile.yaml | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/.env.example b/.env.example index cf59f77e..0bb338e4 100644 --- a/.env.example +++ b/.env.example @@ -38,3 +38,5 @@ AIRBRAKE_API_KEY= GITLAB_URI=https://0xacab.org GITLAB_PROJECT= GITLAB_TOKEN= +PGVER=15 +PGPID=/run/postgresql.pid diff --git a/Taskfile.yaml b/Taskfile.yaml index ca2a1ad1..3bb0bdc4 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -76,3 +76,24 @@ tasks: - "echo -e \"::1 panel.{{.SUTTY}} api.{{.SUTTY}} postgresql.{{.SUTTY}}\" | sudo tee -a /etc/hosts" status: - "grep -q \" panel.{{.SUTTY}} \" /etc/hosts" + database-init: + desc: "Database install" + deps: + - "env" + cmds: + - "{{.HAINISH}} /usr/bin/initdb --locale en_US.utf8 -E UTF8 -D /var/lib/postgresql/{{.PGVER}}/data" + - "echo \"host all all samenet trust\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/pg_hba.conf" + - "echo \"listen_addresses = '*'\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf" + - "echo \"external_pid_file = '{{.PGPID}}'\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf" + status: + - "test -d ../hain/var/lib/postgresql/{{.PGVER}}/data" + - "test -f ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf" + database: + desc: "Database" + deps: + - "database-init" + cmds: + - "{{.HAINISH}} daemonize -c /var/lib/postgresql/{{.PGVER}}/data /usr/bin/postgres -D /var/lib/postgresql/{{.PGVER}}/data" + status: + - "test -f ../hain{{.PGPID}}" + - "pgrep -F ../hain{{.PGPID}}" From a46bb264910c1273a6b374ca67db32d01f230b7d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 16:28:31 -0300 Subject: [PATCH 248/814] fix: migraciones faltantes --- db/structure.sql | 78 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index e0d8f710..cb085f63 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -9,13 +9,6 @@ SET xmloption = content; SET client_min_messages = warning; SET row_security = off; --- --- Name: public; Type: SCHEMA; Schema: -; Owner: - --- - --- *not* creating schema, since initdb creates it - - -- -- Name: pg_trgm; Type: EXTENSION; Schema: -; Owner: - -- @@ -44,6 +37,35 @@ CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public; COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions'; +-- +-- Name: access_logs_before_insert_row_tr(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.access_logs_before_insert_row_tr() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + new.created_at := to_timestamp(new.msec); + RETURN NEW; +END; +$$; + + +-- +-- Name: indexed_posts_before_insert_update_row_tr(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.indexed_posts_before_insert_update_row_tr() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + new.indexed_content := to_tsvector(('pg_catalog.' || new.dictionary)::regconfig, coalesce(new.title, '') || ' + ' || coalesce(new.content,'')); + RETURN NEW; +END; +$$; + + -- -- Name: que_validate_tags(jsonb); Type: FUNCTION; Schema: public; Owner: - -- @@ -103,35 +125,6 @@ WITH (fillfactor='90'); COMMENT ON TABLE public.que_jobs IS '7'; --- --- Name: access_logs_before_insert_row_tr(); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION public.access_logs_before_insert_row_tr() RETURNS trigger - LANGUAGE plpgsql - AS $$ -BEGIN - new.created_at := to_timestamp(new.msec); - RETURN NEW; -END; -$$; - - --- --- Name: indexed_posts_before_insert_update_row_tr(); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION public.indexed_posts_before_insert_update_row_tr() RETURNS trigger - LANGUAGE plpgsql - AS $$ -BEGIN - new.indexed_content := to_tsvector(('pg_catalog.' || new.dictionary)::regconfig, coalesce(new.title, '') || ' - ' || coalesce(new.content,'')); - RETURN NEW; -END; -$$; - - -- -- Name: que_determine_job_state(public.que_jobs); Type: FUNCTION; Schema: public; Owner: - -- @@ -1149,7 +1142,8 @@ CREATE TABLE public.roles ( site_id integer, usuarie_id integer, rol character varying, - temporal boolean + temporal boolean, + token character varying ); @@ -1236,7 +1230,9 @@ CREATE TABLE public.sites ( tienda_url character varying DEFAULT ''::character varying, api_key_ciphertext character varying, slugify_mode character varying DEFAULT 'default'::character varying, - pagination boolean DEFAULT false + pagination boolean DEFAULT false, + private_key_pem_ciphertext text, + last_indexed_commit character varying ); @@ -2318,6 +2314,10 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230421182627'), ('20230424174544'), ('20230519143500'), -('20230524190240'); +('20230524190240'), +('20230731195050'), +('20230829204127'), +('20230921155401'), +('20230927153926'); From 4e74204931a509e9edeba0f55bf516e0a6be1ab7 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 16:55:58 -0300 Subject: [PATCH 249/814] feat: servidor de desarrollo --- Makefile | 6 ------ Taskfile.yaml | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index d6ee991d..d8b737c2 100644 --- a/Makefile +++ b/Makefile @@ -8,15 +8,9 @@ hain ?= ENV_FILE=.env $(HAINISH)## Ubicación de Hainish test: always ## Ejecutar los tests $(MAKE) rake args="test RAILS_ENV=test $(args)" -postgresql: ## Iniciar la base de datos - pgrep postgres >/dev/null || $(hain) postgresql - serve-js: ## Iniciar el servidor de desarrollo de Javascript $(hain) 'bundle exec ./bin/webpack-dev-server' -serve: postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails - $(MAKE) rails args=server - rails: ## Corre rails dentro del entorno de desarrollo (pasar argumentos con args=). $(MAKE) bundle args="exec rails $(args)" diff --git a/Taskfile.yaml b/Taskfile.yaml index 3bb0bdc4..576c5f1c 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -97,3 +97,20 @@ tasks: status: - "test -f ../hain{{.PGPID}}" - "pgrep -F ../hain{{.PGPID}}" + prepare: + desc: "Create database or run pending migrations" + deps: + - "database" + cmds: + - "{{.HAINISH}} bundle exec rails db:prepare" + serve: + desc: "Run Rails development server" + deps: + - "prepare" + - "gems" + cmds: + - ": == Development server running at https://panel.{{.SUTTY_WITH_PORT}} ==" + - "{{.HAINISH}} bundle exec rails server" + status: + - "test -f tmp/pids/server.pid" + - "pgrep -F tmp/pids/server.pid" From 8be6337db14deef0beed4d22e751c00c202b98ac Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 16:58:56 -0300 Subject: [PATCH 250/814] docs: readme --- README.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 25d0d31c..6ec288b8 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,17 @@ Para más información visita el [sitio de Sutty](https://sutty.nl/). ### Desarrollar -Todas las tareas se gestionan con `make`, por favor instala GNU Make -antes de comenzar. +Para facilitar la gestión de dependencias y entorno de desarrollo, +instala [haini.sh](https://0xacab.org/sutty/haini.sh) + + +Todas las tareas se gestionan con `go-task`. [Instrucciones de +instalación (en inglés)](https://taskfile.dev/installation/) ```bash -make help +go-task ``` -[Leer la documentación](https://docs.sutty.nl/) - ## English Sutty is a platform for hosting safer, faster and more resilient @@ -39,10 +41,13 @@ For more information, visit [Sutty's website](https://sutty.nl/en/). ### Development -Every task is run via `make`, please install GNU Make before developing. + +To facilitate dependencies and dev environment, install +[haini.sh](https://0xacab.org/sutty/haini.sh) + +Every task is run via `go-task`. [Installation +instructions](https://taskfile.dev/installation/). ```bash -make help +go-task ``` - -[Read the documentation](https://docs.sutty.nl/en/) From 9490d4d57c797d7965161a43631d932c68710d43 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:00:38 -0300 Subject: [PATCH 251/814] fix: typo --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 36e6a6d1..6e7b7022 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -68,7 +68,7 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) - ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h } + ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h }) head :forbidden end From baec1f93d012cec60722aaba5ee5ce51023df9d0 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:13:43 -0300 Subject: [PATCH 252/814] feat: docs --- .gitignore | 2 ++ Gemfile | 1 + Gemfile.lock | 2 ++ README.md | 21 +++++++++++++++++++++ Taskfile.yaml | 6 ++++++ 5 files changed, 32 insertions(+) diff --git a/.gitignore b/.gitignore index 18d02ded..ec350559 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ yarn-debug.log* .yarn-integrity /.task +/.yardoc +/public/doc/ diff --git a/Gemfile b/Gemfile index 37bcd949..03da906d 100644 --- a/Gemfile +++ b/Gemfile @@ -116,6 +116,7 @@ group :development, :test do end group :development do + gem 'yard' gem 'brakeman' gem 'haml-lint', require: false gem 'letter_opener' diff --git a/Gemfile.lock b/Gemfile.lock index b63a806a..5be5a103 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -574,6 +574,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) + yard (0.9.34) zeitwerk (2.6.8) PLATFORMS @@ -669,6 +670,7 @@ DEPENDENCIES web-console webpacker yaml_db! + yard RUBY VERSION ruby 3.1.4p223 diff --git a/README.md b/README.md index 6ec288b8..6fefe82f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,16 @@ instalación (en inglés)](https://taskfile.dev/installation/) go-task ``` +### Documentación + +Para navegar la documentación del código usando YARD: + +```bash +go-task doc serve +``` + +Y luego navegar a + ## English Sutty is a platform for hosting safer, faster and more resilient @@ -51,3 +61,14 @@ instructions](https://taskfile.dev/installation/). ```bash go-task ``` + +### Documentation + +To browse documentation using YARD: + +```bash +go-task doc serve +``` + +And then open + diff --git a/Taskfile.yaml b/Taskfile.yaml index 576c5f1c..8d95e302 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -114,3 +114,9 @@ tasks: status: - "test -f tmp/pids/server.pid" - "pgrep -F tmp/pids/server.pid" + doc: + desc: "Build documentation" + deps: + - "gems" + cmds: + - "{{.HAINISH}} bundle exec yardoc -o public/doc app lib config db" From ce2fd301b41f7fe872a2cf13e0217ffe8717f8e0 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:25:00 -0300 Subject: [PATCH 253/814] feat: reuse tasks --- Taskfile.yaml | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 8d95e302..baacfea3 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -32,7 +32,7 @@ tasks: - "env" - "credentials" cmds: - - "{{.HAINISH}} bundle" + - "go-task bundle" sources: - "Gemfile" generates: @@ -58,9 +58,9 @@ tasks: cmds: - "git lfs fetch" - "git lfs checkout" - - "{{.HAINISH}} RAILS_ENV=production bundle exec rails webpacker:clobber" - - "{{.HAINISH}} RAILS_ENV=production bundle exec rails assets:precompile" - - "{{.HAINISH}} RAILS_ENV=production bundle exec rails assets:clean" + - "go-task bundle rails -- webpacker:clobber RAILS_ENV=production" + - "go-task bundle rails -- assets:precompile RAILS_ENV=production" + - "go-task bundle rails -- assets:clean RAILS_ENV=production" sources: - "package.json" - "yarn.lock" @@ -102,7 +102,7 @@ tasks: deps: - "database" cmds: - - "{{.HAINISH}} bundle exec rails db:prepare" + - "go-task rails -- db:prepare" serve: desc: "Run Rails development server" deps: @@ -110,13 +110,35 @@ tasks: - "gems" cmds: - ": == Development server running at https://panel.{{.SUTTY_WITH_PORT}} ==" - - "{{.HAINISH}} bundle exec rails server" + - "go-task rails -- server" status: - "test -f tmp/pids/server.pid" - "pgrep -F tmp/pids/server.pid" + yarn: + desc: "Yarn. Call with: go-task yarn -- arguments" + deps: + - "node-modules" + cmds: + - "{{.HAINISH}} yarn {{.CLI_ARGS}}" + bundle: + desc: "Bundle. Call with: go-task bundle -- arguments" + deps: + - "gems" + cmds: + - "{{.HAINISH}} bundle {{.CLI_ARGS}}" + rails: + desc: "Rails. Call with: go-task rails -- arguments" + deps: + - "prepare" + cmds: + - "go-task bundle -- exec rails {{.CLI_ARGS}}" + console: + desc: "Rails console" + cmds: + - "go-task rails -- console" doc: desc: "Build documentation" deps: - "gems" cmds: - - "{{.HAINISH}} bundle exec yardoc -o public/doc app lib config db" + - "go-task bundle -- exec yardoc -o public/doc app lib config db" From ef22f29d17203325ebbbaa05486015d7d7a3a792 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:36:39 -0300 Subject: [PATCH 254/814] feat: auditar dependencias --- .gitlab-ci.yml | 10 ++++++++++ Taskfile.yaml | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1726eb19..a2afebff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,3 +20,13 @@ assets: after_script: - "git add public && git commit -m \"ci: assets [skip ci]\"" - "git push -o ci.skip" +gem-audit: + stage: "audit" + before_script: + - "gem install bundler-audit" + script: + - "go-task gem-audit" +node-audit: + stage: "audit" + script: + - "go-task node-audit" diff --git a/Taskfile.yaml b/Taskfile.yaml index baacfea3..2bac8dd9 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -142,3 +142,15 @@ tasks: - "gems" cmds: - "go-task bundle -- exec yardoc -o public/doc app lib config db" + gem-audit: + desc: "Audit Gem dependencies" + deps: + - "gems" + cmds: + - "go-task bundle -- audit --update" + node-audit: + desc: "Audit Node dependencies" + deps: + - "node-modules" + cmds: + - "go-task yarn -- audit" From d581fab4dfda56edbfc22a077678e6618f167076 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:52:00 -0300 Subject: [PATCH 255/814] feat: lint --- .gitlab-ci.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a2afebff..ee2a7a10 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,10 +23,36 @@ assets: gem-audit: stage: "audit" before_script: + - "apk add go-task" - "gem install bundler-audit" script: - "go-task gem-audit" node-audit: stage: "audit" script: + - "apk add go-task" - "go-task node-audit" +brakeman: + stage: "lint" + rules: + - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" + before_script: + - "apk add go-task" + script: + - "go-task bundle -- exec brakeman" +rubocop: + stage: "lint" + rules: + - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" + before_script: + - "apk add go-task" + script: + - "git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...HEAD | grep -v \"^D\" | cut -f 2 | grep \"\.rb$\" | xargs go-task bundle -- exec rubocop" +haml: + stage: "lint" + rules: + - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" + before_script: + - "apk add go-task" + script: + - "git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...HEAD | grep -v \"^D\" | cut -f 2 | grep \"\.haml$\" | xargs go-task bundle -- exec haml-lint" From bf637bcc5c10ccd2732ff35192fbf09b082386fb Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:55:46 -0300 Subject: [PATCH 256/814] refactor: helper script --- .gitlab-ci.yml | 4 ++-- bin/modified_files | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100755 bin/modified_files diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ee2a7a10..44438cbb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,7 +47,7 @@ rubocop: before_script: - "apk add go-task" script: - - "git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...HEAD | grep -v \"^D\" | cut -f 2 | grep \"\.rb$\" | xargs go-task bundle -- exec rubocop" + - "./bin/modified_files | grep \"\.rb$$\" | xargs go-task bundle -- exec rubocop" haml: stage: "lint" rules: @@ -55,4 +55,4 @@ haml: before_script: - "apk add go-task" script: - - "git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...HEAD | grep -v \"^D\" | cut -f 2 | grep \"\.haml$\" | xargs go-task bundle -- exec haml-lint" + - "./bin/modified_files | grep \"\.haml$$\" | xargs go-task bundle -- exec haml-lint" diff --git a/bin/modified_files b/bin/modified_files new file mode 100755 index 00000000..0e6a4e08 --- /dev/null +++ b/bin/modified_files @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}" + +git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...rails \ + | grep -v "^D" \ + | cut -f 2 From 3837c92030abe4fb769117ce7f7055f6f8a65f06 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:57:04 -0300 Subject: [PATCH 257/814] fix: escape --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 44438cbb..feb2bc48 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,7 +47,7 @@ rubocop: before_script: - "apk add go-task" script: - - "./bin/modified_files | grep \"\.rb$$\" | xargs go-task bundle -- exec rubocop" + - "./bin/modified_files | grep .rb | xargs go-task bundle -- exec rubocop" haml: stage: "lint" rules: @@ -55,4 +55,4 @@ haml: before_script: - "apk add go-task" script: - - "./bin/modified_files | grep \"\.haml$$\" | xargs go-task bundle -- exec haml-lint" + - "./bin/modified_files | grep .haml | xargs go-task bundle -- exec haml-lint" From 6a91a4179c1b6e8b2f9e44f3f6ca6dbd603ee0df Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 17:59:27 -0300 Subject: [PATCH 258/814] ci: stages --- .gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index feb2bc48..67b737f8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,19 +21,19 @@ assets: - "git add public && git commit -m \"ci: assets [skip ci]\"" - "git push -o ci.skip" gem-audit: - stage: "audit" + stage: "test" before_script: - "apk add go-task" - "gem install bundler-audit" script: - "go-task gem-audit" node-audit: - stage: "audit" + stage: "test" script: - "apk add go-task" - "go-task node-audit" brakeman: - stage: "lint" + stage: "test" rules: - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" before_script: @@ -41,7 +41,7 @@ brakeman: script: - "go-task bundle -- exec brakeman" rubocop: - stage: "lint" + stage: "test" rules: - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" before_script: @@ -49,7 +49,7 @@ rubocop: script: - "./bin/modified_files | grep .rb | xargs go-task bundle -- exec rubocop" haml: - stage: "lint" + stage: "test" rules: - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" before_script: From 2bf907aa009df00412958d789d0612d35627bb9c Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:00:52 -0300 Subject: [PATCH 259/814] ci: compilar assets al final --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 67b737f8..93b8ad4f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,7 @@ cache: - "node_modules" - ".task" assets: - stage: "build" + stage: "deploy" before_script: - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" From ad017f559869282cacc5b2b84da59e000720ed99 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:15:36 -0300 Subject: [PATCH 260/814] ci: disable hainish + dry --- .gitlab-ci.yml | 30 ++++++++++++++++++++++-------- Taskfile.yaml | 1 + 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 93b8ad4f..144b609c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,8 @@ +.add-go-task: &add-go-task +- "apk add go-task" +.disable-hainish: &disable-hainish +- "echo \"HAINISH=\" >> .env.production" + image: "gitea.nulo.in/sutty/panel:3.17.3-3.1.4-rails" variables: RAILS_ENV: "production" @@ -14,7 +19,9 @@ assets: - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" - - "apk add brotli go-task diffutils" + - "apk add brotli diffutils" + - *add-go-task + - *disable-hainish script: - "go-task assets" after_script: @@ -23,36 +30,43 @@ assets: gem-audit: stage: "test" before_script: - - "apk add go-task" - "gem install bundler-audit" + - *add-go-task + - *disable-hainish script: - "go-task gem-audit" node-audit: stage: "test" + before_script: + - *add-go-task + - *disable-hainish script: - "apk add go-task" - "go-task node-audit" brakeman: stage: "test" rules: - - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" + - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: - - "apk add go-task" + - *add-go-task + - *disable-hainish script: - "go-task bundle -- exec brakeman" rubocop: stage: "test" rules: - - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" + - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: - - "apk add go-task" + - *add-go-task + - *disable-hainish script: - "./bin/modified_files | grep .rb | xargs go-task bundle -- exec rubocop" haml: stage: "test" rules: - - if: "$CI_PIPELINE_SOURCE == \"merge_request_event\"" + - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: - - "apk add go-task" + - *add-go-task + - *disable-hainish script: - "./bin/modified_files | grep .haml | xargs go-task bundle -- exec haml-lint" diff --git a/Taskfile.yaml b/Taskfile.yaml index 2bac8dd9..6dc255b1 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -7,6 +7,7 @@ shopt: - "globstar" dotenv: - ".env" +- ".env.production" tasks: credentials: desc: "Generate credentials file" From 6d24e7c56a7537173c7faa7e3d6a8a1827a5a4d8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:18:15 -0300 Subject: [PATCH 261/814] ci: diffutils --- .gitlab-ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 144b609c..7f3da468 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ -.add-go-task: &add-go-task -- "apk add go-task" +.apk-add: &apk-add +- "apk add go-task diffutils" .disable-hainish: &disable-hainish - "echo \"HAINISH=\" >> .env.production" @@ -19,8 +19,8 @@ assets: - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" - - "apk add brotli diffutils" - - *add-go-task + - "apk add brotli" + - *apk-add - *disable-hainish script: - "go-task assets" @@ -31,14 +31,14 @@ gem-audit: stage: "test" before_script: - "gem install bundler-audit" - - *add-go-task + - *apk-add - *disable-hainish script: - "go-task gem-audit" node-audit: stage: "test" before_script: - - *add-go-task + - *apk-add - *disable-hainish script: - "apk add go-task" @@ -48,7 +48,7 @@ brakeman: rules: - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: - - *add-go-task + - *apk-add - *disable-hainish script: - "go-task bundle -- exec brakeman" @@ -57,7 +57,7 @@ rubocop: rules: - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: - - *add-go-task + - *apk-add - *disable-hainish script: - "./bin/modified_files | grep .rb | xargs go-task bundle -- exec rubocop" @@ -66,7 +66,7 @@ haml: rules: - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: - - *add-go-task + - *apk-add - *disable-hainish script: - "./bin/modified_files | grep .haml | xargs go-task bundle -- exec haml-lint" From e0a214948352ea3878cb88cad8af991501d6b12e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:25:24 -0300 Subject: [PATCH 262/814] ci: no hacer nada si no hay nada que hacer --- .gitlab-ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7f3da468..cb4cd1e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,6 @@ - "apk add go-task diffutils" .disable-hainish: &disable-hainish - "echo \"HAINISH=\" >> .env.production" - image: "gitea.nulo.in/sutty/panel:3.17.3-3.1.4-rails" variables: RAILS_ENV: "production" @@ -60,7 +59,7 @@ rubocop: - *apk-add - *disable-hainish script: - - "./bin/modified_files | grep .rb | xargs go-task bundle -- exec rubocop" + - "./bin/modified_files | grep .rb | xargs -r go-task bundle -- exec rubocop" haml: stage: "test" rules: @@ -69,4 +68,4 @@ haml: - *apk-add - *disable-hainish script: - - "./bin/modified_files | grep .haml | xargs go-task bundle -- exec haml-lint" + - "./bin/modified_files | grep .haml | xargs -r go-task bundle -- exec haml-lint" From 0569f7cab9a24909e7478a77ffaa2598693882a2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:30:22 -0300 Subject: [PATCH 263/814] ci: caches --- .gitlab-ci.yml | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb4cd1e1..45671a40 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,18 +2,27 @@ - "apk add go-task diffutils" .disable-hainish: &disable-hainish - "echo \"HAINISH=\" >> .env.production" +.cache-ruby: &cache-ruby +- paths: + - "vendor/ruby" +.cache-node: &cache-node +- paths: + - "node_modules" +.cache-task: &cache-task +- paths: + - ".task" image: "gitea.nulo.in/sutty/panel:3.17.3-3.1.4-rails" variables: RAILS_ENV: "production" LC_ALL: "C.UTF-8" HAINISH: "" cache: - paths: - - "vendor/ruby" - - "node_modules" - - ".task" assets: stage: "deploy" + cache: + - *cache-ruby + - *cache-node + - *cache-task before_script: - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" @@ -28,6 +37,8 @@ assets: - "git push -o ci.skip" gem-audit: stage: "test" + cache: + - *cache-ruby before_script: - "gem install bundler-audit" - *apk-add @@ -36,6 +47,8 @@ gem-audit: - "go-task gem-audit" node-audit: stage: "test" + cache: + - *cache-node before_script: - *apk-add - *disable-hainish @@ -44,6 +57,8 @@ node-audit: - "go-task node-audit" brakeman: stage: "test" + cache: + - *cache-ruby rules: - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: @@ -53,6 +68,8 @@ brakeman: - "go-task bundle -- exec brakeman" rubocop: stage: "test" + cache: + - *cache-ruby rules: - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: @@ -62,6 +79,8 @@ rubocop: - "./bin/modified_files | grep .rb | xargs -r go-task bundle -- exec rubocop" haml: stage: "test" + cache: + - *cache-ruby rules: - if: "$CI_PIPELINE_SOURCE == 'merge_request_event'" before_script: From b6d214c05286366194e7059a840b2aa0c7570256 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:32:33 -0300 Subject: [PATCH 264/814] ci: deshabilitar hainish en ci --- .env.example | 1 - .gitlab-ci.yml | 2 +- Taskfile.yaml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 0bb338e4..480175f8 100644 --- a/.env.example +++ b/.env.example @@ -3,7 +3,6 @@ NODE_OPTIONS=--openssl-legacy-provider RAILS_MASTER_KEY=11111111111111111111111111111111 RAILS_GROUPS=assets DELEGATE=panel.sutty.nl -HAINISH=../haini.sh/haini.sh DATABASE_URL=postgres://suttier@postgresql.sutty.local/sutty RAILS_ENV=development IMAP_SERVER= diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 45671a40..fa394d6a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ .apk-add: &apk-add - "apk add go-task diffutils" .disable-hainish: &disable-hainish -- "echo \"HAINISH=\" >> .env.production" +- "rm -f .env.development" .cache-ruby: &cache-ruby - paths: - "vendor/ruby" diff --git a/Taskfile.yaml b/Taskfile.yaml index 6dc255b1..bebae6bf 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -7,7 +7,7 @@ shopt: - "globstar" dotenv: - ".env" -- ".env.production" +- ".env.development" tasks: credentials: desc: "Generate credentials file" From 1dfd76704f203e534a1970c09b900a1de50931ea Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:35:02 -0300 Subject: [PATCH 265/814] fix: origin --- bin/modified_files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/modified_files b/bin/modified_files index 0e6a4e08..37bcabeb 100755 --- a/bin/modified_files +++ b/bin/modified_files @@ -3,6 +3,6 @@ set -e test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}" -git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...rails \ +git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...origin/rails \ | grep -v "^D" \ | cut -f 2 From aa0aac20e6fce72fde9250122206ca632eba8f88 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:43:12 -0300 Subject: [PATCH 266/814] ci: no fallar si no hay archivos --- .gitlab-ci.yml | 4 ++-- bin/with_extension | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100755 bin/with_extension diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fa394d6a..c7a665a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -76,7 +76,7 @@ rubocop: - *apk-add - *disable-hainish script: - - "./bin/modified_files | grep .rb | xargs -r go-task bundle -- exec rubocop" + - "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop" haml: stage: "test" cache: @@ -87,4 +87,4 @@ haml: - *apk-add - *disable-hainish script: - - "./bin/modified_files | grep .haml | xargs -r go-task bundle -- exec haml-lint" + - "./bin/modified_files | ./bin/with_extension haml | xargs -r go-task bundle -- exec haml-lint" diff --git a/bin/with_extension b/bin/with_extension new file mode 100755 index 00000000..129122dc --- /dev/null +++ b/bin/with_extension @@ -0,0 +1,4 @@ +#!/bin/sh + +grep "\.${1}$" +exit 0 From c2cc490772b9a357a5ff8dc544439d035bcd64c8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:46:14 -0300 Subject: [PATCH 267/814] BREAKING CHANGE: deprecar makefile --- Makefile | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 Makefile diff --git a/Makefile b/Makefile deleted file mode 100644 index d8b737c2..00000000 --- a/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -SHELL := /bin/bash - -# XXX: El espacio antes del comentario cuenta como espacio -args ?=## Argumentos para Hain -delegate ?= $(DELEGATE)## Cambia el nodo delegado -hain ?= ENV_FILE=.env $(HAINISH)## Ubicación de Hainish - -test: always ## Ejecutar los tests - $(MAKE) rake args="test RAILS_ENV=test $(args)" - -serve-js: ## Iniciar el servidor de desarrollo de Javascript - $(hain) 'bundle exec ./bin/webpack-dev-server' - -rails: ## Corre rails dentro del entorno de desarrollo (pasar argumentos con args=). - $(MAKE) bundle args="exec rails $(args)" - -rake: ## Corre rake dentro del entorno de desarrollo (pasar argumentos con args=). - $(MAKE) bundle args="exec rake $(args)" - -bundle: ## Corre bundle dentro del entorno de desarrollo (pasar argumentos con args=). - $(hain) 'bundle $(args)' - -psql := psql $(DATABASE_URL) -copy-table: - test -n "$(table)" - echo "truncate $(table) $(cascade);" | $(psql) - ssh $(delegate) docker exec postgresql pg_dump -U sutty -d sutty -t $(table) | $(psql) - -psql: - $(hain) $(psql) - -rubocop: ## Yutea el código que está por ser commiteado - git status --porcelain \ - | grep -E "^(A|M)" \ - | sed "s/^...//" \ - | grep ".rb$$" \ - | ../haini.sh/haini.sh "xargs -r ./bin/rubocop --auto-correct" - -audit: ## Encuentra dependencias con vulnerabilidades - $(hain) 'gem install bundler-audit' - $(hain) 'bundle audit --update' - -brakeman: ## Busca posibles vulnerabilidades en Sutty - $(MAKE) bundle args='exec brakeman' - -# Correr un test en particular por ejemplo -# `make test/models/usuarie_test.rb` -tests := $(shell find test/ -name "*_test.rb") -$(tests): always - $(MAKE) test args="TEST=$@" - -.PHONY: always From 034af360ee8a0467af84ac801c2d906b0285acf1 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Jan 2024 18:55:49 -0300 Subject: [PATCH 268/814] ci: condicional --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c7a665a8..b4aa5154 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,6 +19,8 @@ variables: cache: assets: stage: "deploy" + only: + - "rails" cache: - *cache-ruby - *cache-node @@ -37,6 +39,8 @@ assets: - "git push -o ci.skip" gem-audit: stage: "test" + only: + - "schedules" cache: - *cache-ruby before_script: @@ -47,6 +51,8 @@ gem-audit: - "go-task gem-audit" node-audit: stage: "test" + only: + - "schedules" cache: - *cache-node before_script: From 0b87e9753e0f29328104378d1c83eba547416190 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 11:39:07 -0300 Subject: [PATCH 269/814] fix: env para desarrollo (cherry picked from commit c2534578400e416d5560ed1344e58a87d1cc6092) --- .env.development | 1 + 1 file changed, 1 insertion(+) create mode 100644 .env.development diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..df2788b0 --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +HAINISH=../haini.sh/haini.sh From c4600edb6a3cbd580d116de97cc9cf280d17b2d6 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 11:43:13 -0300 Subject: [PATCH 270/814] fix: solo llamar a rails --- Taskfile.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index bebae6bf..bb0691e1 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -59,9 +59,9 @@ tasks: cmds: - "git lfs fetch" - "git lfs checkout" - - "go-task bundle rails -- webpacker:clobber RAILS_ENV=production" - - "go-task bundle rails -- assets:precompile RAILS_ENV=production" - - "go-task bundle rails -- assets:clean RAILS_ENV=production" + - "go-task rails -- webpacker:clobber RAILS_ENV=production" + - "go-task rails -- assets:precompile RAILS_ENV=production" + - "go-task rails -- assets:clean RAILS_ENV=production" sources: - "package.json" - "yarn.lock" From 77672535dd40553c3873b22faaffdd2202921b08 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 11:47:00 -0300 Subject: [PATCH 271/814] fix: evitar loop infinito --- Taskfile.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index bb0691e1..bbbe7f1f 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -129,8 +129,6 @@ tasks: - "{{.HAINISH}} bundle {{.CLI_ARGS}}" rails: desc: "Rails. Call with: go-task rails -- arguments" - deps: - - "prepare" cmds: - "go-task bundle -- exec rails {{.CLI_ARGS}}" console: From 089c09a26cd8355bebf57c4328ae57bb0320f262 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 11:48:40 -0300 Subject: [PATCH 272/814] fix: la consola es interactiva --- Taskfile.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index bbbe7f1f..71f582db 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -133,6 +133,7 @@ tasks: - "go-task bundle -- exec rails {{.CLI_ARGS}}" console: desc: "Rails console" + interactive: true cmds: - "go-task rails -- console" doc: From f48802845583036fd7773ff95d4889b50bf37a28 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 17:04:53 -0300 Subject: [PATCH 273/814] BREAKING CHANGE: variables de entorno --- .env.example => .env | 0 .gitignore | 2 +- Gemfile | 3 +-- README.md | 11 +++++++++++ Taskfile.yaml | 17 +++-------------- config/application.rb | 11 +++++++++++ 6 files changed, 27 insertions(+), 17 deletions(-) rename .env.example => .env (100%) diff --git a/.env.example b/.env similarity index 100% rename from .env.example rename to .env diff --git a/.gitignore b/.gitignore index ec350559..2bdf8c49 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ /data/* /_storage/* -.env* +.env.* # Ignore master key for decrypting credentials and more. /config/master.key diff --git a/Gemfile b/Gemfile index 03da906d..f97c29ab 100644 --- a/Gemfile +++ b/Gemfile @@ -4,8 +4,6 @@ source ENV.fetch('GEMS_SOURCE', 'https://17.3.alpine.gems.sutty.nl') ruby "~> #{ENV.fetch('RUBY_VERSION', '3.1')}" -gem 'dotenv-rails', require: 'dotenv/rails-now' - # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 6.1.0' # Use Puma as the app server @@ -108,6 +106,7 @@ end group :development, :test do gem 'derailed_benchmarks' + gem 'dotenv-rails' gem 'pry' # Adds support for Capybara system testing and selenium driver gem 'capybara', '~> 2.13' diff --git a/README.md b/README.md index 6fefe82f..5139f6cd 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,12 @@ instalación (en inglés)](https://taskfile.dev/installation/) go-task ``` +### Variables de entorno + +Las variables de entorno por defecto se encuentran en el archivo `.env`. +Para modificar las opciones, crear o modificar el archivo `.env.local` +con valores distintos. + ### Documentación Para navegar la documentación del código usando YARD: @@ -62,6 +68,11 @@ instructions](https://taskfile.dev/installation/). go-task ``` +### Environment variables + +Default env vars are store on `.env`. For local options, copy them to +`.env.local`. + ### Documentation To browse documentation using YARD: diff --git a/Taskfile.yaml b/Taskfile.yaml index 71f582db..e98c2d0e 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -6,8 +6,10 @@ vars: shopt: - "globstar" dotenv: -- ".env" - ".env.development" +- ".env" +- ".env.local" +- ".env.development.local" tasks: credentials: desc: "Generate credentials file" @@ -17,20 +19,9 @@ tasks: - "config/credentials.yml.enc.ci" generates: - "config/credentials.yml.enc" - env: - desc: "Install the .env file" - cmds: - - "test -f .env || cp .env.example .env" - - ": == Environment vars have changed, please review and edit ==" - - "diff -auN --color .env.example .env" - sources: - - ".env.example" - generates: - - ".env" gems: desc: "Install gems" deps: - - "env" - "credentials" cmds: - "go-task bundle" @@ -79,8 +70,6 @@ tasks: - "grep -q \" panel.{{.SUTTY}} \" /etc/hosts" database-init: desc: "Database install" - deps: - - "env" cmds: - "{{.HAINISH}} /usr/bin/initdb --locale en_US.utf8 -E UTF8 -D /var/lib/postgresql/{{.PGVER}}/data" - "echo \"host all all samenet trust\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/pg_hba.conf" diff --git a/config/application.rb b/config/application.rb index 606ccaf4..529e341a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -21,6 +21,17 @@ require 'rails/test_unit/railtie' # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) +if %w[development test].include? ENV['RAILS_ENV'] + # https://github.com/bkeepers/dotenv/pull/453 + Dotenv::Railtie.class_eval do + def overload + Dotenv.overload(*dotenv_files.reverse) + end + end + + Dotenv::Railtie.overload +end + module Sutty # Sutty! class Application < Rails::Application From e82e93c8839287f6d3ac6123c4bc2e515b74829a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Jan 2024 17:17:19 -0300 Subject: [PATCH 274/814] fix: permitir que task se llame a si mismo en ubuntu el comando se llama `task` en vez de `go-task` --- Taskfile.yaml | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index e98c2d0e..d13eae35 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -24,7 +24,7 @@ tasks: deps: - "credentials" cmds: - - "go-task bundle" + - task: "bundle" sources: - "Gemfile" generates: @@ -50,9 +50,15 @@ tasks: cmds: - "git lfs fetch" - "git lfs checkout" - - "go-task rails -- webpacker:clobber RAILS_ENV=production" - - "go-task rails -- assets:precompile RAILS_ENV=production" - - "go-task rails -- assets:clean RAILS_ENV=production" + - task: "rails" + vars: + CLI_ARGS: "webpacker:clobber RAILS_ENV=production" + - task: "rails" + vars: + CLI_ARGS: "assets:precompile RAILS_ENV=production" + - task: "rails" + vars: + CLI_ARGS: "assets:clean RAILS_ENV=production" sources: - "package.json" - "yarn.lock" @@ -92,7 +98,9 @@ tasks: deps: - "database" cmds: - - "go-task rails -- db:prepare" + - task: "rails" + vars: + CLI_ARGS: "db:prepare" serve: desc: "Run Rails development server" deps: @@ -100,7 +108,9 @@ tasks: - "gems" cmds: - ": == Development server running at https://panel.{{.SUTTY_WITH_PORT}} ==" - - "go-task rails -- server" + - task: "rails" + vars: + CLI_ARGS: "server" status: - "test -f tmp/pids/server.pid" - "pgrep -F tmp/pids/server.pid" @@ -112,6 +122,7 @@ tasks: - "{{.HAINISH}} yarn {{.CLI_ARGS}}" bundle: desc: "Bundle. Call with: go-task bundle -- arguments" + interactive: true deps: - "gems" cmds: @@ -119,27 +130,37 @@ tasks: rails: desc: "Rails. Call with: go-task rails -- arguments" cmds: - - "go-task bundle -- exec rails {{.CLI_ARGS}}" + - task: "bundle" + vars: + CLI_ARGS: "exec rails {{.CLI_ARGS}}" console: desc: "Rails console" interactive: true cmds: - - "go-task rails -- console" + - task: "rails" + vars: + CLI_ARGS: "console" doc: desc: "Build documentation" deps: - "gems" cmds: - - "go-task bundle -- exec yardoc -o public/doc app lib config db" + - task: "bundle" + vars: + CLI_ARGS: "exec yardoc -o public/doc app lib config db" gem-audit: desc: "Audit Gem dependencies" deps: - "gems" cmds: - - "go-task bundle -- audit --update" + - task: "bundle" + vars: + CLI_ARGS: "audit --update" node-audit: desc: "Audit Node dependencies" deps: - "node-modules" cmds: - - "go-task yarn -- audit" + - task: "yarn" + vars: + CLI_ARGS: "audit" From 9a1bd58aa5ac6636953c2935da1bc6cb79d6d87b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 11:22:13 -0300 Subject: [PATCH 275/814] fix: usar el contenedor local --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b4aa5154..38f480c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,7 +11,7 @@ .cache-task: &cache-task - paths: - ".task" -image: "gitea.nulo.in/sutty/panel:3.17.3-3.1.4-rails" +image: "registry.0xacab.org/sutty/sutty:3.17.3-3.1.4-rails" variables: RAILS_ENV: "production" LC_ALL: "C.UTF-8" From b93bfd7fd30047252ecd0ad28615146645649d57 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 12:38:54 -0300 Subject: [PATCH 276/814] feat: notificar cuando termina una tarea --- Taskfile.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index d13eae35..ccaf5ef0 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -120,6 +120,8 @@ tasks: - "node-modules" cmds: - "{{.HAINISH}} yarn {{.CLI_ARGS}}" + - defer: + task: "notify" bundle: desc: "Bundle. Call with: go-task bundle -- arguments" interactive: true @@ -127,6 +129,8 @@ tasks: - "gems" cmds: - "{{.HAINISH}} bundle {{.CLI_ARGS}}" + - defer: + task: "notify" rails: desc: "Rails. Call with: go-task rails -- arguments" cmds: @@ -164,3 +168,7 @@ tasks: - task: "yarn" vars: CLI_ARGS: "audit" + notify: + internal: true + cmds: + - "echo -e \"\a\"" From ae81640fcc96abbd5a53624452f8582651ca5b7d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 12:45:49 -0300 Subject: [PATCH 277/814] fix: instalar directorio para el socket --- Taskfile.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index ccaf5ef0..27c02f67 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -81,6 +81,7 @@ tasks: - "echo \"host all all samenet trust\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/pg_hba.conf" - "echo \"listen_addresses = '*'\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf" - "echo \"external_pid_file = '{{.PGPID}}'\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf" + - "install -dm755 ../hain/run/postgresql" status: - "test -d ../hain/var/lib/postgresql/{{.PGVER}}/data" - "test -f ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf" From c7310b733988669cdff6c68592e6e508b2e1f2de Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 12:55:37 -0300 Subject: [PATCH 278/814] =?UTF-8?q?fix:=20instalar=20bundler=20audit=20si?= =?UTF-8?q?=20no=20existe=20todav=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Taskfile.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index 27c02f67..8427db4a 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -157,6 +157,7 @@ tasks: desc: "Audit Gem dependencies" deps: - "gems" + - "bundler-audit" cmds: - task: "bundle" vars: @@ -173,3 +174,9 @@ tasks: internal: true cmds: - "echo -e \"\a\"" + bundler-audit: + internal: true + cmds: + - "{{.HAINISH}} gem install bundler-audit" + status: + - "test -f ../hain/usr/bin/bundler-audit" From 5aef69cd940e05cadc365bed4af835cd7e82a78e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 16:52:24 -0300 Subject: [PATCH 279/814] fix: eliminar los guiones bajos al principio del nombre de archivo #14953 porque jekyll los toma como archivos ocultos --- .../active_storage/direct_uploads_controller_decorator.rb | 2 +- app/lib/action_dispatch/http/uploaded_file_decorator.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/active_storage/direct_uploads_controller_decorator.rb b/app/controllers/active_storage/direct_uploads_controller_decorator.rb index c62dae2a..5ac58ecf 100644 --- a/app/controllers/active_storage/direct_uploads_controller_decorator.rb +++ b/app/controllers/active_storage/direct_uploads_controller_decorator.rb @@ -19,7 +19,7 @@ module ActiveStorage # stack. def blob_args params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, metadata: {}).to_h.symbolize_keys.tap do |ba| - ba[:filename] = ba[:filename].unicode_normalize + ba[:filename] = ba[:filename].unicode_normalize.sub(/\A_+/, '') end end end diff --git a/app/lib/action_dispatch/http/uploaded_file_decorator.rb b/app/lib/action_dispatch/http/uploaded_file_decorator.rb index 0bdebdc0..7b28a0db 100644 --- a/app/lib/action_dispatch/http/uploaded_file_decorator.rb +++ b/app/lib/action_dispatch/http/uploaded_file_decorator.rb @@ -11,7 +11,7 @@ module ActionDispatch # Devolver el nombre de archivo con caracteres unicode # normalizados def original_filename - @original_filename.unicode_normalize + @original_filename.unicode_normalize.sub(/\A_+/, '') end end end From 76644700d164060079c125148b6a7f62d50ca4ba Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:03:37 -0300 Subject: [PATCH 280/814] fix: traer la lista de archivos modificados --- bin/modified_files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/modified_files b/bin/modified_files index 37bcabeb..d26e71f3 100755 --- a/bin/modified_files +++ b/bin/modified_files @@ -3,6 +3,6 @@ set -e test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}" -git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...origin/rails \ +git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA} \ | grep -v "^D" \ | cut -f 2 From 9c97e0f87c3c618083444d75af4f5b8021d2a16c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:08:05 -0300 Subject: [PATCH 281/814] =?UTF-8?q?ci:=20por=20qu=C3=A9=20faltan=20las=20g?= =?UTF-8?q?emas=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 38f480c9..39d7787f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -81,6 +81,7 @@ rubocop: before_script: - *apk-add - *disable-hainish + - ls -hal vendor/ruby script: - "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop" haml: From a78d02d84af8fb4bc9db2e23a7b18a2bb5ef2dee Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:10:55 -0300 Subject: [PATCH 282/814] =?UTF-8?q?fixup!=20ci:=20por=20qu=C3=A9=20faltan?= =?UTF-8?q?=20las=20gemas=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 39d7787f..aa3677f2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -81,6 +81,9 @@ rubocop: before_script: - *apk-add - *disable-hainish + - env + - ls -hal vendor + - ls -hal vendor - ls -hal vendor/ruby script: - "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop" From 1ede2af465114a80c776e116d40a537f851334f7 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:18:36 -0300 Subject: [PATCH 283/814] fix: instalar dependencias --- Taskfile.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 8427db4a..c2d72472 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -24,11 +24,14 @@ tasks: deps: - "credentials" cmds: - - task: "bundle" + - "{{.HAINISH}} bundle config set --local path './vendor'" + - "{{.HAINISH}} bundle install" sources: - "Gemfile" generates: - "Gemfile.lock" + status: + - "test -d vendor/ruby" clean: desc: "Clean" cmds: From 24120bfd904101e42e722ef9dc456da03e129a81 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:18:58 -0300 Subject: [PATCH 284/814] =?UTF-8?q?fix:=20agregar=20configuraci=C3=B3n=20d?= =?UTF-8?q?e=20bundler=20a=20la=20cach=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aa3677f2..0e38e7d6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ .cache-ruby: &cache-ruby - paths: - "vendor/ruby" + - ".bundle" .cache-node: &cache-node - paths: - "node_modules" From 987e19f565e7e85ae68836ddb552a83d315e1e51 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:24:51 -0300 Subject: [PATCH 285/814] =?UTF-8?q?fixup!=20fixup!=20ci:=20por=20qu=C3=A9?= =?UTF-8?q?=20faltan=20las=20gemas=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0e38e7d6..e4cee087 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ .apk-add: &apk-add -- "apk add go-task diffutils" +- "apk add go-task diffutils gitlab_ci_log_section" .disable-hainish: &disable-hainish - "rm -f .env.development" .cache-ruby: &cache-ruby @@ -27,13 +27,18 @@ assets: - *cache-node - *cache-task before_script: + - "gitlab_ci_log_section --name git --header=\"Configuring git\"" - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" + - "gitlab_ci_log_section --name git --end" + - "gitlab_ci_log_section --name apk --header=\"Installing dependencies\"" - "apk add brotli" - *apk-add - *disable-hainish + - "gitlab_ci_log_section --name apk --end" script: + - "gitlab_ci_log_section --name assets --header=\"Building\"" - "go-task assets" after_script: - "git add public && git commit -m \"ci: assets [skip ci]\"" @@ -82,10 +87,6 @@ rubocop: before_script: - *apk-add - *disable-hainish - - env - - ls -hal vendor - - ls -hal vendor - - ls -hal vendor/ruby script: - "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop" haml: From 7f3d87b3177f3f87b3b4bc484be3ffec751b7edc Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:29:32 -0300 Subject: [PATCH 286/814] chore: rubocop --- .../active_storage/direct_uploads_controller_decorator.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/active_storage/direct_uploads_controller_decorator.rb b/app/controllers/active_storage/direct_uploads_controller_decorator.rb index 5ac58ecf..94070882 100644 --- a/app/controllers/active_storage/direct_uploads_controller_decorator.rb +++ b/app/controllers/active_storage/direct_uploads_controller_decorator.rb @@ -18,7 +18,8 @@ module ActiveStorage # para que puedan propagarse correctamente a través de todo el # stack. def blob_args - params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, metadata: {}).to_h.symbolize_keys.tap do |ba| + params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, + metadata: {}).to_h.symbolize_keys.tap do |ba| ba[:filename] = ba[:filename].unicode_normalize.sub(/\A_+/, '') end end From 1fbfd30017079bafaff19021b32d8587f95fa116 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:18:36 -0300 Subject: [PATCH 287/814] fix: instalar dependencias --- Taskfile.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 8427db4a..c2d72472 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -24,11 +24,14 @@ tasks: deps: - "credentials" cmds: - - task: "bundle" + - "{{.HAINISH}} bundle config set --local path './vendor'" + - "{{.HAINISH}} bundle install" sources: - "Gemfile" generates: - "Gemfile.lock" + status: + - "test -d vendor/ruby" clean: desc: "Clean" cmds: From 7e43d8f3326bc91e87b224a4b2eea51058ef4694 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:18:58 -0300 Subject: [PATCH 288/814] =?UTF-8?q?fix:=20agregar=20configuraci=C3=B3n=20d?= =?UTF-8?q?e=20bundler=20a=20la=20cach=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 38f480c9..fd67b54a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ .cache-ruby: &cache-ruby - paths: - "vendor/ruby" + - ".bundle" .cache-node: &cache-node - paths: - "node_modules" From 6ec99072736dae32e8aef1f068e78e0ea2fbc254 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:29:32 -0300 Subject: [PATCH 289/814] chore: rubocop --- .../active_storage/direct_uploads_controller_decorator.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/active_storage/direct_uploads_controller_decorator.rb b/app/controllers/active_storage/direct_uploads_controller_decorator.rb index 5ac58ecf..94070882 100644 --- a/app/controllers/active_storage/direct_uploads_controller_decorator.rb +++ b/app/controllers/active_storage/direct_uploads_controller_decorator.rb @@ -18,7 +18,8 @@ module ActiveStorage # para que puedan propagarse correctamente a través de todo el # stack. def blob_args - params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, metadata: {}).to_h.symbolize_keys.tap do |ba| + params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, + metadata: {}).to_h.symbolize_keys.tap do |ba| ba[:filename] = ba[:filename].unicode_normalize.sub(/\A_+/, '') end end From 1fdc3404bef69963a47d475a77b8695f9936a19b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:03:37 -0300 Subject: [PATCH 290/814] fix: traer la lista de archivos modificados (cherry picked from commit 76644700d164060079c125148b6a7f62d50ca4ba) --- bin/modified_files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/modified_files b/bin/modified_files index 37bcabeb..d26e71f3 100755 --- a/bin/modified_files +++ b/bin/modified_files @@ -3,6 +3,6 @@ set -e test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}" -git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA}...origin/rails \ +git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA} \ | grep -v "^D" \ | cut -f 2 From 8f319eba6b11422db520b2debffb36ba273a898c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:18:36 -0300 Subject: [PATCH 291/814] fix: instalar dependencias (cherry picked from commit 1fbfd30017079bafaff19021b32d8587f95fa116) --- Taskfile.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 8427db4a..c2d72472 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -24,11 +24,14 @@ tasks: deps: - "credentials" cmds: - - task: "bundle" + - "{{.HAINISH}} bundle config set --local path './vendor'" + - "{{.HAINISH}} bundle install" sources: - "Gemfile" generates: - "Gemfile.lock" + status: + - "test -d vendor/ruby" clean: desc: "Clean" cmds: From 399d904f9efa3128e6e574f564b29ab1f6a891f7 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 17:18:58 -0300 Subject: [PATCH 292/814] =?UTF-8?q?fix:=20agregar=20configuraci=C3=B3n=20d?= =?UTF-8?q?e=20bundler=20a=20la=20cach=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 7e43d8f3326bc91e87b224a4b2eea51058ef4694) --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 38f480c9..fd67b54a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ .cache-ruby: &cache-ruby - paths: - "vendor/ruby" + - ".bundle" .cache-node: &cache-node - paths: - "node_modules" From c22276f74f9de7fa8fa69d42db2e32b1455b6b1d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 18:13:52 -0300 Subject: [PATCH 293/814] =?UTF-8?q?fix:=20especificar=20qu=C3=A9=20paramet?= =?UTF-8?q?ros=20de=20airbrake=20permitimos=20#14956?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/notices_controller.rb | 38 ++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/notices_controller.rb b/app/controllers/api/v1/notices_controller.rb index 3d74a48f..8f384f1a 100644 --- a/app/controllers/api/v1/notices_controller.rb +++ b/app/controllers/api/v1/notices_controller.rb @@ -9,10 +9,10 @@ module Api # Generar un stacktrace en segundo plano y enviarlo por correo # solo si la API key es verificable. Del otro lado siempre # respondemos con lo mismo. - def create + def create if (site&.airbrake_valid? airbrake_token) && !detected_device.bot? BacktraceJob.perform_later site_id: params[:site_id], - params: airbrake_params.to_h + params: airbrake_params.to_h end render status: 201, json: { id: 1, url: '' } @@ -23,7 +23,39 @@ module Api # XXX: Por alguna razón Airbrake envía los datos con Content-Type: # text/plain. def airbrake_params - @airbrake_params ||= params.merge!(FastJsonparser.parse(request.raw_post) || {}).permit! + @airbrake_params ||= + params.merge!(FastJsonparser.parse(request.raw_post) || {}) + .permit( + { + errors: [ + :type, + :message, + { backtrace: %i[file line column function] } + ] + }, + { + context: [ + :url, + :language, + :severity, + :userAgent, + :windowError, + :rootDirectory, + { + history: [ + :date, + :type, + :severity, + :target, + :method, + :duration, + :statusCode, + { arguments: [] } + ] + } + ] + } + ) end def site From 22bd58054a8f024c11344211c4506386bd7e1ec4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 18:14:21 -0300 Subject: [PATCH 294/814] fix: deprecar carga de archivo desde el sitio #14956 --- app/controllers/sites_controller.rb | 21 --------------------- app/models/post.rb | 4 +++- config/routes.rb | 3 --- 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index 17287eb0..bec42b39 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -110,27 +110,6 @@ class SitesController < ApplicationController redirect_to sites_path end - # Obtiene y streamea archivos estáticos desde el repositorio mismo, - # pero sólo los públicos (es decir los archivos subidos desde Sutty). - def static_file - authorize site - - file = params.require(:file) + '.' + params.require(:format) - - raise ActionController::RoutingError.new(nil, nil) unless file.start_with? 'public/' - - path = site.relative_path file - - raise ActionController::RoutingError.new(nil, nil) unless File.exist? path - - # TODO: Hacer esto usa recursos, pero menos que generar el sitio - # cada vez. Para poder usar X-Accel tendríamos que montar los - # repositorios en el servidor web, cosa que no queremos, o hacer - # links simbólicos desde todos los public, o usar un servidor web - # local que soporte sendfile mejor que Rails (nghttpd?) - send_file path - end - private def site diff --git a/app/models/post.rb b/app/models/post.rb index 9aa0ac61..8885897f 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -103,8 +103,10 @@ class Post src = element.attributes['src'] next unless src&.value&.start_with? 'public/' + file = MetadataFile.new(site: site, post: self, document: document, layout: layout) + file.value['path'] = src.value - src.value = Rails.application.routes.url_helpers.site_static_file_url(site, file: src.value) + src.value = Rails.application.routes.url_helpers.url_for(file.static_file) end # Notificar a les usuaries que están viendo una previsualización diff --git a/config/routes.rb b/config/routes.rb index f2487066..635be07a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,9 +28,6 @@ Rails.application.routes.draw do # alias en nginx sin tener que usar expresiones regulares para # detectar el nombre del sitio. get '/sites/private/:site_id(*file)', to: 'private#show', constraints: { site_id: %r{[^/]+} } - # Obtener archivos estáticos desde el directorio público - get '/sites/:site_id/static_file/(*file)', to: 'sites#static_file', as: 'site_static_file', - constraints: { site_id: %r{[^/]+} } get '/env.js', to: 'env#index' match '/api/v3/projects/:site_id/notices' => 'api/v1/notices#create', via: %i[post] From 1bed78345c6a478724fbb6a6525053fc62551d28 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 18:16:38 -0300 Subject: [PATCH 295/814] fix: ignorar alertas de brakeman MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * las redirecciones son necesarias para poder reenviar a las páginas de agradecimiento y no podemos saber la url de antemano. * Site.domain no es un atributo sino una configuración estática * Site#tienda_url es un atributo estático * no sabemos todos los parametros de antemano en los breadcrumbs --- config/brakeman.ignore | 252 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 config/brakeman.ignore diff --git a/config/brakeman.ignore b/config/brakeman.ignore new file mode 100644 index 00000000..137d2090 --- /dev/null +++ b/config/brakeman.ignore @@ -0,0 +1,252 @@ +{ + "ignored_warnings": [ + { + "warning_type": "Redirect", + "warning_code": 18, + "fingerprint": "0ae5c3990d49dfbfd4fd61874451f7a576d5056aca913068adf58c314625f810", + "check_name": "Redirect", + "message": "Possible unprotected redirect", + "file": "app/controllers/api/v1/posts_controller.rb", + "line": 20, + "link": "https://brakemanscanner.org/docs/warning_types/redirect/", + "code": "redirect_to((params[:redirect_to] or origin.to_s))", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V1::PostsController", + "method": "create" + }, + "user_input": "params[:redirect_to]", + "confidence": "High", + "cwe_id": [ + 601 + ], + "note": "" + }, + { + "warning_type": "Denial of Service", + "warning_code": 76, + "fingerprint": "1947d1a2ae6e4bf718d0cc563e660efca96897165e9a8dd18186c1d7abe6ddf6", + "check_name": "RegexDoS", + "message": "Model attribute used in regular expression", + "file": "app/controllers/api/v1/base_controller.rb", + "line": 20, + "link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/", + "code": "/\\.#{Site.domain}\\z/", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V1::BaseController", + "method": "site_id" + }, + "user_input": "Site.domain", + "confidence": "Medium", + "cwe_id": [ + 20, + 185 + ], + "note": "No es un atributo, es una variable de entorno" + }, + { + "warning_type": "Cross-Site Scripting", + "warning_code": 4, + "fingerprint": "28d98d08a15c4b3ad94a2cfa20a12573de12d99f1a30b3ca51074ee1f1886592", + "check_name": "LinkToHref", + "message": "Potentially unsafe model attribute in `link_to` href", + "file": "app/views/layouts/_breadcrumb.haml", + "line": 19, + "link": "https://brakemanscanner.org/docs/warning_types/link_to_href", + "code": "link_to(t(\".tienda\"), Site.find(params[:site_id]).tienda_url, :role => \"button\", :class => \"btn\")", + "render_path": [ + { + "type": "controller", + "class": "Api::V1::NoticesController", + "method": "site", + "line": 31, + "file": "app/controllers/api/v1/notices_controller.rb", + "rendered": { + "name": "layouts/application", + "file": "app/views/layouts/application.html.haml" + } + }, + { + "type": "template", + "name": "layouts/application", + "line": 25, + "file": "app/views/layouts/application.html.haml", + "rendered": { + "name": "layouts/_breadcrumb", + "file": "app/views/layouts/_breadcrumb.haml" + } + } + ], + "location": { + "type": "template", + "template": "layouts/_breadcrumb" + }, + "user_input": "Site.find(params[:site_id]).tienda_url", + "confidence": "Weak", + "cwe_id": [ + 79 + ], + "note": "" + }, + { + "warning_type": "Redirect", + "warning_code": 18, + "fingerprint": "5034e51aaa1bac06d15fdde5956edffbfd65f94f5620a409526bbea896dc7b5f", + "check_name": "Redirect", + "message": "Possible unprotected redirect", + "file": "app/controllers/api/v1/contact_controller.rb", + "line": 26, + "link": "https://brakemanscanner.org/docs/warning_types/redirect/", + "code": "redirect_to((params[:redirect] or origin.to_s))", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V1::ContactController", + "method": "receive" + }, + "user_input": "params[:redirect]", + "confidence": "High", + "cwe_id": [ + 601 + ], + "note": "" + }, + { + "warning_type": "Mass Assignment", + "warning_code": 70, + "fingerprint": "50582f39f8dfa900d3f2b5b9908b1592f8b8bd9e2d0b9d1cc05d77e5ede2d94e", + "check_name": "MassAssignment", + "message": "Specify exact keys allowed for mass assignment instead of using `permit!` which allows any keys", + "file": "app/views/layouts/_link_rel_alternate.haml", + "line": 2, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit!", + "render_path": [ + { + "type": "controller", + "class": "Api::V1::BaseController", + "method": "site_id", + "line": 20, + "file": "app/controllers/api/v1/base_controller.rb", + "rendered": { + "name": "layouts/application", + "file": "app/views/layouts/application.html.haml" + } + }, + { + "type": "template", + "name": "layouts/application", + "line": 21, + "file": "app/views/layouts/application.html.haml", + "rendered": { + "name": "layouts/_link_rel_alternate", + "file": "app/views/layouts/_link_rel_alternate.haml" + } + } + ], + "location": { + "type": "template", + "template": "layouts/_link_rel_alternate" + }, + "user_input": null, + "confidence": "Medium", + "cwe_id": [ + 915 + ], + "note": "" + }, + { + "warning_type": "Mass Assignment", + "warning_code": 70, + "fingerprint": "b8e0aa898288bebb614ccc1340d169caa196d315c6ac2e4744081cc892c2ae97", + "check_name": "MassAssignment", + "message": "Specify exact keys allowed for mass assignment instead of using `permit!` which allows any keys", + "file": "app/views/layouts/_breadcrumb.haml", + "line": 30, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit!", + "render_path": [ + { + "type": "controller", + "class": "Api::V1::BaseController", + "method": "site_id", + "line": 20, + "file": "app/controllers/api/v1/base_controller.rb", + "rendered": { + "name": "layouts/application", + "file": "app/views/layouts/application.html.haml" + } + }, + { + "type": "template", + "name": "layouts/application", + "line": 25, + "file": "app/views/layouts/application.html.haml", + "rendered": { + "name": "layouts/_breadcrumb", + "file": "app/views/layouts/_breadcrumb.haml" + } + } + ], + "location": { + "type": "template", + "template": "layouts/_breadcrumb" + }, + "user_input": null, + "confidence": "Medium", + "cwe_id": [ + 915 + ], + "note": "" + }, + { + "warning_type": "Cross-Site Scripting", + "warning_code": 4, + "fingerprint": "c051421c7cf4c2706b8e27bfd2f3b0661ec6a6df873da322a6b634b59e80351b", + "check_name": "LinkToHref", + "message": "Potentially unsafe model attribute in `link_to` href", + "file": "app/views/sites/_form.haml", + "line": 74, + "link": "https://brakemanscanner.org/docs/warning_types/link_to_href", + "code": "link_to(t(\".design.url\"), (Unresolved Model).new.url, :target => \"_blank\", :class => \"btn\")", + "render_path": [ + { + "type": "controller", + "class": "SitesController", + "method": "new", + "line": 31, + "file": "app/controllers/sites_controller.rb", + "rendered": { + "name": "sites/new", + "file": "app/views/sites/new.haml" + } + }, + { + "type": "template", + "name": "sites/new", + "line": 6, + "file": "app/views/sites/new.haml", + "rendered": { + "name": "sites/_form", + "file": "app/views/sites/_form.haml" + } + } + ], + "location": { + "type": "template", + "template": "sites/_form" + }, + "user_input": "(Unresolved Model).new.url", + "confidence": "Weak", + "cwe_id": [ + 79 + ], + "note": "" + } + ], + "updated": "2024-01-11 18:12:14 -0300", + "brakeman_version": "5.4.1" +} From eb2ce9d509fae9da45dd7147d9becc741f48393d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 18:31:55 -0300 Subject: [PATCH 296/814] chore: vincular a #14957 --- config/brakeman.ignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 137d2090..2388e4fb 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -21,7 +21,7 @@ "cwe_id": [ 601 ], - "note": "" + "note": "https://0xacab.org/sutty/sutty/-/issues/14957" }, { "warning_type": "Denial of Service", @@ -112,7 +112,7 @@ "cwe_id": [ 601 ], - "note": "" + "note": "https://0xacab.org/sutty/sutty/-/issues/14957" }, { "warning_type": "Mass Assignment", From 939d07430a2fad65d6a63159e4b3a64b710a3890 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 11 Jan 2024 18:33:30 -0300 Subject: [PATCH 297/814] chore: vincular a #14958 --- config/brakeman.ignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 2388e4fb..2f987772 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -156,7 +156,7 @@ "cwe_id": [ 915 ], - "note": "" + "note": "https://0xacab.org/sutty/sutty/-/issues/14958" }, { "warning_type": "Mass Assignment", @@ -200,7 +200,7 @@ "cwe_id": [ 915 ], - "note": "" + "note": "https://0xacab.org/sutty/sutty/-/issues/14958" }, { "warning_type": "Cross-Site Scripting", From f5e4376f1dc2edafc807c3b2b1d8e0fa46b77120 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 10:25:58 -0300 Subject: [PATCH 298/814] fix: no compilar assets en cronjobs --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fd67b54a..ddb8e5b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,6 +22,8 @@ assets: stage: "deploy" only: - "rails" + except: + - "schedules" cache: - *cache-ruby - *cache-node From bbc937419415a0fb97746a275b957690ccabb379 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 10:26:52 -0300 Subject: [PATCH 299/814] =?UTF-8?q?fix:=20compilar=20assets=20en=20el=20pa?= =?UTF-8?q?nel=20de=20producci=C3=B3n=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ddb8e5b6..2ce50d03 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,6 +22,7 @@ assets: stage: "deploy" only: - "rails" + - "17.3.alpine.panel.sutty.nl" except: - "schedules" cache: From f8a46d645980e5e580ddccb51eb3c2aade4af63d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 10:29:47 -0300 Subject: [PATCH 300/814] fix: instalar bundler audit --- .gitlab-ci.yml | 1 - Gemfile | 1 + Gemfile.lock | 6 +++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2ce50d03..cb2766d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,6 @@ gem-audit: cache: - *cache-ruby before_script: - - "gem install bundler-audit" - *apk-add - *disable-hainish script: diff --git a/Gemfile b/Gemfile index f97c29ab..466ec079 100644 --- a/Gemfile +++ b/Gemfile @@ -117,6 +117,7 @@ end group :development do gem 'yard' gem 'brakeman' + gem 'bundler-audit' gem 'haml-lint', require: false gem 'letter_opener' gem 'listen' diff --git a/Gemfile.lock b/Gemfile.lock index 5be5a103..78563c84 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,6 +106,9 @@ GEM sassc-rails (>= 2.0.0) brakeman (5.4.1) builder (3.2.4) + bundler-audit (0.9.1) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) capybara (2.18.0) addressable mini_mime (>= 0.1.3) @@ -536,7 +539,7 @@ GEM temple (0.10.1) terminal-table (2.0.0) unicode-display_width (~> 1.1, >= 1.1.1) - thor (1.2.2) + thor (1.3.0) tilt (2.1.0) timecop (0.9.6) timeout (0.3.2) @@ -586,6 +589,7 @@ DEPENDENCIES blazer bootstrap (~> 4) brakeman + bundler-audit capybara (~> 2.13) chartkick commonmarker From 56e4684ef1bd937e5fc6bf9f599257206e77d5bf Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 14:11:29 -0300 Subject: [PATCH 301/814] fix: todos los botones son secundarios closes #14967 --- app/assets/stylesheets/application.scss | 11 +---- app/assets/stylesheets/dark.scss | 19 +++++++++ app/views/collaborations/collaborate.haml | 2 +- app/views/devise/confirmations/new.haml | 2 +- app/views/devise/invitations/edit.haml | 2 +- app/views/devise/invitations/new.haml | 2 +- app/views/devise/passwords/edit.haml | 2 +- app/views/devise/passwords/new.haml | 2 +- app/views/devise/registrations/edit.haml | 4 +- app/views/devise/registrations/new.haml | 2 +- app/views/devise/sessions/new.haml | 2 +- app/views/devise/unlocks/new.haml | 2 +- app/views/i18n/_form.haml | 10 ++--- app/views/layouts/_breadcrumb.haml | 6 +-- app/views/layouts/_btn_with_tooltip.haml | 2 +- app/views/posts/_submit.haml | 2 +- app/views/posts/attributes/_content.haml | 50 +++++++++++------------ app/views/posts/edit.haml | 5 ++- app/views/posts/index.haml | 30 +++++++------- app/views/posts/show.haml | 2 +- app/views/sites/_build.haml | 2 +- app/views/sites/_form.haml | 8 ++-- app/views/sites/fetch.haml | 2 +- app/views/sites/index.haml | 8 ++-- app/views/stats/index.haml | 6 +-- app/views/usuaries/index.haml | 10 ++--- app/views/usuaries/invite.haml | 2 +- 27 files changed, 106 insertions(+), 91 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 23e4a899..7f62e658 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -29,11 +29,6 @@ $sizes: ( "70ch": 70ch, ); -.btn { - background-color: var(--foreground); - color: var(--background); -} - @import "bootstrap"; @import "editor"; @@ -195,7 +190,7 @@ fieldset { &[type=button] { @extend .btn; - @extend .btn-info; + @extend .btn-secondary; @extend .m-0; } } @@ -209,8 +204,6 @@ svg { } .btn { - border: none; - border-radius: 0; margin-right: 0.3rem; margin-bottom: 0.3rem; @@ -246,7 +239,7 @@ svg { color: $magenta; } - .btn { + .btn-secondary { background-color: $white; color: $black; border: none; diff --git a/app/assets/stylesheets/dark.scss b/app/assets/stylesheets/dark.scss index 9893c70b..59e15180 100644 --- a/app/assets/stylesheets/dark.scss +++ b/app/assets/stylesheets/dark.scss @@ -7,3 +7,22 @@ $cyan: #13fefe; --background: #{$black}; --color: #{$cyan}; } + +.btn-secondary { + background-color: $white; + color: $black; + border: none; + + &:hover { + color: $black; + background-color: $cyan; + } + + &:active { + background-color: $cyan; + } + + &:focus { + box-shadow: 0 0 0 0.2rem $cyan; + } +} diff --git a/app/views/collaborations/collaborate.haml b/app/views/collaborations/collaborate.haml index 4d43ad7e..cc951b0c 100644 --- a/app/views/collaborations/collaborate.haml +++ b/app/views/collaborations/collaborate.haml @@ -25,4 +25,4 @@ class: 'form-control' .form-group - = f.submit t('.submit'), class: 'btn btn-lg btn-block' + = f.submit t('.submit'), class: 'btn btn-secondary btn-lg btn-block' diff --git a/app/views/devise/confirmations/new.haml b/app/views/devise/confirmations/new.haml index bc2f77bb..c934edc5 100644 --- a/app/views/devise/confirmations/new.haml +++ b/app/views/devise/confirmations/new.haml @@ -30,5 +30,5 @@ placeholder: t('activerecord.attributes.usuarie.email') .actions = f.submit t('.resend_confirmation_instructions'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' = render 'devise/shared/links' diff --git a/app/views/devise/invitations/edit.haml b/app/views/devise/invitations/edit.haml index ed4980ef..3d2f8d76 100644 --- a/app/views/devise/invitations/edit.haml +++ b/app/views/devise/invitations/edit.haml @@ -32,4 +32,4 @@ placeholder: t('activerecord.attributes.usuarie.password') .actions = f.submit t('devise.invitations.edit.submit_button'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' diff --git a/app/views/devise/invitations/new.haml b/app/views/devise/invitations/new.haml index 4ebb8fa7..b8b097d0 100644 --- a/app/views/devise/invitations/new.haml +++ b/app/views/devise/invitations/new.haml @@ -16,4 +16,4 @@ = f.text_field field, class: 'form-control' .actions = f.submit t('devise.invitations.new.submit_button'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' diff --git a/app/views/devise/passwords/edit.haml b/app/views/devise/passwords/edit.haml index 3a8843c0..cd8ab8ad 100644 --- a/app/views/devise/passwords/edit.haml +++ b/app/views/devise/passwords/edit.haml @@ -39,6 +39,6 @@ .actions = f.submit t('.change_my_password'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' = render 'devise/shared/links' diff --git a/app/views/devise/passwords/new.haml b/app/views/devise/passwords/new.haml index 08dd8d2e..4bf7c990 100644 --- a/app/views/devise/passwords/new.haml +++ b/app/views/devise/passwords/new.haml @@ -20,5 +20,5 @@ placeholder: t('activerecord.attributes.usuarie.email') .actions = f.submit t('.send_me_reset_password_instructions'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' = render 'devise/shared/links' diff --git a/app/views/devise/registrations/edit.haml b/app/views/devise/registrations/edit.haml index 92699ab8..8bdc55d9 100644 --- a/app/views/devise/registrations/edit.haml +++ b/app/views/devise/registrations/edit.haml @@ -55,7 +55,7 @@ = t('.we_need_your_current_password_to_confirm_your_changes') .actions = f.submit t('.update'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' %hr/ .sr-only @@ -63,4 +63,4 @@ = button_to t('.cancel_my_account'), registration_path(resource_name), data: { confirm: t('.are_you_sure') }, - method: :delete, class: 'btn btn-block' + method: :delete, class: 'btn btn-secondary btn-block' diff --git a/app/views/devise/registrations/new.haml b/app/views/devise/registrations/new.haml index 26fc8e18..aabc0487 100644 --- a/app/views/devise/registrations/new.haml +++ b/app/views/devise/registrations/new.haml @@ -56,6 +56,6 @@ .actions = f.submit t('.sign_up'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' = render 'devise/shared/links' diff --git a/app/views/devise/sessions/new.haml b/app/views/devise/sessions/new.haml index 9b396187..03c3974b 100644 --- a/app/views/devise/sessions/new.haml +++ b/app/views/devise/sessions/new.haml @@ -35,5 +35,5 @@ remember_for: distance_of_time_in_words(Usuarie.remember_for)) .actions = f.submit t('.sign_in'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' = render 'devise/shared/links' diff --git a/app/views/devise/unlocks/new.haml b/app/views/devise/unlocks/new.haml index 09468a52..34253f44 100644 --- a/app/views/devise/unlocks/new.haml +++ b/app/views/devise/unlocks/new.haml @@ -20,5 +20,5 @@ placeholder: t('activerecord.attributes.usuarie.email') .actions = f.submit t('.resend_unlock_instructions'), - class: 'btn btn-lg btn-block' + class: 'btn btn-secondary btn-lg btn-block' = render 'devise/shared/links' diff --git a/app/views/i18n/_form.haml b/app/views/i18n/_form.haml index c88e8616..31b76932 100644 --- a/app/views/i18n/_form.haml +++ b/app/views/i18n/_form.haml @@ -11,7 +11,7 @@ = select_tag 'to', options_for_select(@options, @lang_to), class: 'form-control' - = submit_tag t('i18n.translate'), class: 'btn', name: nil + = submit_tag t('i18n.translate'), class: 'btn btn-secondary', name: nil - else = t('i18n.translating.from') = select_tag 'from', @@ -21,7 +21,7 @@ = select_tag 'to', options_for_select(@options, @lang_to), class: 'form-control' - = submit_tag t('i18n.change'), class: 'btn', name: nil + = submit_tag t('i18n.change'), class: 'btn btn-secondary', name: nil = render 'layouts/help', help: t('help.i18n.index') @@ -33,16 +33,16 @@ = hidden_field 'i18n', 'lang_to', value: @lang_to .form-group .dropdown.inline - %button.btn.dropdown-toggle{type: 'button', + %button.btn.btn-secondary.dropdown-toggle{type: 'button', data: { toggle: 'dropdown' }, aria: { haspopup: 'true', expanded: 'false' }} = t('i18n.jump') .dropdown-menu{aria: { labelledby: t('i18n.jump') }} - @site.data.dig(@lang_from).each_pair do |section, content| %a.dropdown-item{href: "##{section}"}= t("help.i18n.#{section}") - = submit_tag t('i18n.save'), class: 'btn' + = submit_tag t('i18n.save'), class: 'btn btn-secondary' = render 'i18n/recursive', data: @site.data.dig(@lang_from), superkeys: [] .form-group - = submit_tag t('i18n.save'), class: 'btn' + = submit_tag t('i18n.save'), class: 'btn btn-secondary' diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index 11f7f005..137f086e 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -17,15 +17,15 @@ - if @site&.tienda? %li.nav-item = link_to t('.tienda'), @site.tienda_url, - role: 'button', class: 'btn' + role: 'button', class: 'btn btn-secondary' %li.nav-item = link_to t('.contact_us'), t('.contact_us_href'), - class: 'btn', rel: 'me', target: '_blank' + class: 'btn btn-secondary', rel: 'me', target: '_blank' %li.nav-item = link_to t('.logout'), main_app.destroy_usuarie_session_path, - method: :delete, role: 'button', class: 'btn' + method: :delete, role: 'button', class: 'btn btn-secondary' - else - params.permit! - I18n.available_locales.each do |locale| diff --git a/app/views/layouts/_btn_with_tooltip.haml b/app/views/layouts/_btn_with_tooltip.haml index 27eda3c1..9651eae0 100644 --- a/app/views/layouts/_btn_with_tooltip.haml +++ b/app/views/layouts/_btn_with_tooltip.haml @@ -1,2 +1,2 @@ -= link_to text, link, class: 'btn', += link_to text, link, class: 'btn btn-secondary', data: { toggle: 'tooltip' }, 'aria-role': 'button', title: tooltip diff --git a/app/views/posts/_submit.haml b/app/views/posts/_submit.haml index 944694c1..c6c0a68a 100644 --- a/app/views/posts/_submit.haml +++ b/app/views/posts/_submit.haml @@ -1,7 +1,7 @@ - invalid_help = site.config.fetch('invalid_help', t('.invalid_help')) - sending_help = site.config.fetch('sending_help', t('.sending_help')) .form-group - = submit_tag t('.save'), class: 'btn submit-post' + = submit_tag t('.save'), class: 'btn btn-secondary submit-post' = render 'bootstrap/alert', class: 'invalid-help d-none' do = invalid_help = render 'bootstrap/alert', class: 'sending-help d-none' do diff --git a/app/views/posts/attributes/_content.haml b/app/views/posts/attributes/_content.haml index 03867941..872422af 100644 --- a/app/views/posts/attributes/_content.haml +++ b/app/views/posts/attributes/_content.haml @@ -20,82 +20,82 @@ TODO: Eliminar todo el espacio en blanco para minificar HTML .editor-toolbar{ style: 'z-index: 1' } .editor-primary-toolbar.scrollbar-black - %button.btn{ type: 'button', title: t('editor.multimedia'), data: { editor_button: 'multimedia' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.multimedia'), data: { editor_button: 'multimedia' } }> %i.fa.fa-fw.fa-upload> %span.sr-only>= t('editor.multimedia') - %button.btn{ type: 'button', title: t('editor.bold'), data: { editor_button: 'mark-bold' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.bold'), data: { editor_button: 'mark-bold' } }> %i.fa.fa-fw.fa-bold> %span.sr-only>= t('editor.bold') - %button.btn{ type: 'button', title: t('editor.italic'), data: { editor_button: 'mark-italic' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.italic'), data: { editor_button: 'mark-italic' } }> %i.fa.fa-fw.fa-italic> %span.sr-only>= t('editor.italic') - %button.btn{ type: 'button', title: t('editor.mark'), data: { editor_button: 'mark-mark' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.mark'), data: { editor_button: 'mark-mark' } }> %i.fa.fa-fw.fa-tint> %span.sr-only>= t('editor.mark') - %button.btn{ type: 'button', title: t('editor.link'), data: { editor_button: 'mark-link' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.link'), data: { editor_button: 'mark-link' } }> %i.fa.fa-fw.fa-link> %span.sr-only>= t('editor.link') - %button.btn{ type: 'button', title: t('editor.deleted'), data: { editor_button: 'mark-deleted' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.deleted'), data: { editor_button: 'mark-deleted' } }> %i.fa.fa-fw.fa-strikethrough> %span.sr-only>= t('editor.deleted') - %button.btn{ type: 'button', title: t('editor.underline'), data: { editor_button: 'mark-underline' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.underline'), data: { editor_button: 'mark-underline' } }> %i.fa.fa-fw.fa-underline> %span.sr-only>= t('editor.underline') - %button.btn{ type: 'button', title: t('editor.super'), data: { editor_button: 'mark-super' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.super'), data: { editor_button: 'mark-super' } }> %i.fa.fa-fw.fa-superscript> %span.sr-only>= t('editor.super') - %button.btn{ type: 'button', title: t('editor.sub'), data: { editor_button: 'mark-sub' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.sub'), data: { editor_button: 'mark-sub' } }> %i.fa.fa-fw.fa-subscript> %span.sr-only>= t('editor.sub') - %button.btn{ type: 'button', title: t('editor.small'), data: { editor_button: 'mark-small' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.small'), data: { editor_button: 'mark-small' } }> %i.fa.fa-fw.fa-subscript> %span.sr-only>= t('editor.small') - %button.btn.mr-0{ type: 'button', title: t('editor.h1'), data: { editor_button: 'block-h1' } }> + %button.btn.btn-secondary.mr-0{ type: 'button', title: t('editor.h1'), data: { editor_button: 'block-h1' } }> %i.fa.fa-fw.fa-heading> 1 %span.sr-only>= t('editor.h1') %details.d-inline> %summary.d-inline> - %span.btn.ml-0{ role: 'button', title: t('editor.more') }> + %span.btn.btn-secondary.ml-0{ role: 'button', title: t('editor.more') }> %i.fa.fa-caret-right> %span.sr-only= t('editor.more') .d-inline> - %button.btn{ type: 'button', title: t('editor.h2'), data: { editor_button: 'block-h2' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.h2'), data: { editor_button: 'block-h2' } }> %i.fa.fa-fw.fa-heading> 2 %span.sr-only>= t('editor.h2') - %button.btn{ type: 'button', title: t('editor.h3'), data: { editor_button: 'block-h3' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.h3'), data: { editor_button: 'block-h3' } }> %i.fa.fa-fw.fa-heading> 3 %span.sr-only>= t('editor.h3') - %button.btn{ type: 'button', title: t('editor.h4'), data: { editor_button: 'block-h4' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.h4'), data: { editor_button: 'block-h4' } }> %i.fa.fa-fw.fa-heading> 4 %span.sr-only>= t('editor.h4') - %button.btn{ type: 'button', title: t('editor.h5'), data: { editor_button: 'block-h5' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.h5'), data: { editor_button: 'block-h5' } }> %i.fa.fa-fw.fa-heading> 5 %span.sr-only>= t('editor.h5') - %button.btn{ type: 'button', title: t('editor.h6'), data: { editor_button: 'block-h6' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.h6'), data: { editor_button: 'block-h6' } }> %i.fa.fa-fw.fa-heading> 6 %span.sr-only>= t('editor.h6') - %button.btn{ type: 'button', title: t('editor.ul'), data: { editor_button: 'block-unordered_list' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.ul'), data: { editor_button: 'block-unordered_list' } }> %i.fa.fa-fw.fa-list-ul> %span.sr-only>= t('editor.ul') - %button.btn{ type: 'button', title: t('editor.ol'), data: { editor_button: 'block-ordered_list' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.ol'), data: { editor_button: 'block-ordered_list' } }> %i.fa.fa-fw.fa-list-ol> %span.sr-only>= t('editor.ol') - %button.btn{ type: 'button', title: t('editor.left'), data: { editor_button: 'parentBlock-left' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.left'), data: { editor_button: 'parentBlock-left' } }> %i.fa.fa-fw.fa-align-left> %span.sr-only>= t('editor.left') - %button.btn{ type: 'button', title: t('editor.center'), data: { editor_button: 'parentBlock-center' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.center'), data: { editor_button: 'parentBlock-center' } }> %i.fa.fa-fw.fa-align-center> %span.sr-only>= t('editor.center') - %button.btn{ type: 'button', title: t('editor.right'), data: { editor_button: 'parentBlock-right' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.right'), data: { editor_button: 'parentBlock-right' } }> %i.fa.fa-fw.fa-align-right> %span.sr-only>= t('editor.right') - %button.btn{ type: 'button', title: t('editor.blockquote'), data: { editor_button: 'block-blockquote' } }> + %button.btn.btn-secondary{ type: 'button', title: t('editor.blockquote'), data: { editor_button: 'block-blockquote' } }> %i.fa.fa-fw.fa-quote-left> %span.sr-only>= t('editor.blockquote') @@ -116,8 +116,8 @@ %label{ for: 'multimedia-alt' }= t('editor.description') %input.form-control{ type: 'text', id: 'multimedia-alt', name: 'multimedia-alt' }/ .form-group - %button.btn{ type: 'button', id: 'multimedia-file-upload', name: 'multimedia-file-upload' }= t('editor.multimedia-upload') - %button.btn{ type: 'button', id: 'multimedia-remove', name: 'multimedia-remove' }= t('editor.multimedia-remove') + %button.btn.btn-secondary{ type: 'button', id: 'multimedia-file-upload', name: 'multimedia-file-upload' }= t('editor.multimedia-upload') + %button.btn.btn-secondary{ type: 'button', id: 'multimedia-remove', name: 'multimedia-remove' }= t('editor.multimedia-remove') .form-group{ data: { editor_auxiliary: 'link' } } %label{ for: 'link-url' }= t('editor.url') diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 6ec252fe..c792ac93 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,3 +1,6 @@ .row.justify-content-center .col-md-8 - = render 'posts/form', site: @site, post: @post + = render 'layouts/details', summary: "Post" do + = render 'posts/form', site: @site, post: @post + = render 'layouts/details', summary: t('.moderation_queue') do + = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index ae53aa7a..374f06ee 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -15,13 +15,13 @@ = render 'schemas/row', site: @site, schema: schema, filter: @filter_params - if policy(@site_stat).index? - = link_to t('stats.index.title'), site_stats_path(@site), class: 'btn' + = link_to t('stats.index.title'), site_stats_path(@site), class: 'btn btn-secondary' - if policy(@site).edit? - = link_to t('sites.edit.btn', site: @site.title), edit_site_path(@site), class: 'btn' + = link_to t('sites.edit.btn', site: @site.title), edit_site_path(@site), class: 'btn btn-secondary' - if policy(@site).private? - = link_to t('sites.private'), '../private/' + @site.name, class: 'btn', target: '_blank', rel: 'noopener' + = link_to t('sites.private'), '../private/' + @site.name, class: 'btn btn-secondary', target: '_blank', rel: 'noopener' - if policy(SiteUsuarie.new(@site, current_usuarie)).index? = render 'layouts/btn_with_tooltip', @@ -33,9 +33,9 @@ - if @site.design.credits = render 'bootstrap/alert' do = sanitize_markdown @site.design.credits - = link_to t('sites.donations.text'), t('sites.donations.url'), class: 'btn' + = link_to t('sites.donations.text'), t('sites.donations.url'), class: 'btn btn-secondary' - if @site.design.designer_url - = link_to t('sites.designer_url'), @site.design.designer_url, class: 'btn' + = link_to t('sites.designer_url'), @site.design.designer_url, class: 'btn btn-secondary' %section.col .d-flex.justify-content-between.align-items-center.pl-2-plus.pr-2-plus.mb-2 @@ -75,19 +75,19 @@ %th.border-0{ colspan: '4' } .d-flex.flex-row.justify-content-between %div - = submit_tag t('posts.reorder.submit'), class: 'btn' - %button.btn{ data: { action: 'reorder#unselect' } } + = submit_tag t('posts.reorder.submit'), class: 'btn btn-secondary' + %button.btn.btn-secondary{ data: { action: 'reorder#unselect' } } = t('posts.reorder.unselect') %span.badge{ data: { target: 'reorder.counter' } } 0 - %button.btn{ data: { action: 'reorder#up' } }= t('posts.reorder.up') - %button.btn{ data: { action: 'reorder#down' } }= t('posts.reorder.down') - %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') - %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') + %button.btn.btn-secondary{ data: { action: 'reorder#up' } }= t('posts.reorder.up') + %button.btn.btn-secondary{ data: { action: 'reorder#down' } }= t('posts.reorder.down') + %button.btn.btn-secondary{ data: { action: 'reorder#top' } }= t('posts.reorder.top') + %button.btn.btn-secondary{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') - if @site.pagination %div - = link_to_prev_page @posts, t('posts.prev'), class: 'btn' - = link_to_next_page @posts, t('posts.next'), class: 'btn' + = link_to_prev_page @posts, t('posts.prev'), class: 'btn btn-secondary' + = link_to_next_page @posts, t('posts.next'), class: 'btn btn-secondary' %tbody - dir = @site.data.dig(params[:locale], 'dir') - size = @posts.size @@ -126,9 +126,9 @@ = post.order %td.text-nowrap - if @usuarie || policy(post).edit? - = link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-block' + = link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block' - if @usuarie || policy(post).destroy? - = link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') } + = link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-secondary btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') } #footnotes{ hidden: true } - @filter_params.each do |param, value| diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index 068a6adf..10900d67 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -4,7 +4,7 @@ %article.content.table-responsive-md = link_to t('posts.edit'), edit_site_post_path(@site, @post.id), - class: 'btn btn-block' + class: 'btn btn-secondary btn-block' %table.table.table-condensed %thead diff --git a/app/views/sites/_build.haml b/app/views/sites/_build.haml index 5911e908..b0961e31 100644 --- a/app/views/sites/_build.haml +++ b/app/views/sites/_build.haml @@ -3,7 +3,7 @@ method: :post, class: 'form-inline inline' do = submit_tag site.enqueued? ? t('sites.enqueued') : t('sites.enqueue'), - class: "btn no-border-radius #{local_assigns[:class]}", + class: "btn btn-secondary #{local_assigns[:class]}", title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'), data: { disable_with: t('sites.enqueued') }, disabled: site.enqueued? diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 0dcccbe3..ec2712bf 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -72,10 +72,10 @@ .btn-group{ role: 'group', 'aria-label': t('.design.actions') } - if design.url = link_to t('.design.url'), design.url, - target: '_blank', class: 'btn' + target: '_blank', class: 'btn btn-secondary' - if design.license = link_to t('.design.license'), design.license, - target: '_blank', class: 'btn' + target: '_blank', class: 'btn btn-secondary' %hr/ .form-group.licenses#license_id @@ -99,7 +99,7 @@ tags: %w[p a strong em ul ol li h1 h2 h3 h4 h5 h6] - unless licencia.custom? - = link_to t('.licencia.url'), licencia.url, target: '_blank', class: 'btn', rel: 'noopener' + = link_to t('.licencia.url'), licencia.url, target: '_blank', class: 'btn btn-secondary', rel: 'noopener' %hr/ @@ -163,4 +163,4 @@ deploy: deploy, site: site .form-group - = f.submit submit, class: 'btn btn-lg btn-block' + = f.submit submit, class: 'btn btn-secondary btn-lg btn-block' diff --git a/app/views/sites/fetch.haml b/app/views/sites/fetch.haml index f5d049c8..6d670d6f 100644 --- a/app/views/sites/fetch.haml +++ b/app/views/sites/fetch.haml @@ -27,4 +27,4 @@ .row.justify-content-center .col-md-8 = link_to t('.merge.request'), site_pull_path(@site), - method: 'post', class: 'btn btn-lg' + method: 'post', class: 'btn btn-secondary btn-lg' diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index b7231292..ed87180a 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -4,7 +4,7 @@ %p.lead= t('.help') - if policy(Site).new? = link_to t('sites.new.title'), new_site_path, - class: 'btn' + class: 'btn btn-secondary' %section.col - if @sites.empty? @@ -29,18 +29,18 @@ = site.title %p.lead= site.description %br - = link_to t('.visit'), site.url, class: 'btn' + = link_to t('.visit'), site.url, class: 'btn btn-secondary' - if rol.temporal = button_to t('sites.invitations.accept'), site_usuaries_accept_invitation_path(site), method: :patch, title: t('help.sites.invitations.accept'), - class: 'btn' + class: 'btn btn-secondary' = button_to t('sites.invitations.reject'), site_usuaries_reject_invitation_path(site), method: :patch, title: t('help.sites.invitations.reject'), - class: 'btn' + class: 'btn btn-secondary' - else - if policy(site).show? = render 'layouts/btn_with_tooltip', diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 88e86aa3..1c1a31f1 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -11,11 +11,11 @@ %form.mb-5.form-inline{ method: 'get' } - Stat::INTERVALS.each do |interval| - = link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls], period_start: params[:period_start].to_date.try(:"beginning_of_#{interval}").to_date, period_end: params[:period_end]), class: "mb-0 btn #{'btn-primary active' if @interval == interval}" + = link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls], period_start: params[:period_start].to_date.try(:"beginning_of_#{interval}").to_date, period_end: params[:period_end]), class: "mb-0 btn #{@interval == interval ? 'btn-primary active' : 'btn-secondary' }" %input.form-control{ type: 'date', name: :period_start, value: params[:period_start] } %input.form-control{ type: 'date', name: :period_end, value: params[:period_end] } - %button.btn.mb-0{ type: 'submit' }= t('.filter') + %button.btn.btn-secondary.mb-0{ type: 'submit' }= t('.filter') .mb-5 %h2= t('.host.title', count: @hostnames.size) @@ -34,7 +34,7 @@ %textarea#urls.form-control{ name: 'urls', autocomplete: 'on', required: true, rows: @normalized_urls.size + 1, aria_describedby: 'help-urls' }= @normalized_urls.join("\n") %small#help-urls.feedback.form-text.text-muted= t('.urls.help') .form-group - %button.btn{ type: 'submit' }= t('.urls.submit') + %button.btn.btn-secondary{ type: 'submit' }= t('.urls.submit') - if @normalized_urls.present? = line_chart site_stats_uris_path(urls: @normalized_urls, **@chart_params), **@chart_options diff --git a/app/views/usuaries/index.haml b/app/views/usuaries/index.haml index 124fb04b..f972a91f 100644 --- a/app/views/usuaries/index.haml +++ b/app/views/usuaries/index.haml @@ -9,13 +9,13 @@ - if @policy.invite? = link_to t('.invite'), site_usuaries_invite_path(@site, invite_as: u.to_s), - class: 'btn', + class: 'btn btn-secondary', data: { toggle: 'tooltip' }, title: t('.help.invite', invite_as: u.to_s) - if policy(Collaboration.new(@site)).collaborate? = link_to t('.public_invite'), site_collaborate_path(@site), - class: 'btn', + class: 'btn btn-secondary', data: { toggle: 'tooltip' }, title: t('.help.public_invite') %p.lead= t(".help.#{u}") @@ -38,7 +38,7 @@ - if @policy.demote? && @site.usuarie?(cuenta) = link_to t('.demote.text'), site_usuarie_demote_path(@site, cuenta), - class: 'btn', + class: 'btn btn-secondary', data: { toggle: 'tooltip', confirm: t('.demote.confirm') }, title: t('.help.demote'), @@ -46,7 +46,7 @@ - if @policy.promote? && @site.invitade?(cuenta) = link_to t('.promote.text'), site_usuarie_promote_path(@site, cuenta), - class: 'btn', + class: 'btn btn-secondary', data: { toggle: 'tooltip', confirm: t('.promote.confirm') }, title: t('.help.promote'), @@ -54,7 +54,7 @@ - if @policy.destroy? = link_to t('.destroy.text'), site_usuarie_path(@site, cuenta), - class: 'btn', + class: 'btn btn-secondary', data: { toggle: 'tooltip', confirm: t('.destroy.confirm') }, title: t('.help.destroy'), diff --git a/app/views/usuaries/invite.haml b/app/views/usuaries/invite.haml index 26eb5039..2698fb8f 100644 --- a/app/views/usuaries/invite.haml +++ b/app/views/usuaries/invite.haml @@ -13,4 +13,4 @@ invite_as: invite_as) = f.text_area :invitaciones, class: 'form-control' .form-group - = f.submit t('.submit'), class: 'btn' + = f.submit t('.submit'), class: 'btn btn-secondary' From 60fa25e5a86e8bcc5913d4f7a398f1db68055a91 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:09:08 -0300 Subject: [PATCH 302/814] fix: no fallar en File#touch --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 5fb7bcc3..8810f83b 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -578,7 +578,7 @@ class Site < ApplicationRecord if !gems_installed? || gemfile_updated? || gemfile_lock_updated? deploy_local.bundle touch - File.touch(gemfile_path) + ::File.touch(gemfile_path) end end From 29b0622ea873ab2d820fcdd0a94031863f70c989 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:09:27 -0300 Subject: [PATCH 303/814] =?UTF-8?q?fix:=20el=20m=C3=A9todo=20es=20p=C3=BAb?= =?UTF-8?q?lico=20para=20poder=20instalar=20gemas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #14964 --- app/models/deploy_local.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index ce4f858c..29a31f8c 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -7,6 +7,15 @@ class DeployLocal < Deploy before_destroy :remove_destination! + def bundle(output: false) + run %(bundle config set --local clean 'true'), output: output + run(%(bundle config set --local deployment 'true'), output: output) if site.gemfile_lock_path? + run %(bundle config set --local path '#{gems_dir}'), output: output + run %(bundle config set --local without 'test development'), output: output + run %(bundle config set --local cache_all 'false'), output: output + run %(bundle install), output: output + end + def git_lfs(output: false) run %(git lfs fetch), output: output run %(git lfs checkout), output: output @@ -129,15 +138,6 @@ class DeployLocal < Deploy run 'yarn install --production', output: output end - def bundle(output: false) - run %(bundle config set --local clean 'true'), output: output - run(%(bundle config set --local deployment 'true'), output: output) if site.gemfile_lock_path? - run %(bundle config set --local path '#{gems_dir}'), output: output - run %(bundle config set --local without 'test development'), output: output - run %(bundle config set --local cache_all 'false'), output: output - run %(bundle install), output: output - end - def jekyll_build(output: false) with_tempfile(site.private_key_pem) do |file| flags = extra_flags(private_key: file) From 4192e8b8f9272d2f80e88790c7350c078dcdef79 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:34:27 -0300 Subject: [PATCH 304/814] fix: cargar distributed press --- app/models/site/social_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 5d469f03..3be6404e 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -16,7 +16,7 @@ class Site # # @return [nil] def generate_private_key_pem! - self.private_key_pem ||= DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export + self.private_key_pem ||= ::DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export end end end From 5e6cbba28ef57e43ec7e1aeb547614cc96f22778 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:36:31 -0300 Subject: [PATCH 305/814] =?UTF-8?q?fix:=20prevenci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index 8810f83b..dd250e3d 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -159,19 +159,19 @@ class Site < ApplicationRecord # Traer la ruta del sitio def path - File.join(Site.site_path, name) + ::File.join(Site.site_path, name) end # La ruta anterior def path_was - File.join(Site.site_path, name_was) + ::File.join(Site.site_path, name_was) end # Limpiar la ruta y unirla con el separador de directorios del # sistema operativo. Como si algún día fuera a cambiar o # soportáramos Windows :P def relative_path(suspicious_path) - File.join(path, *suspicious_path.gsub('..', '/').gsub('./', '').squeeze('/').split('/')) + ::File.join(path, *suspicious_path.gsub('..', '/').gsub('./', '').squeeze('/').split('/')) end # Obtiene la lista de traducciones actuales @@ -358,7 +358,7 @@ class Site < ApplicationRecord end def jekyll? - File.directory? path + ::File.directory? path end def jekyll @@ -376,7 +376,7 @@ class Site < ApplicationRecord # documentos de Jekyll hacia Sutty para que podamos leer los datos que # necesitamos. def load_jekyll - return unless name.present? && File.directory?(path) + return unless name.present? && ::File.directory?(path) reload_jekyll! end @@ -404,7 +404,7 @@ class Site < ApplicationRecord # metadatos de Document @configuration = ::Jekyll.configuration('source' => path, - 'destination' => File.join(path, '_site'), + 'destination' => ::File.join(path, '_site'), 'safe' => true, 'watch' => false, 'quiet' => true, 'excerpt_separator' => '') @@ -429,7 +429,7 @@ class Site < ApplicationRecord # El directorio donde se almacenan los sitios def self.site_path - @site_path ||= File.realpath(ENV.fetch('SITE_PATH', Rails.root.join('_sites'))) + @site_path ||= ::File.realpath(ENV.fetch('SITE_PATH', Rails.root.join('_sites'))) end def self.default @@ -460,7 +460,7 @@ class Site < ApplicationRecord end def gemfile_lock_path? - File.exist? gemfile_lock_path + ::File.exist? gemfile_lock_path end private @@ -599,16 +599,16 @@ class Site < ApplicationRecord # Detecta si el Gemfile fue modificado def gemfile_updated? - updated_at < File.mtime(gemfile_path) + updated_at < ::File.mtime(gemfile_path) end def gemfile_path - @gemfile_path ||= File.join(path, 'Gemfile') + @gemfile_path ||= ::File.join(path, 'Gemfile') end # @return [String] def gemfile_lock_path - @gemfile_lock_path ||= File.join(path, 'Gemfile.lock') + @gemfile_lock_path ||= ::File.join(path, 'Gemfile.lock') end # Detecta si el Gemfile.lock fue modificado con respecto al sitio o al @@ -616,8 +616,8 @@ class Site < ApplicationRecord def gemfile_lock_updated? return false unless gemfile_lock_path? - [updated_at, File.mtime(File.join(path, 'Gemfile'))].any? do |compare| - compare < File.mtime(gemfile_lock_path) + [updated_at, ::File.mtime(::File.join(path, 'Gemfile'))].any? do |compare| + compare < ::File.mtime(gemfile_lock_path) end end end From 9ce510223e224017eb9337549f73f86bf1303faa Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:37:37 -0300 Subject: [PATCH 306/814] =?UTF-8?q?feat:=20controladores=20e=20informaci?= =?UTF-8?q?=C3=B3n=20de=20prueba=20#14966?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moderation_queue_controller.rb | 375 ++++++++++++++++++ app/controllers/posts_controller.rb | 72 ++++ config/routes.rb | 4 + 3 files changed, 451 insertions(+) create mode 100644 app/controllers/moderation_queue_controller.rb diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb new file mode 100644 index 00000000..1aef226f --- /dev/null +++ b/app/controllers/moderation_queue_controller.rb @@ -0,0 +1,375 @@ +# frozen_string_literal: true + +# Cola de moderación de ActivityPub +class ModerationQueueController < ApplicationController + # Cola de moderación viendo todo el sitio + def index + @moderation_queue = [ + +{"@context"=> + ["https://www.w3.org/ns/activitystreams", + {"ostatus"=>"http://ostatus.org#", + "atomUri"=>"ostatus:atomUri", + "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", + "conversation"=>"ostatus:conversation", + "sensitive"=>"as:sensitive", + "toot"=>"http://joinmastodon.org/ns#", + "votersCount"=>"toot:votersCount", + "Hashtag"=>"as:Hashtag"}], + "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "type"=>"Note", + "summary"=>nil, + "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "published"=>"2023-11-23T22:50:10Z", + "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", + "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], + "sensitive"=>false, + "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", + "content"=> + "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      ", + "contentMap"=> + {"en"=> + "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      "}, + "attachment"=>[], + "tag"=> + [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], + "replies"=> + {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "type"=>"Collection", + "first"=> + {"type"=>"CollectionPage", + "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", + "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "items"=>[]}}}, +{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], + "type"=>"Note", + "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", + "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "published"=>"2023-12-04T21:53:05+00:00", + "updated"=>"2023-12-05T20:41:34+00:00", + "attributedTo"=>"https://sutty.nl/about.jsonld", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], + "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", + "sensitive"=>true, + "content"=> + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", + "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "contentMap"=> + {"es"=> + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n"}, + "attachment"=> + [{"type"=>"Document", + "mediaType"=>"image/png", + "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", + "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} + + + ] + end + + # Perfil remoto de usuarie + def remote_profile + @remote_profile = { + '@context' => + [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', + 'toot' => 'http://joinmastodon.org/ns#', + 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, + 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' }, + 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' }, + 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' }, + 'schema' => 'http://schema.org#', + 'PropertyValue' => 'schema:PropertyValue', + 'value' => 'schema:value', + 'discoverable' => 'toot:discoverable', + 'Device' => 'toot:Device', + 'Ed25519Signature' => 'toot:Ed25519Signature', + 'Ed25519Key' => 'toot:Ed25519Key', + 'Curve25519Key' => 'toot:Curve25519Key', + 'EncryptedMessage' => 'toot:EncryptedMessage', + 'publicKeyBase64' => 'toot:publicKeyBase64', + 'deviceId' => 'toot:deviceId', + 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, + 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, + 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, + 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, + 'messageFranking' => 'toot:messageFranking', + 'messageType' => 'toot:messageType', + 'cipherText' => 'toot:cipherText', + 'suspended' => 'toot:suspended', + 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } + } + ], + 'id' => 'https://mastodon.mauve.moe/users/mauve', + 'type' => 'Person', + 'following' => 'https://mastodon.mauve.moe/users/mauve/following', + 'followers' => 'https://mastodon.mauve.moe/users/mauve/followers', + 'inbox' => 'https://mastodon.mauve.moe/users/mauve/inbox', + 'outbox' => 'https://mastodon.mauve.moe/users/mauve/outbox', + 'featured' => 'https://mastodon.mauve.moe/users/mauve/collections/featured', + 'featuredTags' => 'https://mastodon.mauve.moe/users/mauve/collections/tags', + 'preferredUsername' => 'mauve', + 'name' => 'Mauve 👁💜', + 'summary' => + '

      Occult Enby that's making local-first software with peer to peer protocols, mesh networks, and the web.

      Also exploring what a local-first cyberspace might look like in my spare time.

      ', + 'url' => 'https://mastodon.mauve.moe/@mauve', + 'manuallyApprovesFollowers' => false, + 'discoverable' => true, + 'published' => '2022-04-25T00:00:00Z', + 'devices' => 'https://mastodon.mauve.moe/users/mauve/collections/devices', + 'alsoKnownAs' => ['https://infosec.exchange/users/RangerMauve'], + 'publicKey' => + { 'id' => 'https://mastodon.mauve.moe/users/mauve#main-key', + 'owner' => 'https://mastodon.mauve.moe/users/mauve', + 'publicKeyPem' => + "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ\numIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng\n7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK\n75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq\nWUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D\nzAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf\nXwIDAQAB\n-----END PUBLIC KEY-----\n" }, + 'tag' => [], + 'attachment' => + [{ 'type' => 'PropertyValue', 'name' => 'Pronouns', 'value' => 'they/them/it' }, + { 'type' => 'PropertyValue', 'name' => 'Email', 'value' => 'mauve@mauve.moe' }, + { 'type' => 'PropertyValue', + 'name' => 'Matrix', + 'value' => + '@mauve:mauve.moe' }, + { 'type' => 'PropertyValue', 'name' => 'Github/Twitter', 'value' => '@RangerMauve' }], + 'endpoints' => { 'sharedInbox' => 'https://mastodon.mauve.moe/inbox' }, + 'icon' => + { 'type' => 'Image', + 'mediaType' => 'image/png', + 'url' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png' }, + 'image' => + { 'type' => 'Image', + 'mediaType' => 'image/png', + 'url' => 'https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png' } + } + end + + # todon.nl está usando /api/v2/instance + # mauve.moe usa /api/v1/instance + def instances + @instances = [ +{"domain"=>"todon.nl", + "title"=>"Todon.nl", + "version"=>"4.2.3", + "source_url"=>"https://github.com/mastodon/mastodon", + "description"=> + "Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.", + "usage"=>{"users"=>{"active_month"=>372}}, + "thumbnail"=> + {"url"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", + "blurhash"=>"UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE", + "versions"=> + {"@1x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", + "@2x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png"}}, + "languages"=>["en"], + "configuration"=> + {"urls"=>{"streaming"=>"wss://todon.nl", "status"=>"https://status.todon.eu"}, + "accounts"=>{"max_featured_tags"=>10}, + "statuses"=>{"max_characters"=>1312, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, + "media_attachments"=> + {"supported_mime_types"=> + ["image/jpeg", + "image/png", + "image/gif", + "image/heic", + "image/heif", + "image/webp", + "image/avif", + "video/webm", + "video/mp4", + "video/quicktime", + "video/ogg", + "audio/wave", + "audio/wav", + "audio/x-wav", + "audio/x-pn-wave", + "audio/vnd.wave", + "audio/ogg", + "audio/vorbis", + "audio/mpeg", + "audio/mp3", + "audio/webm", + "audio/flac", + "audio/aac", + "audio/m4a", + "audio/x-m4a", + "audio/mp4", + "audio/3gpp", + "video/x-ms-asf"], + "image_size_limit"=>16777216, + "image_matrix_limit"=>33177600, + "video_size_limit"=>103809024, + "video_frame_rate_limit"=>120, + "video_matrix_limit"=>8294400}, + "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}, + "translation"=>{"enabled"=>true}}, + "registrations"=> + {"enabled"=>false, + "approval_required"=>false, + "message"=> + "

      ¡No pasarán!

      \n\n

      Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

      \n\n\n\n

      Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

      \n\n

      It is temporary not possible to request on account on Todon.nl.

      \n\n\n\n

      Go to joinmastodon.org or FediDB Network to find another server.

      \n", + "url"=>nil}, + "max_toot_chars"=>1312, + "contact"=> + {"email"=>"todon@posteo.eu", + "account"=> + {"id"=>"1", + "username"=>"admin", + "acct"=>"admin", + "display_name"=>"Admin 🤓 Todon.nl (mod)", + "locked"=>false, + "bot"=>false, + "discoverable"=>false, + "group"=>false, + "created_at"=>"2017-04-28T00:00:00.000Z", + "note"=> + "

      This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

      🚫 Don't follow this account when you are not on Todon.nl.

      New? First read our 👩‍🏫 Todon 101 👩‍🎓 at https://wiki.todon.eu/todon/101

      ⚖️ For all our moderators go to https://wiki.todon.nl/todon/moderators

      📝 Public toots from this account are in English.

      🔕 Criticism is fine, but people who do false accusations are muted.

      ✉ todon@posteo.eu

      #nobot

      ", + "url"=>"https://todon.nl/@admin", + "uri"=>"https://todon.nl/users/admin", + "avatar"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", + "avatar_static"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", + "header"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", + "header_static"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", + "followers_count"=>3164, + "following_count"=>8, + "statuses_count"=>724, + "last_status_at"=>"2024-01-12", + "noindex"=>true, + "emojis"=>[], + "roles"=>[{"id"=>"3", "name"=>"Admin", "color"=>"#595aff"}], + "fields"=> + [{"name"=>"📜 Terms of Service", + "value"=> + "https://wiki.todon.nl/todon/terms_en", + "verified_at"=>"2018-11-01T14:39:45.465+00:00"}, + {"name"=>"ℹ️ Wiki", + "value"=> + "https://wiki.todon.nl/todon/information", + "verified_at"=>"2018-11-01T14:40:54.679+00:00"}, + {"name"=>"📊 Status", + "value"=> + "https://status.todon.eu", + "verified_at"=>"2023-10-26T20:38:30.185+00:00"}, + {"name"=>"💳️ Donations", + "value"=> + "https://wiki.todon.eu/todon/donations", + "verified_at"=>"2022-11-02T00:06:31.865+00:00"}]}}, + "rules"=> + [{"id"=>"1", + "text"=> + "We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition)."}, + {"id"=>"2", + "text"=> + "We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc."}, + {"id"=>"4", "text"=>"Sexism, misogyny and hate against black women (misogynoir)."}, + {"id"=>"6", "text"=>"We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming."}, + {"id"=>"8", "text"=>"We do not accept harassment and trolling."}, + {"id"=>"10", "text"=>"We also do not accept other forms of hate speech."}, + {"id"=>"11", "text"=>"We do not accept (sexual) abuse of minors, adults and animals (also not virtual)."}, + {"id"=>"13", "text"=>"We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism."}, + {"id"=>"15", + "text"=> + "We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service)."}, + {"id"=>"16", "text"=>"We do not accept fascism, right-wing populism, and right-wing and religious extremism."}, + {"id"=>"17", + "text"=>"We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults."}, + {"id"=>"19", + "text"=> + "We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies)."}, + {"id"=>"20", "text"=>"We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals."}, + {"id"=>"21", + "text"=> + "We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy)."}, + {"id"=>"27", "text"=>"We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation."}, + {"id"=>"28", "text"=>"Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step."}]}, +{"uri"=>"mastodon.mauve.moe", + "title"=>"Mauvestodon", + "short_description"=>"Escape ship from centralized social media run by Mauve.", + "description"=>"Chat about random techie and anarchist stuff.", + "email"=>"contact@mauve.moe", + "version"=>"3.5.10", + "urls"=>{"streaming_api"=>"wss://mastodon.mauve.moe"}, + "stats"=>{"user_count"=>12, "status_count"=>3287, "domain_count"=>11625}, + "thumbnail"=>"https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png", + "languages"=>["en"], + "registrations"=>false, + "approval_required"=>false, + "invites_enabled"=>true, + "configuration"=> + {"statuses"=>{"max_characters"=>500, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, + "media_attachments"=> + {"supported_mime_types"=> + ["image/jpeg", + "image/png", + "image/gif", + "video/webm", + "video/mp4", + "video/quicktime", + "video/ogg", + "audio/wave", + "audio/wav", + "audio/x-wav", + "audio/x-pn-wave", + "audio/ogg", + "audio/vorbis", + "audio/mpeg", + "audio/mp3", + "audio/webm", + "audio/flac", + "audio/aac", + "audio/m4a", + "audio/x-m4a", + "audio/mp4", + "audio/3gpp", + "video/x-ms-asf"], + "image_size_limit"=>10485760, + "image_matrix_limit"=>16777216, + "video_size_limit"=>41943040, + "video_frame_rate_limit"=>60, + "video_matrix_limit"=>2304000}, + "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}}, + "contact_account"=> + {"id"=>"1", + "username"=>"admin", + "acct"=>"admin", + "display_name"=>"", + "locked"=>false, + "bot"=>false, + "discoverable"=>true, + "group"=>false, + "created_at"=>"2022-04-25T00:00:00.000Z", + "note"=>"", + "url"=>"https://mastodon.mauve.moe/@admin", + "avatar"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", + "avatar_static"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", + "header"=>"https://mastodon.mauve.moe/headers/original/missing.png", + "header_static"=>"https://mastodon.mauve.moe/headers/original/missing.png", + "followers_count"=>0, + "following_count"=>0, + "statuses_count"=>0, + "last_status_at"=>"2023-01-30", + "emojis"=>[], + "fields"=> + [{"name"=>"Alternatel Contact", + "value"=> + "@mauve", + "verified_at"=>nil}]}, + "rules"=>[]} + + + + ] + + end +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 057c3068..8b4d975f 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -81,6 +81,78 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' + + @moderation_queue = [ + +{"@context"=> + ["https://www.w3.org/ns/activitystreams", + {"ostatus"=>"http://ostatus.org#", + "atomUri"=>"ostatus:atomUri", + "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", + "conversation"=>"ostatus:conversation", + "sensitive"=>"as:sensitive", + "toot"=>"http://joinmastodon.org/ns#", + "votersCount"=>"toot:votersCount", + "Hashtag"=>"as:Hashtag"}], + "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "type"=>"Note", + "summary"=>nil, + "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "published"=>"2023-11-23T22:50:10Z", + "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", + "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], + "sensitive"=>false, + "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", + "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", + "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", + "content"=> + "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      ", + "contentMap"=> + {"en"=> + "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      "}, + "attachment"=>[], + "tag"=> + [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, + {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], + "replies"=> + {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "type"=>"Collection", + "first"=> + {"type"=>"CollectionPage", + "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", + "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", + "items"=>[]}}}, +{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], + "type"=>"Note", + "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", + "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "published"=>"2023-12-04T21:53:05+00:00", + "updated"=>"2023-12-05T20:41:34+00:00", + "attributedTo"=>"https://sutty.nl/about.jsonld", + "to"=>["https://www.w3.org/ns/activitystreams#Public"], + "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], + "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", + "sensitive"=>true, + "content"=> + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", + "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", + "contentMap"=> + {"es"=> + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n"}, + "attachment"=> + [{"type"=>"Document", + "mediaType"=>"image/png", + "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", + "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} + + + ] + + end def update diff --git a/config/routes.rb b/config/routes.rb index 635be07a..664a4ab3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -50,6 +50,10 @@ Rails.application.routes.draw do get 'collaborate', to: 'collaborations#collaborate' post 'collaborate', to: 'collaborations#accept_collaboration' + get 'moderation_queue', to: 'moderation_queue#index' + get 'remote_profile', to: 'moderation_queue#remote_profile' + get 'instances', to: 'moderation_queue#instances' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From 6efae5f8f0448b68107e95092a15c8933c19c5b8 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:37:56 -0300 Subject: [PATCH 307/814] feat: correr rubocop y haml-lint sobre los archivos --- Taskfile.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index c2d72472..735724f5 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -183,3 +183,15 @@ tasks: - "{{.HAINISH}} gem install bundler-audit" status: - "test -f ../hain/usr/bin/bundler-audit" + rubocop: + desc: "Ruby linting. Call with: go-task rubocop -- -A file.rb" + cmds: + - task: "bundle" + vars: + CLI_ARGS: "exec rubocop {{.CLI_ARGS}}" + haml-lint: + desc: "HAML linting. Call with: go-task haml-lint -- file.haml" + cmds: + - task: "bundle" + vars: + CLI_ARGS: "exec haml-lint {{.CLI_ARGS}}" From e20ef9dd21b75896849ee2279fc2fa2fc3043a2a Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:44:26 -0300 Subject: [PATCH 308/814] feat: no es necesario pasar los archivos como parametros --- .gitlab-ci.yml | 4 ++-- Taskfile.yaml | 12 ++++-------- bin/modified_files | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb2766d3..9718e770 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -85,7 +85,7 @@ rubocop: - *apk-add - *disable-hainish script: - - "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop" + - "go-task rubocop" haml: stage: "test" cache: @@ -96,4 +96,4 @@ haml: - *apk-add - *disable-hainish script: - - "./bin/modified_files | ./bin/with_extension haml | xargs -r go-task bundle -- exec haml-lint" + - "go-task haml-lint" diff --git a/Taskfile.yaml b/Taskfile.yaml index 735724f5..57fb0238 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -184,14 +184,10 @@ tasks: status: - "test -f ../hain/usr/bin/bundler-audit" rubocop: - desc: "Ruby linting. Call with: go-task rubocop -- -A file.rb" + desc: "Ruby linting" cmds: - - task: "bundle" - vars: - CLI_ARGS: "exec rubocop {{.CLI_ARGS}}" + - "./bin/modified_files | ./bin/with_extension rb | xargs -r {{.HAINISH}} bundle exec rubocop {{.CLI_ARGS}}" haml-lint: - desc: "HAML linting. Call with: go-task haml-lint -- file.haml" + desc: "HAML linting" cmds: - - task: "bundle" - vars: - CLI_ARGS: "exec haml-lint {{.CLI_ARGS}}" + - "./bin/modified_files | ./bin/with_extension haml | xargs -r {{.HAINISH}} bundle exec haml-lint {{.CLI_ARGS}}" diff --git a/bin/modified_files b/bin/modified_files index d26e71f3..4d06b4c5 100755 --- a/bin/modified_files +++ b/bin/modified_files @@ -1,7 +1,7 @@ #!/bin/sh set -e -test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}" +CI_MERGE_REQUEST_DIFF_BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-origin/rails}" git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA} \ | grep -v "^D" \ From decbd2fb52a82f38dedf4e01f5e5d66075457115 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:44:49 -0300 Subject: [PATCH 309/814] chore: rubocop --- .../moderation_queue_controller.rb | 555 +++++++++--------- app/controllers/posts_controller.rb | 131 ++--- 2 files changed, 344 insertions(+), 342 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 1aef226f..6d58baf0 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,71 +6,70 @@ class ModerationQueueController < ApplicationController def index @moderation_queue = [ -{"@context"=> - ["https://www.w3.org/ns/activitystreams", - {"ostatus"=>"http://ostatus.org#", - "atomUri"=>"ostatus:atomUri", - "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", - "conversation"=>"ostatus:conversation", - "sensitive"=>"as:sensitive", - "toot"=>"http://joinmastodon.org/ns#", - "votersCount"=>"toot:votersCount", - "Hashtag"=>"as:Hashtag"}], - "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "type"=>"Note", - "summary"=>nil, - "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "published"=>"2023-11-23T22:50:10Z", - "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", - "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], - "sensitive"=>false, - "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", - "content"=> - "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      ", - "contentMap"=> - {"en"=> - "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      "}, - "attachment"=>[], - "tag"=> - [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], - "replies"=> - {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "type"=>"Collection", - "first"=> - {"type"=>"CollectionPage", - "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", - "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "items"=>[]}}}, -{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], - "type"=>"Note", - "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", - "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "published"=>"2023-12-04T21:53:05+00:00", - "updated"=>"2023-12-05T20:41:34+00:00", - "attributedTo"=>"https://sutty.nl/about.jsonld", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], - "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", - "sensitive"=>true, - "content"=> - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", - "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "contentMap"=> - {"es"=> - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n"}, - "attachment"=> - [{"type"=>"Document", - "mediaType"=>"image/png", - "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", - "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} - + { '@context' => + ['https://www.w3.org/ns/activitystreams', + { 'ostatus' => 'http://ostatus.org#', + 'atomUri' => 'ostatus:atomUri', + 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', + 'conversation' => 'ostatus:conversation', + 'sensitive' => 'as:sensitive', + 'toot' => 'http://joinmastodon.org/ns#', + 'votersCount' => 'toot:votersCount', + 'Hashtag' => 'as:Hashtag' }], + 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'type' => 'Note', + 'summary' => nil, + 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'published' => '2023-11-23T22:50:10Z', + 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', + 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], + 'sensitive' => false, + 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', + 'content' => + '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ', + 'contentMap' => + { 'en' => + '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ' }, + 'attachment' => [], + 'tag' => + [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], + 'replies' => + { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'type' => 'Collection', + 'first' => + { 'type' => 'CollectionPage', + 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', + 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'items' => [] } } }, + { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], + 'type' => 'Note', + 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', + 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'published' => '2023-12-04T21:53:05+00:00', + 'updated' => '2023-12-05T20:41:34+00:00', + 'attributedTo' => 'https://sutty.nl/about.jsonld', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], + 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', + 'sensitive' => true, + 'content' => + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", + 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'contentMap' => + { 'es' => + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n" }, + 'attachment' => + [{ 'type' => 'Document', + 'mediaType' => 'image/png', + 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', + 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } ] end @@ -159,217 +158,223 @@ class ModerationQueueController < ApplicationController # mauve.moe usa /api/v1/instance def instances @instances = [ -{"domain"=>"todon.nl", - "title"=>"Todon.nl", - "version"=>"4.2.3", - "source_url"=>"https://github.com/mastodon/mastodon", - "description"=> - "Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.", - "usage"=>{"users"=>{"active_month"=>372}}, - "thumbnail"=> - {"url"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", - "blurhash"=>"UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE", - "versions"=> - {"@1x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png", - "@2x"=>"https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png"}}, - "languages"=>["en"], - "configuration"=> - {"urls"=>{"streaming"=>"wss://todon.nl", "status"=>"https://status.todon.eu"}, - "accounts"=>{"max_featured_tags"=>10}, - "statuses"=>{"max_characters"=>1312, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, - "media_attachments"=> - {"supported_mime_types"=> - ["image/jpeg", - "image/png", - "image/gif", - "image/heic", - "image/heif", - "image/webp", - "image/avif", - "video/webm", - "video/mp4", - "video/quicktime", - "video/ogg", - "audio/wave", - "audio/wav", - "audio/x-wav", - "audio/x-pn-wave", - "audio/vnd.wave", - "audio/ogg", - "audio/vorbis", - "audio/mpeg", - "audio/mp3", - "audio/webm", - "audio/flac", - "audio/aac", - "audio/m4a", - "audio/x-m4a", - "audio/mp4", - "audio/3gpp", - "video/x-ms-asf"], - "image_size_limit"=>16777216, - "image_matrix_limit"=>33177600, - "video_size_limit"=>103809024, - "video_frame_rate_limit"=>120, - "video_matrix_limit"=>8294400}, - "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}, - "translation"=>{"enabled"=>true}}, - "registrations"=> - {"enabled"=>false, - "approval_required"=>false, - "message"=> - "

      ¡No pasarán!

      \n\n

      Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

      \n\n\n\n

      Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

      \n\n

      It is temporary not possible to request on account on Todon.nl.

      \n\n\n\n

      Go to joinmastodon.org or FediDB Network to find another server.

      \n", - "url"=>nil}, - "max_toot_chars"=>1312, - "contact"=> - {"email"=>"todon@posteo.eu", - "account"=> - {"id"=>"1", - "username"=>"admin", - "acct"=>"admin", - "display_name"=>"Admin 🤓 Todon.nl (mod)", - "locked"=>false, - "bot"=>false, - "discoverable"=>false, - "group"=>false, - "created_at"=>"2017-04-28T00:00:00.000Z", - "note"=> - "

      This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

      🚫 Don't follow this account when you are not on Todon.nl.

      New? First read our 👩‍🏫 Todon 101 👩‍🎓 at https://wiki.todon.eu/todon/101

      ⚖️ For all our moderators go to https://wiki.todon.nl/todon/moderators

      📝 Public toots from this account are in English.

      🔕 Criticism is fine, but people who do false accusations are muted.

      ✉ todon@posteo.eu

      #nobot

      ", - "url"=>"https://todon.nl/@admin", - "uri"=>"https://todon.nl/users/admin", - "avatar"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", - "avatar_static"=>"https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png", - "header"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", - "header_static"=>"https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png", - "followers_count"=>3164, - "following_count"=>8, - "statuses_count"=>724, - "last_status_at"=>"2024-01-12", - "noindex"=>true, - "emojis"=>[], - "roles"=>[{"id"=>"3", "name"=>"Admin", "color"=>"#595aff"}], - "fields"=> - [{"name"=>"📜 Terms of Service", - "value"=> - "https://wiki.todon.nl/todon/terms_en", - "verified_at"=>"2018-11-01T14:39:45.465+00:00"}, - {"name"=>"ℹ️ Wiki", - "value"=> - "https://wiki.todon.nl/todon/information", - "verified_at"=>"2018-11-01T14:40:54.679+00:00"}, - {"name"=>"📊 Status", - "value"=> - "https://status.todon.eu", - "verified_at"=>"2023-10-26T20:38:30.185+00:00"}, - {"name"=>"💳️ Donations", - "value"=> - "https://wiki.todon.eu/todon/donations", - "verified_at"=>"2022-11-02T00:06:31.865+00:00"}]}}, - "rules"=> - [{"id"=>"1", - "text"=> - "We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition)."}, - {"id"=>"2", - "text"=> - "We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc."}, - {"id"=>"4", "text"=>"Sexism, misogyny and hate against black women (misogynoir)."}, - {"id"=>"6", "text"=>"We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming."}, - {"id"=>"8", "text"=>"We do not accept harassment and trolling."}, - {"id"=>"10", "text"=>"We also do not accept other forms of hate speech."}, - {"id"=>"11", "text"=>"We do not accept (sexual) abuse of minors, adults and animals (also not virtual)."}, - {"id"=>"13", "text"=>"We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism."}, - {"id"=>"15", - "text"=> - "We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service)."}, - {"id"=>"16", "text"=>"We do not accept fascism, right-wing populism, and right-wing and religious extremism."}, - {"id"=>"17", - "text"=>"We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults."}, - {"id"=>"19", - "text"=> - "We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies)."}, - {"id"=>"20", "text"=>"We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals."}, - {"id"=>"21", - "text"=> - "We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy)."}, - {"id"=>"27", "text"=>"We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation."}, - {"id"=>"28", "text"=>"Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step."}]}, -{"uri"=>"mastodon.mauve.moe", - "title"=>"Mauvestodon", - "short_description"=>"Escape ship from centralized social media run by Mauve.", - "description"=>"Chat about random techie and anarchist stuff.", - "email"=>"contact@mauve.moe", - "version"=>"3.5.10", - "urls"=>{"streaming_api"=>"wss://mastodon.mauve.moe"}, - "stats"=>{"user_count"=>12, "status_count"=>3287, "domain_count"=>11625}, - "thumbnail"=>"https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png", - "languages"=>["en"], - "registrations"=>false, - "approval_required"=>false, - "invites_enabled"=>true, - "configuration"=> - {"statuses"=>{"max_characters"=>500, "max_media_attachments"=>4, "characters_reserved_per_url"=>23}, - "media_attachments"=> - {"supported_mime_types"=> - ["image/jpeg", - "image/png", - "image/gif", - "video/webm", - "video/mp4", - "video/quicktime", - "video/ogg", - "audio/wave", - "audio/wav", - "audio/x-wav", - "audio/x-pn-wave", - "audio/ogg", - "audio/vorbis", - "audio/mpeg", - "audio/mp3", - "audio/webm", - "audio/flac", - "audio/aac", - "audio/m4a", - "audio/x-m4a", - "audio/mp4", - "audio/3gpp", - "video/x-ms-asf"], - "image_size_limit"=>10485760, - "image_matrix_limit"=>16777216, - "video_size_limit"=>41943040, - "video_frame_rate_limit"=>60, - "video_matrix_limit"=>2304000}, - "polls"=>{"max_options"=>4, "max_characters_per_option"=>50, "min_expiration"=>300, "max_expiration"=>2629746}}, - "contact_account"=> - {"id"=>"1", - "username"=>"admin", - "acct"=>"admin", - "display_name"=>"", - "locked"=>false, - "bot"=>false, - "discoverable"=>true, - "group"=>false, - "created_at"=>"2022-04-25T00:00:00.000Z", - "note"=>"", - "url"=>"https://mastodon.mauve.moe/@admin", - "avatar"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", - "avatar_static"=>"https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png", - "header"=>"https://mastodon.mauve.moe/headers/original/missing.png", - "header_static"=>"https://mastodon.mauve.moe/headers/original/missing.png", - "followers_count"=>0, - "following_count"=>0, - "statuses_count"=>0, - "last_status_at"=>"2023-01-30", - "emojis"=>[], - "fields"=> - [{"name"=>"Alternatel Contact", - "value"=> - "@mauve", - "verified_at"=>nil}]}, - "rules"=>[]} - - + { 'domain' => 'todon.nl', + 'title' => 'Todon.nl', + 'version' => '4.2.3', + 'source_url' => 'https://github.com/mastodon/mastodon', + 'description' => + 'Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.', + 'usage' => { 'users' => { 'active_month' => 372 } }, + 'thumbnail' => + { 'url' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', + 'blurhash' => 'UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE', + 'versions' => + { '@1x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', + '@2x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png' } }, + 'languages' => ['en'], + 'configuration' => + { 'urls' => { 'streaming' => 'wss://todon.nl', 'status' => 'https://status.todon.eu' }, + 'accounts' => { 'max_featured_tags' => 10 }, + 'statuses' => { 'max_characters' => 1312, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, + 'media_attachments' => + { 'supported_mime_types' => + ['image/jpeg', + 'image/png', + 'image/gif', + 'image/heic', + 'image/heif', + 'image/webp', + 'image/avif', + 'video/webm', + 'video/mp4', + 'video/quicktime', + 'video/ogg', + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wave', + 'audio/vnd.wave', + 'audio/ogg', + 'audio/vorbis', + 'audio/mpeg', + 'audio/mp3', + 'audio/webm', + 'audio/flac', + 'audio/aac', + 'audio/m4a', + 'audio/x-m4a', + 'audio/mp4', + 'audio/3gpp', + 'video/x-ms-asf'], + 'image_size_limit' => 16_777_216, + 'image_matrix_limit' => 33_177_600, + 'video_size_limit' => 103_809_024, + 'video_frame_rate_limit' => 120, + 'video_matrix_limit' => 8_294_400 }, + 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, + 'max_expiration' => 2_629_746 }, + 'translation' => { 'enabled' => true } }, + 'registrations' => + { 'enabled' => false, + 'approval_required' => false, + 'message' => + "

      ¡No pasarán!

      \n\n

      Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

      \n\n\n\n

      Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

      \n\n

      It is temporary not possible to request on account on Todon.nl.

      \n\n\n\n

      Go to joinmastodon.org or FediDB Network to find another server.

      \n", + 'url' => nil }, + 'max_toot_chars' => 1312, + 'contact' => + { 'email' => 'todon@posteo.eu', + 'account' => + { 'id' => '1', + 'username' => 'admin', + 'acct' => 'admin', + 'display_name' => 'Admin 🤓 Todon.nl (mod)', + 'locked' => false, + 'bot' => false, + 'discoverable' => false, + 'group' => false, + 'created_at' => '2017-04-28T00:00:00.000Z', + 'note' => + '

      This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

      🚫 Don't follow this account when you are not on Todon.nl.

      New? First read our 👩‍🏫 Todon 101 👩‍🎓 at wiki.todon.eu/todon/101

      ⚖️ For all our moderators go to wiki.todon.nl/todon/moderators

      📝 Public toots from this account are in English.

      🔕 Criticism is fine, but people who do false accusations are muted.

      ✉ todon@posteo.eu

      ', + 'url' => 'https://todon.nl/@admin', + 'uri' => 'https://todon.nl/users/admin', + 'avatar' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', + 'avatar_static' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', + 'header' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', + 'header_static' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', + 'followers_count' => 3164, + 'following_count' => 8, + 'statuses_count' => 724, + 'last_status_at' => '2024-01-12', + 'noindex' => true, + 'emojis' => [], + 'roles' => [{ 'id' => '3', 'name' => 'Admin', 'color' => '#595aff' }], + 'fields' => + [{ 'name' => '📜 Terms of Service', + 'value' => + 'wiki.todon.nl/todon/terms_en', + 'verified_at' => '2018-11-01T14:39:45.465+00:00' }, + { 'name' => 'ℹ️ Wiki', + 'value' => + 'wiki.todon.nl/todon/informatio', + 'verified_at' => '2018-11-01T14:40:54.679+00:00' }, + { 'name' => '📊 Status', + 'value' => + 'status.todon.eu', + 'verified_at' => '2023-10-26T20:38:30.185+00:00' }, + { 'name' => '💳️ Donations', + 'value' => + 'wiki.todon.eu/todon/donations', + 'verified_at' => '2022-11-02T00:06:31.865+00:00' }] } }, + 'rules' => + [{ 'id' => '1', + 'text' => + 'We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition).' }, + { 'id' => '2', + 'text' => + 'We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc.' }, + { 'id' => '4', 'text' => 'Sexism, misogyny and hate against black women (misogynoir).' }, + { 'id' => '6', + 'text' => 'We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming.' }, + { 'id' => '8', 'text' => 'We do not accept harassment and trolling.' }, + { 'id' => '10', 'text' => 'We also do not accept other forms of hate speech.' }, + { 'id' => '11', + 'text' => 'We do not accept (sexual) abuse of minors, adults and animals (also not virtual).' }, + { 'id' => '13', + 'text' => 'We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism.' }, + { 'id' => '15', + 'text' => + 'We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service).' }, + { 'id' => '16', + 'text' => 'We do not accept fascism, right-wing populism, and right-wing and religious extremism.' }, + { 'id' => '17', + 'text' => 'We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults.' }, + { 'id' => '19', + 'text' => + 'We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies).' }, + { 'id' => '20', + 'text' => "We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals." }, + { 'id' => '21', + 'text' => + 'We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy).' }, + { 'id' => '27', + 'text' => "We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation." }, + { 'id' => '28', + 'text' => 'Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step.' }] }, + { 'uri' => 'mastodon.mauve.moe', + 'title' => 'Mauvestodon', + 'short_description' => 'Escape ship from centralized social media run by Mauve.', + 'description' => 'Chat about random techie and anarchist stuff.', + 'email' => 'contact@mauve.moe', + 'version' => '3.5.10', + 'urls' => { 'streaming_api' => 'wss://mastodon.mauve.moe' }, + 'stats' => { 'user_count' => 12, 'status_count' => 3287, 'domain_count' => 11_625 }, + 'thumbnail' => 'https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png', + 'languages' => ['en'], + 'registrations' => false, + 'approval_required' => false, + 'invites_enabled' => true, + 'configuration' => + { 'statuses' => { 'max_characters' => 500, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, + 'media_attachments' => + { 'supported_mime_types' => + ['image/jpeg', + 'image/png', + 'image/gif', + 'video/webm', + 'video/mp4', + 'video/quicktime', + 'video/ogg', + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wave', + 'audio/ogg', + 'audio/vorbis', + 'audio/mpeg', + 'audio/mp3', + 'audio/webm', + 'audio/flac', + 'audio/aac', + 'audio/m4a', + 'audio/x-m4a', + 'audio/mp4', + 'audio/3gpp', + 'video/x-ms-asf'], + 'image_size_limit' => 10_485_760, + 'image_matrix_limit' => 16_777_216, + 'video_size_limit' => 41_943_040, + 'video_frame_rate_limit' => 60, + 'video_matrix_limit' => 2_304_000 }, + 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, + 'max_expiration' => 2_629_746 } }, + 'contact_account' => + { 'id' => '1', + 'username' => 'admin', + 'acct' => 'admin', + 'display_name' => '', + 'locked' => false, + 'bot' => false, + 'discoverable' => true, + 'group' => false, + 'created_at' => '2022-04-25T00:00:00.000Z', + 'note' => '', + 'url' => 'https://mastodon.mauve.moe/@admin', + 'avatar' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', + 'avatar_static' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', + 'header' => 'https://mastodon.mauve.moe/headers/original/missing.png', + 'header_static' => 'https://mastodon.mauve.moe/headers/original/missing.png', + 'followers_count' => 0, + 'following_count' => 0, + 'statuses_count' => 0, + 'last_status_at' => '2023-01-30', + 'emojis' => [], + 'fields' => + [{ 'name' => 'Alternatel Contact', + 'value' => + '@mauve', + 'verified_at' => nil }] }, + 'rules' => [] } ] - end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 8b4d975f..1bc94ec1 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -84,75 +84,72 @@ class PostsController < ApplicationController @moderation_queue = [ -{"@context"=> - ["https://www.w3.org/ns/activitystreams", - {"ostatus"=>"http://ostatus.org#", - "atomUri"=>"ostatus:atomUri", - "inReplyToAtomUri"=>"ostatus:inReplyToAtomUri", - "conversation"=>"ostatus:conversation", - "sensitive"=>"as:sensitive", - "toot"=>"http://joinmastodon.org/ns#", - "votersCount"=>"toot:votersCount", - "Hashtag"=>"as:Hashtag"}], - "id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "type"=>"Note", - "summary"=>nil, - "inReplyTo"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "published"=>"2023-11-23T22:50:10Z", - "url"=>"https://mastodon.mauve.moe/@mauve/111462305634770041", - "attributedTo"=>"https://mastodon.mauve.moe/users/mauve", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://mastodon.mauve.moe/users/mauve/followers", "https://hypha.coop/about.jsonld"], - "sensitive"=>false, - "atomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041", - "inReplyToAtomUri"=>"https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886", - "conversation"=>"tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation", - "content"=> - "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      ", - "contentMap"=> - {"en"=> - "

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      #P2P #ActivityPub #Fediverse

      "}, - "attachment"=>[], - "tag"=> - [{"type"=>"Mention", "href"=>"https://hypha.coop/about.jsonld", "name"=>"@dripline@hypha.coop"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/p2p", "name"=>"#p2p"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/activitypub", "name"=>"#activitypub"}, - {"type"=>"Hashtag", "href"=>"https://mastodon.mauve.moe/tags/fediverse", "name"=>"#fediverse"}], - "replies"=> - {"id"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "type"=>"Collection", - "first"=> - {"type"=>"CollectionPage", - "next"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true", - "partOf"=>"https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies", - "items"=>[]}}}, -{"@context"=>["https://www.w3.org/ns/activitystreams", {"@language"=>"es", "sensitive"=>"as:sensitive"}], - "type"=>"Note", - "id"=>"https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/", - "summary"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "published"=>"2023-12-04T21:53:05+00:00", - "updated"=>"2023-12-05T20:41:34+00:00", - "attributedTo"=>"https://sutty.nl/about.jsonld", - "to"=>["https://www.w3.org/ns/activitystreams#Public"], - "cc"=>["https://social.distributed.press/v1/@sutty@sutty.nl/followers"], - "inReplyTo"=>"https://hypha.coop/dripline/announcing-dp-social-inbox/", - "sensitive"=>true, - "content"=> - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", - "name"=>"Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty", - "contentMap"=> - {"es"=> - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n"}, - "attachment"=> - [{"type"=>"Document", - "mediaType"=>"image/png", - "url"=>"https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png", - "name"=>"Botones de colores para activar la \"Web Disribuida\" y el \"Fediverso\"."}]} - + { '@context' => + ['https://www.w3.org/ns/activitystreams', + { 'ostatus' => 'http://ostatus.org#', + 'atomUri' => 'ostatus:atomUri', + 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', + 'conversation' => 'ostatus:conversation', + 'sensitive' => 'as:sensitive', + 'toot' => 'http://joinmastodon.org/ns#', + 'votersCount' => 'toot:votersCount', + 'Hashtag' => 'as:Hashtag' }], + 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'type' => 'Note', + 'summary' => nil, + 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'published' => '2023-11-23T22:50:10Z', + 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', + 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], + 'sensitive' => false, + 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', + 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', + 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', + 'content' => + '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ', + 'contentMap' => + { 'en' => + '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ' }, + 'attachment' => [], + 'tag' => + [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, + { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], + 'replies' => + { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'type' => 'Collection', + 'first' => + { 'type' => 'CollectionPage', + 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', + 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', + 'items' => [] } } }, + { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], + 'type' => 'Note', + 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', + 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'published' => '2023-12-04T21:53:05+00:00', + 'updated' => '2023-12-05T20:41:34+00:00', + 'attributedTo' => 'https://sutty.nl/about.jsonld', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], + 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', + 'sensitive' => true, + 'content' => + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", + 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', + 'contentMap' => + { 'es' => + "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n" }, + 'attachment' => + [{ 'type' => 'Document', + 'mediaType' => 'image/png', + 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', + 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } ] - - end def update From 2a2878e4696645aee6c22e2d9301cd69a614db39 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Jan 2024 17:55:15 -0300 Subject: [PATCH 310/814] =?UTF-8?q?refactor:=20cargar=20los=20datos=20desd?= =?UTF-8?q?e=20archivos=20m=C3=A1s=20legibles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moderation_queue_controller.rb | 366 +----------------- app/controllers/posts_controller.rb | 70 +--- db/seeds/instances.yaml | 285 ++++++++++++++ db/seeds/moderation_queue.yaml | 153 ++++++++ db/seeds/remote_profile.yaml | 106 +++++ 5 files changed, 548 insertions(+), 432 deletions(-) create mode 100644 db/seeds/instances.yaml create mode 100644 db/seeds/moderation_queue.yaml create mode 100644 db/seeds/remote_profile.yaml diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 6d58baf0..eb39dae6 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -4,377 +4,17 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index - @moderation_queue = [ - - { '@context' => - ['https://www.w3.org/ns/activitystreams', - { 'ostatus' => 'http://ostatus.org#', - 'atomUri' => 'ostatus:atomUri', - 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', - 'conversation' => 'ostatus:conversation', - 'sensitive' => 'as:sensitive', - 'toot' => 'http://joinmastodon.org/ns#', - 'votersCount' => 'toot:votersCount', - 'Hashtag' => 'as:Hashtag' }], - 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'type' => 'Note', - 'summary' => nil, - 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'published' => '2023-11-23T22:50:10Z', - 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', - 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], - 'sensitive' => false, - 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', - 'content' => - '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ', - 'contentMap' => - { 'en' => - '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ' }, - 'attachment' => [], - 'tag' => - [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], - 'replies' => - { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'type' => 'Collection', - 'first' => - { 'type' => 'CollectionPage', - 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', - 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'items' => [] } } }, - { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], - 'type' => 'Note', - 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', - 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'published' => '2023-12-04T21:53:05+00:00', - 'updated' => '2023-12-05T20:41:34+00:00', - 'attributedTo' => 'https://sutty.nl/about.jsonld', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], - 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', - 'sensitive' => true, - 'content' => - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", - 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'contentMap' => - { 'es' => - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n" }, - 'attachment' => - [{ 'type' => 'Document', - 'mediaType' => 'image/png', - 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', - 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } - - ] + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) end # Perfil remoto de usuarie def remote_profile - @remote_profile = { - '@context' => - [ - 'https://www.w3.org/ns/activitystreams', - 'https://w3id.org/security/v1', - { - 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', - 'toot' => 'http://joinmastodon.org/ns#', - 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, - 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' }, - 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' }, - 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' }, - 'schema' => 'http://schema.org#', - 'PropertyValue' => 'schema:PropertyValue', - 'value' => 'schema:value', - 'discoverable' => 'toot:discoverable', - 'Device' => 'toot:Device', - 'Ed25519Signature' => 'toot:Ed25519Signature', - 'Ed25519Key' => 'toot:Ed25519Key', - 'Curve25519Key' => 'toot:Curve25519Key', - 'EncryptedMessage' => 'toot:EncryptedMessage', - 'publicKeyBase64' => 'toot:publicKeyBase64', - 'deviceId' => 'toot:deviceId', - 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, - 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, - 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, - 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, - 'messageFranking' => 'toot:messageFranking', - 'messageType' => 'toot:messageType', - 'cipherText' => 'toot:cipherText', - 'suspended' => 'toot:suspended', - 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } - } - ], - 'id' => 'https://mastodon.mauve.moe/users/mauve', - 'type' => 'Person', - 'following' => 'https://mastodon.mauve.moe/users/mauve/following', - 'followers' => 'https://mastodon.mauve.moe/users/mauve/followers', - 'inbox' => 'https://mastodon.mauve.moe/users/mauve/inbox', - 'outbox' => 'https://mastodon.mauve.moe/users/mauve/outbox', - 'featured' => 'https://mastodon.mauve.moe/users/mauve/collections/featured', - 'featuredTags' => 'https://mastodon.mauve.moe/users/mauve/collections/tags', - 'preferredUsername' => 'mauve', - 'name' => 'Mauve 👁💜', - 'summary' => - '

      Occult Enby that's making local-first software with peer to peer protocols, mesh networks, and the web.

      Also exploring what a local-first cyberspace might look like in my spare time.

      ', - 'url' => 'https://mastodon.mauve.moe/@mauve', - 'manuallyApprovesFollowers' => false, - 'discoverable' => true, - 'published' => '2022-04-25T00:00:00Z', - 'devices' => 'https://mastodon.mauve.moe/users/mauve/collections/devices', - 'alsoKnownAs' => ['https://infosec.exchange/users/RangerMauve'], - 'publicKey' => - { 'id' => 'https://mastodon.mauve.moe/users/mauve#main-key', - 'owner' => 'https://mastodon.mauve.moe/users/mauve', - 'publicKeyPem' => - "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ\numIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng\n7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK\n75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq\nWUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D\nzAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf\nXwIDAQAB\n-----END PUBLIC KEY-----\n" }, - 'tag' => [], - 'attachment' => - [{ 'type' => 'PropertyValue', 'name' => 'Pronouns', 'value' => 'they/them/it' }, - { 'type' => 'PropertyValue', 'name' => 'Email', 'value' => 'mauve@mauve.moe' }, - { 'type' => 'PropertyValue', - 'name' => 'Matrix', - 'value' => - '@mauve:mauve.moe' }, - { 'type' => 'PropertyValue', 'name' => 'Github/Twitter', 'value' => '@RangerMauve' }], - 'endpoints' => { 'sharedInbox' => 'https://mastodon.mauve.moe/inbox' }, - 'icon' => - { 'type' => 'Image', - 'mediaType' => 'image/png', - 'url' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png' }, - 'image' => - { 'type' => 'Image', - 'mediaType' => 'image/png', - 'url' => 'https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png' } - } + @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) end # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances - @instances = [ - { 'domain' => 'todon.nl', - 'title' => 'Todon.nl', - 'version' => '4.2.3', - 'source_url' => 'https://github.com/mastodon/mastodon', - 'description' => - 'Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, intersectionelen, veganisten, mensenrechten, enz.', - 'usage' => { 'users' => { 'active_month' => 372 } }, - 'thumbnail' => - { 'url' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', - 'blurhash' => 'UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE', - 'versions' => - { '@1x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png', - '@2x' => 'https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png' } }, - 'languages' => ['en'], - 'configuration' => - { 'urls' => { 'streaming' => 'wss://todon.nl', 'status' => 'https://status.todon.eu' }, - 'accounts' => { 'max_featured_tags' => 10 }, - 'statuses' => { 'max_characters' => 1312, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, - 'media_attachments' => - { 'supported_mime_types' => - ['image/jpeg', - 'image/png', - 'image/gif', - 'image/heic', - 'image/heif', - 'image/webp', - 'image/avif', - 'video/webm', - 'video/mp4', - 'video/quicktime', - 'video/ogg', - 'audio/wave', - 'audio/wav', - 'audio/x-wav', - 'audio/x-pn-wave', - 'audio/vnd.wave', - 'audio/ogg', - 'audio/vorbis', - 'audio/mpeg', - 'audio/mp3', - 'audio/webm', - 'audio/flac', - 'audio/aac', - 'audio/m4a', - 'audio/x-m4a', - 'audio/mp4', - 'audio/3gpp', - 'video/x-ms-asf'], - 'image_size_limit' => 16_777_216, - 'image_matrix_limit' => 33_177_600, - 'video_size_limit' => 103_809_024, - 'video_frame_rate_limit' => 120, - 'video_matrix_limit' => 8_294_400 }, - 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, - 'max_expiration' => 2_629_746 }, - 'translation' => { 'enabled' => true } }, - 'registrations' => - { 'enabled' => false, - 'approval_required' => false, - 'message' => - "

      ¡No pasarán!

      \n\n

      Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

      \n\n\n\n

      Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

      \n\n

      It is temporary not possible to request on account on Todon.nl.

      \n\n\n\n

      Go to joinmastodon.org or FediDB Network to find another server.

      \n", - 'url' => nil }, - 'max_toot_chars' => 1312, - 'contact' => - { 'email' => 'todon@posteo.eu', - 'account' => - { 'id' => '1', - 'username' => 'admin', - 'acct' => 'admin', - 'display_name' => 'Admin 🤓 Todon.nl (mod)', - 'locked' => false, - 'bot' => false, - 'discoverable' => false, - 'group' => false, - 'created_at' => '2017-04-28T00:00:00.000Z', - 'note' => - '

      This account is used for 🎙 Todon.nl announcements and ⚖️ moderation.

      🚫 Don't follow this account when you are not on Todon.nl.

      New? First read our 👩‍🏫 Todon 101 👩‍🎓 at wiki.todon.eu/todon/101

      ⚖️ For all our moderators go to wiki.todon.nl/todon/moderators

      📝 Public toots from this account are in English.

      🔕 Criticism is fine, but people who do false accusations are muted.

      ✉ todon@posteo.eu

      ', - 'url' => 'https://todon.nl/@admin', - 'uri' => 'https://todon.nl/users/admin', - 'avatar' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', - 'avatar_static' => 'https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png', - 'header' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', - 'header_static' => 'https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png', - 'followers_count' => 3164, - 'following_count' => 8, - 'statuses_count' => 724, - 'last_status_at' => '2024-01-12', - 'noindex' => true, - 'emojis' => [], - 'roles' => [{ 'id' => '3', 'name' => 'Admin', 'color' => '#595aff' }], - 'fields' => - [{ 'name' => '📜 Terms of Service', - 'value' => - 'wiki.todon.nl/todon/terms_en', - 'verified_at' => '2018-11-01T14:39:45.465+00:00' }, - { 'name' => 'ℹ️ Wiki', - 'value' => - 'wiki.todon.nl/todon/informatio', - 'verified_at' => '2018-11-01T14:40:54.679+00:00' }, - { 'name' => '📊 Status', - 'value' => - 'status.todon.eu', - 'verified_at' => '2023-10-26T20:38:30.185+00:00' }, - { 'name' => '💳️ Donations', - 'value' => - 'wiki.todon.eu/todon/donations', - 'verified_at' => '2022-11-02T00:06:31.865+00:00' }] } }, - 'rules' => - [{ 'id' => '1', - 'text' => - 'We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, apartheid and casteism - see our Terms of Service for our complete definition).' }, - { 'id' => '2', - 'text' => - 'We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, non-binary people, intersexual people, queer people in general, etc.' }, - { 'id' => '4', 'text' => 'Sexism, misogyny and hate against black women (misogynoir).' }, - { 'id' => '6', - 'text' => 'We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) and body-shaming.' }, - { 'id' => '8', 'text' => 'We do not accept harassment and trolling.' }, - { 'id' => '10', 'text' => 'We also do not accept other forms of hate speech.' }, - { 'id' => '11', - 'text' => 'We do not accept (sexual) abuse of minors, adults and animals (also not virtual).' }, - { 'id' => '13', - 'text' => 'We do not accept glorification of violence, calls for murder, death threats, terrorism and militarism.' }, - { 'id' => '15', - 'text' => - 'We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms and nationalism (above all nationalism of nation states, incl. flags/symbols of those on Todon.*, see our Terms of Service).' }, - { 'id' => '16', - 'text' => 'We do not accept fascism, right-wing populism, and right-wing and religious extremism.' }, - { 'id' => '17', - 'text' => 'We do not accept evangelisation and other forms of religious propaganda [local only], and extreme sects and cults.' }, - { 'id' => '19', - 'text' => - 'We do not accept Marxist-Leninists, Stalinists, Maoists or other followers of extreme authoritarian (so called) communist/socialist ideologies/regimes (aka tankies).' }, - { 'id' => '20', - 'text' => "We do not accept capitalists, including so called 'anarcho-capitalists' (aka ancaps) and neoliberals." }, - { 'id' => '21', - 'text' => - 'We do not accept anthropogenic climate change denial, downplaying the climate crisis, greenwashing and deceptive climate solutions (like nuclear energy).' }, - { 'id' => '27', - 'text' => "We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and other forms of disinformation." }, - { 'id' => '28', - 'text' => 'Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain in the final step.' }] }, - { 'uri' => 'mastodon.mauve.moe', - 'title' => 'Mauvestodon', - 'short_description' => 'Escape ship from centralized social media run by Mauve.', - 'description' => 'Chat about random techie and anarchist stuff.', - 'email' => 'contact@mauve.moe', - 'version' => '3.5.10', - 'urls' => { 'streaming_api' => 'wss://mastodon.mauve.moe' }, - 'stats' => { 'user_count' => 12, 'status_count' => 3287, 'domain_count' => 11_625 }, - 'thumbnail' => 'https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png', - 'languages' => ['en'], - 'registrations' => false, - 'approval_required' => false, - 'invites_enabled' => true, - 'configuration' => - { 'statuses' => { 'max_characters' => 500, 'max_media_attachments' => 4, 'characters_reserved_per_url' => 23 }, - 'media_attachments' => - { 'supported_mime_types' => - ['image/jpeg', - 'image/png', - 'image/gif', - 'video/webm', - 'video/mp4', - 'video/quicktime', - 'video/ogg', - 'audio/wave', - 'audio/wav', - 'audio/x-wav', - 'audio/x-pn-wave', - 'audio/ogg', - 'audio/vorbis', - 'audio/mpeg', - 'audio/mp3', - 'audio/webm', - 'audio/flac', - 'audio/aac', - 'audio/m4a', - 'audio/x-m4a', - 'audio/mp4', - 'audio/3gpp', - 'video/x-ms-asf'], - 'image_size_limit' => 10_485_760, - 'image_matrix_limit' => 16_777_216, - 'video_size_limit' => 41_943_040, - 'video_frame_rate_limit' => 60, - 'video_matrix_limit' => 2_304_000 }, - 'polls' => { 'max_options' => 4, 'max_characters_per_option' => 50, 'min_expiration' => 300, - 'max_expiration' => 2_629_746 } }, - 'contact_account' => - { 'id' => '1', - 'username' => 'admin', - 'acct' => 'admin', - 'display_name' => '', - 'locked' => false, - 'bot' => false, - 'discoverable' => true, - 'group' => false, - 'created_at' => '2022-04-25T00:00:00.000Z', - 'note' => '', - 'url' => 'https://mastodon.mauve.moe/@admin', - 'avatar' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', - 'avatar_static' => 'https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png', - 'header' => 'https://mastodon.mauve.moe/headers/original/missing.png', - 'header_static' => 'https://mastodon.mauve.moe/headers/original/missing.png', - 'followers_count' => 0, - 'following_count' => 0, - 'statuses_count' => 0, - 'last_status_at' => '2023-01-30', - 'emojis' => [], - 'fields' => - [{ 'name' => 'Alternatel Contact', - 'value' => - '@mauve', - 'verified_at' => nil }] }, - 'rules' => [] } - - ] + @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 1bc94ec1..d572e052 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -38,6 +38,7 @@ class PostsController < ApplicationController @usuarie = site.usuarie? current_usuarie @site_stat = SiteStat.new(site) + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) end def show @@ -81,75 +82,6 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' - - @moderation_queue = [ - - { '@context' => - ['https://www.w3.org/ns/activitystreams', - { 'ostatus' => 'http://ostatus.org#', - 'atomUri' => 'ostatus:atomUri', - 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', - 'conversation' => 'ostatus:conversation', - 'sensitive' => 'as:sensitive', - 'toot' => 'http://joinmastodon.org/ns#', - 'votersCount' => 'toot:votersCount', - 'Hashtag' => 'as:Hashtag' }], - 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'type' => 'Note', - 'summary' => nil, - 'inReplyTo' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'published' => '2023-11-23T22:50:10Z', - 'url' => 'https://mastodon.mauve.moe/@mauve/111462305634770041', - 'attributedTo' => 'https://mastodon.mauve.moe/users/mauve', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://mastodon.mauve.moe/users/mauve/followers', 'https://hypha.coop/about.jsonld'], - 'sensitive' => false, - 'atomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041', - 'inReplyToAtomUri' => 'https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886', - 'conversation' => 'tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation', - 'content' => - '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ', - 'contentMap' => - { 'en' => - '

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      ' }, - 'attachment' => [], - 'tag' => - [{ 'type' => 'Mention', 'href' => 'https://hypha.coop/about.jsonld', 'name' => '@dripline@hypha.coop' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/p2p', 'name' => '#p2p' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/activitypub', 'name' => '#activitypub' }, - { 'type' => 'Hashtag', 'href' => 'https://mastodon.mauve.moe/tags/fediverse', 'name' => '#fediverse' }], - 'replies' => - { 'id' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'type' => 'Collection', - 'first' => - { 'type' => 'CollectionPage', - 'next' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true', - 'partOf' => 'https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies', - 'items' => [] } } }, - { '@context' => ['https://www.w3.org/ns/activitystreams', { '@language' => 'es', 'sensitive' => 'as:sensitive' }], - 'type' => 'Note', - 'id' => 'https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/', - 'summary' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'published' => '2023-12-04T21:53:05+00:00', - 'updated' => '2023-12-05T20:41:34+00:00', - 'attributedTo' => 'https://sutty.nl/about.jsonld', - 'to' => ['https://www.w3.org/ns/activitystreams#Public'], - 'cc' => ['https://social.distributed.press/v1/@sutty@sutty.nl/followers'], - 'inReplyTo' => 'https://hypha.coop/dripline/announcing-dp-social-inbox/', - 'sensitive' => true, - 'content' => - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n", - 'name' => 'Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty', - 'contentMap' => - { 'es' => - "

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        \n
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. \n
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. \n

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        \n
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • \n
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • \n
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • \n
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • \n
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • \n
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • \n

      Qué permite hacer

        \n
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • \n
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • \n
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • \n
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • \n
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • \n

      Qué se viene

        \n
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • \n
      • Incorporación de menciones desde el panel de Sutty.

      • \n
      • Mejoras en la interfaz general del panel.

      • \n
      • Nuevas implementaciones para una mejor moderación.

      • \n
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • \n
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • \n
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • \n
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • \n
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • \n
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • \n

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      \n" }, - 'attachment' => - [{ 'type' => 'Document', - 'mediaType' => 'image/png', - 'url' => 'https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png', - 'name' => 'Botones de colores para activar la "Web Disribuida" y el "Fediverso".' }] } - - ] end def update diff --git a/db/seeds/instances.yaml b/db/seeds/instances.yaml new file mode 100644 index 00000000..bf326832 --- /dev/null +++ b/db/seeds/instances.yaml @@ -0,0 +1,285 @@ +--- +- domain: todon.nl + title: Todon.nl + version: 4.2.3 + source_url: https://github.com/mastodon/mastodon + description: Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, + (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, + intersectionelen, veganisten, mensenrechten, enz. + usage: + users: + active_month: 372 + thumbnail: + url: https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png + blurhash: UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE + versions: + "@1x": https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png + "@2x": https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png + languages: + - en + configuration: + urls: + streaming: wss://todon.nl + status: https://status.todon.eu + accounts: + max_featured_tags: 10 + statuses: + max_characters: 1312 + max_media_attachments: 4 + characters_reserved_per_url: 23 + media_attachments: + supported_mime_types: + - image/jpeg + - image/png + - image/gif + - image/heic + - image/heif + - image/webp + - image/avif + - video/webm + - video/mp4 + - video/quicktime + - video/ogg + - audio/wave + - audio/wav + - audio/x-wav + - audio/x-pn-wave + - audio/vnd.wave + - audio/ogg + - audio/vorbis + - audio/mpeg + - audio/mp3 + - audio/webm + - audio/flac + - audio/aac + - audio/m4a + - audio/x-m4a + - audio/mp4 + - audio/3gpp + - video/x-ms-asf + image_size_limit: 16777216 + image_matrix_limit: 33177600 + video_size_limit: 103809024 + video_frame_rate_limit: 120 + video_matrix_limit: 8294400 + polls: + max_options: 4 + max_characters_per_option: 50 + min_expiration: 300 + max_expiration: 2629746 + translation: + enabled: true + registrations: + enabled: false + approval_required: false + message: | +

      ¡No pasarán!

      + +

      Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

      + + + +

      Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

      + +

      It is temporary not possible to request on account on Todon.nl.

      + + + +

      Go to joinmastodon.org or FediDB Network to find another server.

      + url: + max_toot_chars: 1312 + contact: + email: todon@posteo.eu + account: + id: '1' + username: admin + acct: admin + display_name: "Admin \U0001F913 Todon.nl (mod)" + locked: false + bot: false + discoverable: false + group: false + created_at: '2017-04-28T00:00:00.000Z' + note: "

      This account is used for \U0001F399 Todon.nl announcements and ⚖️ + moderation.

      \U0001F6AB Don't follow this account when you are not + on Todon.nl.

      New? First read our \U0001F469‍\U0001F3EB Todon 101 \U0001F469‍\U0001F393 + at https://wiki.todon.eu/todon/101

      ⚖️ + For all our moderators go to https://wiki.todon.nl/todon/moderators

      \U0001F4DD Public toots from this account + are in English.

      \U0001F515 Criticism is fine, but people who do false + accusations are muted.

      ✉ todon@posteo.eu

      #nobot

      " + url: https://todon.nl/@admin + uri: https://todon.nl/users/admin + avatar: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png + avatar_static: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png + header: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png + header_static: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png + followers_count: 3164 + following_count: 8 + statuses_count: 724 + last_status_at: '2024-01-12' + noindex: true + emojis: [] + roles: + - id: '3' + name: Admin + color: "#595aff" + fields: + - name: "\U0001F4DC Terms of Service" + value: wiki.todon.nl/todon/terms_en + verified_at: '2018-11-01T14:39:45.465+00:00' + - name: ℹ️ Wiki + value: wiki.todon.nl/todon/informatio + verified_at: '2018-11-01T14:40:54.679+00:00' + - name: "\U0001F4CA Status" + value: status.todon.eu + verified_at: '2023-10-26T20:38:30.185+00:00' + - name: "\U0001F4B3️ Donations" + value: wiki.todon.eu/todon/donations + verified_at: '2022-11-02T00:06:31.865+00:00' + rules: + - id: '1' + text: We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, + apartheid and casteism - see our Terms of Service for our complete definition). + - id: '2' + text: We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, + non-binary people, intersexual people, queer people in general, etc. + - id: '4' + text: Sexism, misogyny and hate against black women (misogynoir). + - id: '6' + text: We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) + and body-shaming. + - id: '8' + text: We do not accept harassment and trolling. + - id: '10' + text: We also do not accept other forms of hate speech. + - id: '11' + text: We do not accept (sexual) abuse of minors, adults and animals (also not + virtual). + - id: '13' + text: We do not accept glorification of violence, calls for murder, death threats, + terrorism and militarism. + - id: '15' + text: We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms + and nationalism (above all nationalism of nation states, incl. flags/symbols + of those on Todon.*, see our Terms of Service). + - id: '16' + text: We do not accept fascism, right-wing populism, and right-wing and religious + extremism. + - id: '17' + text: We do not accept evangelisation and other forms of religious propaganda + [local only], and extreme sects and cults. + - id: '19' + text: We do not accept Marxist-Leninists, Stalinists, Maoists or other followers + of extreme authoritarian (so called) communist/socialist ideologies/regimes + (aka tankies). + - id: '20' + text: We do not accept capitalists, including so called 'anarcho-capitalists' + (aka ancaps) and neoliberals. + - id: '21' + text: We do not accept anthropogenic climate change denial, downplaying the climate + crisis, greenwashing and deceptive climate solutions (like nuclear energy). + - id: '27' + text: We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and + other forms of disinformation. + - id: '28' + text: Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain + in the final step. +- uri: mastodon.mauve.moe + title: Mauvestodon + short_description: Escape ship from centralized social media run by Mauve. + description: Chat about random techie and anarchist stuff. + email: contact@mauve.moe + version: 3.5.10 + urls: + streaming_api: wss://mastodon.mauve.moe + stats: + user_count: 12 + status_count: 3287 + domain_count: 11625 + thumbnail: https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png + languages: + - en + registrations: false + approval_required: false + invites_enabled: true + configuration: + statuses: + max_characters: 500 + max_media_attachments: 4 + characters_reserved_per_url: 23 + media_attachments: + supported_mime_types: + - image/jpeg + - image/png + - image/gif + - video/webm + - video/mp4 + - video/quicktime + - video/ogg + - audio/wave + - audio/wav + - audio/x-wav + - audio/x-pn-wave + - audio/ogg + - audio/vorbis + - audio/mpeg + - audio/mp3 + - audio/webm + - audio/flac + - audio/aac + - audio/m4a + - audio/x-m4a + - audio/mp4 + - audio/3gpp + - video/x-ms-asf + image_size_limit: 10485760 + image_matrix_limit: 16777216 + video_size_limit: 41943040 + video_frame_rate_limit: 60 + video_matrix_limit: 2304000 + polls: + max_options: 4 + max_characters_per_option: 50 + min_expiration: 300 + max_expiration: 2629746 + contact_account: + id: '1' + username: admin + acct: admin + display_name: '' + locked: false + bot: false + discoverable: true + group: false + created_at: '2022-04-25T00:00:00.000Z' + note: '' + url: https://mastodon.mauve.moe/@admin + avatar: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png + avatar_static: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png + header: https://mastodon.mauve.moe/headers/original/missing.png + header_static: https://mastodon.mauve.moe/headers/original/missing.png + followers_count: 0 + following_count: 0 + statuses_count: 0 + last_status_at: '2023-01-30' + emojis: [] + fields: + - name: Alternatel Contact + value: @mauve + verified_at: + rules: [] diff --git a/db/seeds/moderation_queue.yaml b/db/seeds/moderation_queue.yaml new file mode 100644 index 00000000..c7075c7e --- /dev/null +++ b/db/seeds/moderation_queue.yaml @@ -0,0 +1,153 @@ +--- +- "@context": + - https://www.w3.org/ns/activitystreams + - ostatus: http://ostatus.org# + atomUri: ostatus:atomUri + inReplyToAtomUri: ostatus:inReplyToAtomUri + conversation: ostatus:conversation + sensitive: as:sensitive + toot: http://joinmastodon.org/ns# + votersCount: toot:votersCount + Hashtag: as:Hashtag + id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 + type: Note + summary: + inReplyTo: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 + published: '2023-11-23T22:50:10Z' + url: https://mastodon.mauve.moe/@mauve/111462305634770041 + attributedTo: https://mastodon.mauve.moe/users/mauve + to: + - https://www.w3.org/ns/activitystreams#Public + cc: + - https://mastodon.mauve.moe/users/mauve/followers + - https://hypha.coop/about.jsonld + sensitive: false + atomUri: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 + inReplyToAtomUri: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 + conversation: tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation + content:

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      +

      + contentMap: + en:

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      +

      + attachment: [] + tag: + - type: Mention + href: https://hypha.coop/about.jsonld + name: "@dripline@hypha.coop" + - type: Hashtag + href: https://mastodon.mauve.moe/tags/p2p + name: "#p2p" + - type: Hashtag + href: https://mastodon.mauve.moe/tags/activitypub + name: "#activitypub" + - type: Hashtag + href: https://mastodon.mauve.moe/tags/fediverse + name: "#fediverse" + replies: + id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies + type: Collection + first: + type: CollectionPage + next: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true + partOf: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies + items: [] +- "@context": + - https://www.w3.org/ns/activitystreams + - "@language": es + sensitive: as:sensitive + type: Note + id: https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/ + summary: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty + published: '2023-12-04T21:53:05+00:00' + updated: '2023-12-05T20:41:34+00:00' + attributedTo: https://sutty.nl/about.jsonld + to: + - https://www.w3.org/ns/activitystreams#Public + cc: + - https://social.distributed.press/v1/@sutty@sutty.nl/followers + inReplyTo: https://hypha.coop/dripline/announcing-dp-social-inbox/ + sensitive: true + content: | +

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        +
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. +
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. +

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        +
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • +
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • +
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • +
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • +
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • +
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • +

      Qué permite hacer

        +
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • +
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • +
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • +
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • +
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • +

      Qué se viene

        +
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • +
      • Incorporación de menciones desde el panel de Sutty.

      • +
      • Mejoras en la interfaz general del panel.

      • +
      • Nuevas implementaciones para una mejor moderación.

      • +
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • +
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • +
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • +
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • +
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • +
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • +

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      + name: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty + contentMap: + es: | +

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        +
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. +
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. +

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        +
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • +
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • +
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • +
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • +
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • +
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • +

      Qué permite hacer

        +
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • +
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • +
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • +
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • +
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • +

      Qué se viene

        +
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • +
      • Incorporación de menciones desde el panel de Sutty.

      • +
      • Mejoras en la interfaz general del panel.

      • +
      • Nuevas implementaciones para una mejor moderación.

      • +
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • +
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • +
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • +
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • +
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • +
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • +

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      + attachment: + - type: Document + mediaType: image/png + url: https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png + name: Botones de colores para activar la "Web Disribuida" y el "Fediverso". diff --git a/db/seeds/remote_profile.yaml b/db/seeds/remote_profile.yaml new file mode 100644 index 00000000..1a670d6b --- /dev/null +++ b/db/seeds/remote_profile.yaml @@ -0,0 +1,106 @@ +--- +"@context": +- https://www.w3.org/ns/activitystreams +- https://w3id.org/security/v1 +- manuallyApprovesFollowers: as:manuallyApprovesFollowers + toot: http://joinmastodon.org/ns# + featured: + "@id": toot:featured + "@type": "@id" + featuredTags: + "@id": toot:featuredTags + "@type": "@id" + alsoKnownAs: + "@id": as:alsoKnownAs + "@type": "@id" + movedTo: + "@id": as:movedTo + "@type": "@id" + schema: http://schema.org# + PropertyValue: schema:PropertyValue + value: schema:value + discoverable: toot:discoverable + Device: toot:Device + Ed25519Signature: toot:Ed25519Signature + Ed25519Key: toot:Ed25519Key + Curve25519Key: toot:Curve25519Key + EncryptedMessage: toot:EncryptedMessage + publicKeyBase64: toot:publicKeyBase64 + deviceId: toot:deviceId + claim: + "@type": "@id" + "@id": toot:claim + fingerprintKey: + "@type": "@id" + "@id": toot:fingerprintKey + identityKey: + "@type": "@id" + "@id": toot:identityKey + devices: + "@type": "@id" + "@id": toot:devices + messageFranking: toot:messageFranking + messageType: toot:messageType + cipherText: toot:cipherText + suspended: toot:suspended + focalPoint: + "@container": "@list" + "@id": toot:focalPoint +id: https://mastodon.mauve.moe/users/mauve +type: Person +following: https://mastodon.mauve.moe/users/mauve/following +followers: https://mastodon.mauve.moe/users/mauve/followers +inbox: https://mastodon.mauve.moe/users/mauve/inbox +outbox: https://mastodon.mauve.moe/users/mauve/outbox +featured: https://mastodon.mauve.moe/users/mauve/collections/featured +featuredTags: https://mastodon.mauve.moe/users/mauve/collections/tags +preferredUsername: mauve +name: "Mauve \U0001F441\U0001F49C" +summary: "

      Occult Enby that's making local-first software with peer to peer + protocols, mesh networks, and the web.

      Also exploring what a local-first + cyberspace might look like in my spare time.

      " +url: https://mastodon.mauve.moe/@mauve +manuallyApprovesFollowers: false +discoverable: true +published: '2022-04-25T00:00:00Z' +devices: https://mastodon.mauve.moe/users/mauve/collections/devices +alsoKnownAs: +- https://infosec.exchange/users/RangerMauve +publicKey: + id: https://mastodon.mauve.moe/users/mauve#main-key + owner: https://mastodon.mauve.moe/users/mauve + publicKeyPem: | + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ + umIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng + 7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK + 75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq + WUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D + zAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf + XwIDAQAB + -----END PUBLIC KEY----- +tag: [] +attachment: +- type: PropertyValue + name: Pronouns + value: they/them/it +- type: PropertyValue + name: Email + value: mauve@mauve.moe +- type: PropertyValue + name: Matrix + value: @mauve:mauve.moe +- type: PropertyValue + name: Github/Twitter + value: "@RangerMauve" +endpoints: + sharedInbox: https://mastodon.mauve.moe/inbox +icon: + type: Image + mediaType: image/png + url: https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png +image: + type: Image + mediaType: image/png + url: https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png From 66676f009dee7a18953c6522ac59c103d206dafc Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 15 Jan 2024 14:36:07 -0300 Subject: [PATCH 311/814] fix: corregido ocultar schema si es de subnivel #14949 --- app/views/schemas/_row.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/schemas/_row.haml b/app/views/schemas/_row.haml index 1d1fca87..8c91fe1e 100644 --- a/app/views/schemas/_row.haml +++ b/app/views/schemas/_row.haml @@ -10,4 +10,5 @@ -# XXX: Solo un nivel de recursividad - unless local_assigns[:parent_schema] - schema.schemas.each do |s| + - next if s.hidden? = render 'schemas/row', schema: s, site: site, filter: filter, parent_schema: schema From 4c58aea47a712aa1a6d91efbc6e886a5517c3b7f Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 15 Jan 2024 14:50:11 -0300 Subject: [PATCH 312/814] fix: agregada linea segun CI:haml #14949 --- app/views/schemas/_row.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/schemas/_row.haml b/app/views/schemas/_row.haml index 8c91fe1e..40d2fec7 100644 --- a/app/views/schemas/_row.haml +++ b/app/views/schemas/_row.haml @@ -11,4 +11,6 @@ - unless local_assigns[:parent_schema] - schema.schemas.each do |s| - next if s.hidden? - = render 'schemas/row', schema: s, site: site, filter: filter, parent_schema: schema + + = render 'schemas/row', schema: s, site: site, filter: filter, + parent_schema: schema From 2796d3f2ca6bb2881b4d0dcdb7c03d713e6f9905 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 15 Jan 2024 15:11:55 -0300 Subject: [PATCH 313/814] fix: quitada linea agregada segun CI:haml #14949 --- app/views/schemas/_row.haml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/schemas/_row.haml b/app/views/schemas/_row.haml index 40d2fec7..48fd0ee7 100644 --- a/app/views/schemas/_row.haml +++ b/app/views/schemas/_row.haml @@ -11,6 +11,5 @@ - unless local_assigns[:parent_schema] - schema.schemas.each do |s| - next if s.hidden? - = render 'schemas/row', schema: s, site: site, filter: filter, parent_schema: schema From 3a44c9629fd87952fe9347d6334bd0d8eb93a17e Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 15:55:31 -0300 Subject: [PATCH 314/814] agregadas traducciones a posts/edit #15002 --- app/views/posts/edit.haml | 2 +- config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index c792ac93..126b811e 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,6 +1,6 @@ .row.justify-content-center .col-md-8 - = render 'layouts/details', summary: "Post" do + = render 'layouts/details', summary: t('.post') do = render 'posts/form', site: @site, post: @post = render 'layouts/details', summary: t('.moderation_queue') do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/config/locales/en.yml b/config/locales/en.yml index fc9d4894..5a1f31bc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -221,6 +221,10 @@ en: mutual_aid: Mutual aid contact_us: "Contact us" contact_us_href: "https://sutty.nl/en/#contact" + posts: + edit: + moderation_queue: Moderation Queue + post: Post collaborations: collaborate: submit: Register diff --git a/config/locales/es.yml b/config/locales/es.yml index 4bda4982..3b54fbba 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -221,6 +221,10 @@ es: mutual_aid: Ayuda mutua contact_us: "Contacto" contact_us_href: "https://sutty.nl/#contacto" + posts: + edit: + moderation_queue: Cola de moderación + post: Publicación collaborations: collaborate: submit: Registrarme From 49039c24b7ad16d5791ef606c80858ed7739db6a Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 16:12:04 -0300 Subject: [PATCH 315/814] =?UTF-8?q?agregada=20vista=20de=20remote=20profil?= =?UTF-8?q?e=20b=C3=A1sica=20#15003?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/remote_profile.haml | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/views/moderation_queue/remote_profile.haml diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml new file mode 100644 index 00000000..537ab91c --- /dev/null +++ b/app/views/moderation_queue/remote_profile.haml @@ -0,0 +1 @@ +%h1= @remote_profile['name'] \ No newline at end of file From ed0c237d60e1bdaa295c50c8bb08c885f1da6e04 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 16:14:02 -0300 Subject: [PATCH 316/814] agregada partial de details #15000 --- app/views/layouts/_details.haml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 app/views/layouts/_details.haml diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml new file mode 100644 index 00000000..9d6e04a1 --- /dev/null +++ b/app/views/layouts/_details.haml @@ -0,0 +1,4 @@ +%details + %summary= @summary + + = yield \ No newline at end of file From 4c902c8aaf58807c54522f6ba1a33061f034940f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 17 Jan 2024 16:39:20 -0300 Subject: [PATCH 317/814] feat: agregado clase details a application.scss #15000 --- app/assets/stylesheets/application.scss | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 7f62e658..7f7908ca 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -558,3 +558,31 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } +// details styles + +.details summary { + list-style: none; + cursor: default; + position: relative; + + &::after { + content: '▶'; + font-size: 2rem; + position: absolute; + left: 97%; + bottom: 46%; + transform: rotate(55deg); + color: $magenta + } + + &:focus { + background-color: #13FEFE; + color: black + } + } + +.details[open] > summary::after { + transform: rotate(90deg) translatey(-0.1em); + color: $magenta + } + \ No newline at end of file From f098de102eab41d817dc764e59cdbbb1aa367d47 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 17:16:52 -0300 Subject: [PATCH 318/814] feat: agregadas views de moderation_queue #15001 --- app/views/moderation_queue/index.haml | 2 ++ app/views/posts/_moderation_queue.haml | 0 2 files changed, 2 insertions(+) create mode 100644 app/views/moderation_queue/index.haml create mode 100644 app/views/posts/_moderation_queue.haml diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml new file mode 100644 index 00000000..ce5dda0f --- /dev/null +++ b/app/views/moderation_queue/index.haml @@ -0,0 +1,2 @@ +- @comments.each do |comment| + %h1= comment['id'] \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml new file mode 100644 index 00000000..e69de29b From ad8e5bc8115a908d31a964d357529ef4ce690d53 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 17 Jan 2024 17:37:02 -0300 Subject: [PATCH 319/814] fix: corregido edit in es.yml --- app/views/posts/index.haml | 2 +- app/views/posts/show.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 374f06ee..69fb2d8f 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -126,7 +126,7 @@ = post.order %td.text-nowrap - if @usuarie || policy(post).edit? - = link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block' + = link_to t('posts.edit_post'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block' - if @usuarie || policy(post).destroy? = link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-secondary btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') } diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index 10900d67..ec191d87 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -2,7 +2,7 @@ .row.justify-content-center .col-md-8 %article.content.table-responsive-md - = link_to t('posts.edit'), + = link_to t('posts.edit_post'), edit_site_post_path(@site, @post.id), class: 'btn btn-secondary btn-block' From 5d26c6746e6160986e01c03d7bf2cfc7f2afb3db Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 17 Jan 2024 17:37:53 -0300 Subject: [PATCH 320/814] fix: traducciones #15002 --- config/locales/en.yml | 12 +++++++----- config/locales/es.yml | 15 ++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5a1f31bc..4c03fd30 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,4 +1,7 @@ en: + moderation_queue: + remote_profile: + user: Username dark: Dark dir: ltr en: English @@ -221,10 +224,6 @@ en: mutual_aid: Mutual aid contact_us: "Contact us" contact_us_href: "https://sutty.nl/en/#contact" - posts: - edit: - moderation_queue: Moderation Queue - post: Post collaborations: collaborate: submit: Register @@ -582,7 +581,10 @@ en: categories: 'Everything' index: search: 'Search' - edit: 'Edit' + edit_post: 'Edit' + edit: + moderation_queue: Moderation Queue + post: Post preview: btn: 'Preliminary version' alert: 'Not every article type has a preliminary version' diff --git a/config/locales/es.yml b/config/locales/es.yml index 3b54fbba..cc3590ad 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,7 @@ es: + moderation_queue: + remote_profile: + user: Nombre de usuario dark: Oscuro es: Castellano en: English @@ -221,10 +224,6 @@ es: mutual_aid: Ayuda mutua contact_us: "Contacto" contact_us_href: "https://sutty.nl/#contacto" - posts: - edit: - moderation_queue: Cola de moderación - post: Publicación collaborations: collaborate: submit: Registrarme @@ -524,6 +523,9 @@ es: en: 'inglés' ar: 'árabe' posts: + edit: + moderation_queue: Moderation Queue + post: Post prev: Página anterior next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. @@ -590,7 +592,10 @@ es: remove_filter_help: 'Quitar este filtro: %{filter}' index: search: 'Buscar' - edit: 'Editar' + edit_post: 'Editar' + edit: + moderation_queue: Cola de moderación + post: Publicación preview: btn: 'Versión preliminar' alert: 'No todos los tipos de artículos poseen vista preliminar :)' From 28ddaca35a972d797a60191abf66a159669a4248 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 19 Jan 2024 13:41:23 -0300 Subject: [PATCH 321/814] fix: corregido details de post edit --- app/assets/stylesheets/application.scss | 2 +- app/views/layouts/_details.haml | 8 ++++---- app/views/posts/edit.haml | 6 ++++-- config/locales/es.yml | 7 ++----- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 7f7908ca..b11be0de 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -570,7 +570,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); font-size: 2rem; position: absolute; left: 97%; - bottom: 46%; + bottom: 2%; transform: rotate(55deg); color: $magenta } diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 9d6e04a1..f950b097 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,4 +1,4 @@ -%details - %summary= @summary - - = yield \ No newline at end of file +%details.details.py-2 + %summary + %h3.py-2.text-center= @summary + = yield \ No newline at end of file diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 126b811e..488056a4 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,6 +1,8 @@ .row.justify-content-center .col-md-8 - = render 'layouts/details', summary: t('.post') do + - @summary = t('posts.edit.post') + = render 'layouts/details', summary: @summary do = render 'posts/form', site: @site, post: @post - = render 'layouts/details', summary: t('.moderation_queue') do + - @summary = t('posts.edit.moderation_queue') + = render 'layouts/details', summary: @summary do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/config/locales/es.yml b/config/locales/es.yml index cc3590ad..1e4f870c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -524,8 +524,8 @@ es: ar: 'árabe' posts: edit: - moderation_queue: Moderation Queue - post: Post + moderation_queue: Cola de Moderación + post: Contenido prev: Página anterior next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. @@ -593,9 +593,6 @@ es: index: search: 'Buscar' edit_post: 'Editar' - edit: - moderation_queue: Cola de moderación - post: Publicación preview: btn: 'Versión preliminar' alert: 'No todos los tipos de artículos poseen vista preliminar :)' From ef7d9d2a1ee7b6fed274f869da2c20da95297915 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 19 Jan 2024 15:06:20 -0300 Subject: [PATCH 322/814] fix: eliminados espacios en blanco en varias lineas --- app/views/posts/edit.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 488056a4..5234f257 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,8 +1,8 @@ .row.justify-content-center .col-md-8 - - @summary = t('posts.edit.post') - = render 'layouts/details', summary: @summary do + - @summary = t('posts.edit.post') + = render 'layouts/details', summary: @summary do = render 'posts/form', site: @site, post: @post - - @summary = t('posts.edit.moderation_queue') + - @summary = t('posts.edit.moderation_queue') = render 'layouts/details', summary: @summary do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue From d895b9c808fbf4f7977f45a6723e4367aa23c17f Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 14:17:24 -0300 Subject: [PATCH 323/814] feat: agregados componentes comentario, botonera y boton_base --- app/assets/stylesheets/application.scss | 4 ++++ app/views/layouts/_details.haml | 2 ++ app/views/moderation_queue/_btn_base.haml | 3 +++ app/views/moderation_queue/_button_box.haml | 14 ++++++++++++++ app/views/moderation_queue/_comment.haml | 4 ++++ app/views/posts/_moderation_queue.haml | 3 +++ config/locales/es.yml | 6 ++++++ 7 files changed, 36 insertions(+) create mode 100644 app/views/moderation_queue/_btn_base.haml create mode 100644 app/views/moderation_queue/_button_box.haml create mode 100644 app/views/moderation_queue/_comment.haml diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index b11be0de..a4446532 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -585,4 +585,8 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); transform: rotate(90deg) translatey(-0.1em); color: $magenta } + +.bg-blue { + background-color: $azul; +} \ No newline at end of file diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index f950b097..4fe4d2af 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,3 +1,5 @@ +-# Detail Cola de Moderación + %details.details.py-2 %summary %h3.py-2.text-center= @summary diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml new file mode 100644 index 00000000..74e9516a --- /dev/null +++ b/app/views/moderation_queue/_btn_base.haml @@ -0,0 +1,3 @@ +-# Componente Botón general Moderación + +%a.btn.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml new file mode 100644 index 00000000..ea038e59 --- /dev/null +++ b/app/views/moderation_queue/_button_box.haml @@ -0,0 +1,14 @@ +-# Componente Botonera de Moderación + +.d-flex.py-2.justify-content-center + -# parámetros de botones + -# text, class, href + - @btn_box_params = [[t('.text_pause'), 'bg-outline-light', 'https://sutty.nl/'], + [t('.text_reject'), 'btn-outline-info blue', 'https://sutty.nl/'], + [t('.text_accept'), 'bg-blue white', 'https://sutty.nl/'], + [t('.text_reply'), 'btn-outline-dark', 'https://sutty.nl/'], + [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + + - @btn_box_params.each do |btn| + - @class = btn[1] + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml new file mode 100644 index 00000000..051a84b0 --- /dev/null +++ b/app/views/moderation_queue/_comment.haml @@ -0,0 +1,4 @@ +-# Componente Comentario + +%p.py-2 Esta línea es donde irá el cuerpo del comentario += render 'moderation_queue/button_box' \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e69de29b..77df7353 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -0,0 +1,3 @@ +.flex + %h2.text-center Comentarios + = render 'moderation_queue/comment' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 1e4f870c..f9cd1b4f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -2,6 +2,12 @@ es: moderation_queue: remote_profile: user: Nombre de usuario + button_box: + text_pause: Pausa + text_reject: Rechazar + text_accept: Aceptar Publicación + text_reply: Responder + text_report: Reportar dark: Oscuro es: Castellano en: English From 9fa45b01ac8e8afc29babcc462ab2719e010ca9b Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 15:35:19 -0300 Subject: [PATCH 324/814] =?UTF-8?q?feat:=20agregadas=20traducci=C3=B3n=20i?= =?UTF-8?q?ngl=C3=A9s=20botones=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 4 +++- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_button_box.haml | 6 +++--- config/locales/en.yml | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a4446532..c0a666ab 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -3,6 +3,7 @@ $white: white; $grey: grey; $cyan: #13fefe; $magenta: #f206f9; +$blue: blue; $colors: ( "black": $black, @@ -14,6 +15,7 @@ $colors: ( // Redefinir variables de Bootstrap $primary: $magenta; $secondary: $black; +$info: $blue; $jumbotron-bg: transparent; $enable-rounded: false; $form-feedback-valid-color: $black; @@ -589,4 +591,4 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); .bg-blue { background-color: $azul; } - \ No newline at end of file + diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 74e9516a..5f4561ef 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%a.btn.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file +%a.btn.btn-lg.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index ea038e59..9a2f5947 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -1,10 +1,10 @@ -# Componente Botonera de Moderación -.d-flex.py-2.justify-content-center +.d-inline-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - @btn_box_params = [[t('.text_pause'), 'bg-outline-light', 'https://sutty.nl/'], - [t('.text_reject'), 'btn-outline-info blue', 'https://sutty.nl/'], + - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], + [t('.text_reject'), 'btn-outline-info', 'https://sutty.nl/'], [t('.text_accept'), 'bg-blue white', 'https://sutty.nl/'], [t('.text_reply'), 'btn-outline-dark', 'https://sutty.nl/'], [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] diff --git a/config/locales/en.yml b/config/locales/en.yml index 4c03fd30..ef14f51f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2,6 +2,12 @@ en: moderation_queue: remote_profile: user: Username + button_box: + text_pause: Pause + text_reject: Reject + text_accept: Accept Publication + text_reply: Reply + text_report: Report dark: Dark dir: ltr en: English From 45d98b316914db31f47c370b547ac5c31f641f74 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 16:05:57 -0300 Subject: [PATCH 325/814] fix: corregidas clases en botonera --- app/views/moderation_queue/_button_box.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index 9a2f5947..99744088 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -1,6 +1,6 @@ -# Componente Botonera de Moderación -.d-inline-flex.py-2.justify-content-center +.d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], From 1edf052109c643bceb60aed6c1aaaf162a1e0779 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 22 Jan 2024 17:38:32 -0300 Subject: [PATCH 326/814] fix: corregido padding en moderation_queue view --- app/views/posts/_moderation_queue.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 77df7353..4b405bbb 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,3 +1,3 @@ .flex - %h2.text-center Comentarios + %h3.text-center.py-2 Comentarios = render 'moderation_queue/comment' \ No newline at end of file From 9cb1e6fd36afc95f912e45f6323e6c0ade9c8c41 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 23 Jan 2024 16:29:11 -0300 Subject: [PATCH 327/814] =?UTF-8?q?feat:=20index=20de=20cola=20de=20modera?= =?UTF-8?q?ci=C3=B3n,=20con=20metadatos=20pero=20sin=20maquetar=20#15039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 7 +++++++ app/views/moderation_queue/index.haml | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 051a84b0..f2fb3ac2 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,4 +1,11 @@ -# Componente Comentario %p.py-2 Esta línea es donde irá el cuerpo del comentario + + +.row + .col.col-1 + %p "hola" + .col + %p "chau" = render 'moderation_queue/button_box' \ No newline at end of file diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index ce5dda0f..0881add2 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,2 +1,4 @@ -- @comments.each do |comment| - %h1= comment['id'] \ No newline at end of file +- @moderation_queue.each do |comment| + + = render 'comment', comment: comment +-# %h1= comment['id'] \ No newline at end of file From 2c7081a57f361c3e6f5479cd68d4659aaed62746 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 23 Jan 2024 17:04:38 -0300 Subject: [PATCH 328/814] feat: agregado componente remote_profile y botonera --- app/views/moderation_queue/_comment.haml | 2 +- .../{_button_box.haml => _comment_button_box.haml} | 0 app/views/moderation_queue/_profile_button_box.haml | 12 ++++++++++++ app/views/moderation_queue/_remote_profile.haml | 5 +++++ app/views/moderation_queue/remote_profile.haml | 4 +++- config/locales/es.yml | 11 +++++++++-- 6 files changed, 30 insertions(+), 4 deletions(-) rename app/views/moderation_queue/{_button_box.haml => _comment_button_box.haml} (100%) create mode 100644 app/views/moderation_queue/_profile_button_box.haml create mode 100644 app/views/moderation_queue/_remote_profile.haml diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 051a84b0..e43e8c42 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,4 +1,4 @@ -# Componente Comentario %p.py-2 Esta línea es donde irá el cuerpo del comentario -= render 'moderation_queue/button_box' \ No newline at end of file += render 'moderation_queue/comment_button_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml similarity index 100% rename from app/views/moderation_queue/_button_box.haml rename to app/views/moderation_queue/_comment_button_box.haml diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml new file mode 100644 index 00000000..d5852ffa --- /dev/null +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -0,0 +1,12 @@ +-# Componente Botonera de Profile + +.d-flex.py-2.justify-content-center + -# parámetros de botones + -# text, class, href + - @btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], + [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], + [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + + - @btn_box_params.each do |btn| + - @class = btn[1] + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml new file mode 100644 index 00000000..3a18a24a --- /dev/null +++ b/app/views/moderation_queue/_remote_profile.haml @@ -0,0 +1,5 @@ +.flex.py-2.mx-2.text-center + %h4= t('.profile_name') + ": " + @remote_profile['name'] + %h5= t('.profile_id') + ": " + @remote_profile['id'] + %h5= t('.profile_published') + ": " + @remote_profile['published'] + = render 'moderation_queue/profile_button_box' \ No newline at end of file diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index 537ab91c..36613405 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1 +1,3 @@ -%h1= @remote_profile['name'] \ No newline at end of file +.flex + %h1.text-center= t('.profile') + = render 'moderation_queue/remote_profile' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index f9cd1b4f..0f5e314c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,8 +1,15 @@ es: moderation_queue: remote_profile: - user: Nombre de usuario - button_box: + profile: Cuentas + profile_name: Nombre de la Cuenta + profile_id: ID + profile_published: Publicada + profile_button_box: + text_deny: Bloquear que te siga + text_allow: Permitir que te siga + text_report: Reportar + comment_button_box: text_pause: Pausa text_reject: Rechazar text_accept: Aceptar Publicación From f78fb436817aa5546cc98ef120013ca291076064 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 23 Jan 2024 17:13:42 -0300 Subject: [PATCH 329/814] =?UTF-8?q?feat:=20esqueleto=20b=C3=A1sico=20maque?= =?UTF-8?q?tado=20de=20comentario=20para=20cola=20de=20moderaci=C3=B3n=20#?= =?UTF-8?q?15039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index f2fb3ac2..766e4a22 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -3,9 +3,16 @@ %p.py-2 Esta línea es donde irá el cuerpo del comentario +.row.border.border-white + .col.col-1.border.border-white + %p= comment['published'] # falta parsear + .col.border.border-white + %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear +.row.border.border-white + %p= "En respuesta a: " + %span + %a{:href => comment['inReplyTo']}= comment['inReplyTo'] +.row.border.border-white + %p= comment['content'] #falta parsear .row - .col.col-1 - %p "hola" - .col - %p "chau" -= render 'moderation_queue/button_box' \ No newline at end of file + = render 'moderation_queue/button_box' \ No newline at end of file From d3e5434a00a703c7c749bbc3ac1e01ca4c1f3854 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 25 Jan 2024 15:48:25 -0300 Subject: [PATCH 330/814] fix: agregadas traduccion y estilos a componente _comment --- app/views/moderation_queue/_comment.haml | 36 +++++++++++++----------- config/locales/es.yml | 3 ++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d412ce62..1093a26b 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,18 +1,20 @@ -# Componente Comentario - -%p.py-2 Esta línea es donde irá el cuerpo del comentario - - -.row.border.border-white - .col.col-1.border.border-white - %p= comment['published'] # falta parsear - .col.border.border-white - %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear -.row.border.border-white - %p= "En respuesta a: " - %span - %a{:href => comment['inReplyTo']}= comment['inReplyTo'] -.row.border.border-white - %p= comment['content'] #falta parsear -.row - = render 'moderation_queue/comment_button_box' +.flex.mx-4.my-5 + .row.no-gutters + .col-1 + %input{type: "checkbox", id: ""} + .col-10 + .row.border.border-white + .col.col-1.border.border-white.mr-2 + %p= comment['published'].to_datetime.strftime('%m/%d/%Y') # falta parsear + .col.border.border-white + %span.mr-3= t('.source_profile') + %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear + .row.border.border-white + %p.mr-3= t('.reply_to') + %span + %a{:href => comment['inReplyTo']}= comment['inReplyTo'] + .row.border.border-white + %p= comment['content'] #falta parsear + .row.d-flex.justify-content-center + = render 'moderation_queue/comment_button_box' diff --git a/config/locales/es.yml b/config/locales/es.yml index 0f5e314c..451d5fa4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,5 +1,8 @@ es: moderation_queue: + comment: + source_profile: Cuenta de Origen + reply_to: En respuesta a remote_profile: profile: Cuentas profile_name: Nombre de la Cuenta From f6a93b5bc21722d731cceef54a66c0bb17c2b222 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 25 Jan 2024 16:15:20 -0300 Subject: [PATCH 331/814] fix: corregida llamada en _moderation_queue para mostrar comentarios en vista posts/edit --- app/controllers/posts_controller.rb | 1 + app/views/moderation_queue/_comment_button_box.haml | 8 ++++---- app/views/moderation_queue/index.haml | 1 - app/views/posts/_moderation_queue.haml | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index d572e052..12b3ab55 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -82,6 +82,7 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) end def update diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml index 99744088..13a9c8a3 100644 --- a/app/views/moderation_queue/_comment_button_box.haml +++ b/app/views/moderation_queue/_comment_button_box.haml @@ -4,10 +4,10 @@ -# parámetros de botones -# text, class, href - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], - [t('.text_reject'), 'btn-outline-info', 'https://sutty.nl/'], - [t('.text_accept'), 'bg-blue white', 'https://sutty.nl/'], - [t('.text_reply'), 'btn-outline-dark', 'https://sutty.nl/'], - [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + [t('.text_reject'), 'btn-outline-info', ''], + [t('.text_accept'), 'bg-blue white', ''], + [t('.text_reply'), 'btn-outline-dark', ''], + [t('.text_report'), 'btn-outline-danger', '']] - @btn_box_params.each do |btn| - @class = btn[1] diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0881add2..0c693d26 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,4 +1,3 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment --# %h1= comment['id'] \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 4b405bbb..c754d51d 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,3 +1,4 @@ .flex %h3.text-center.py-2 Comentarios - = render 'moderation_queue/comment' \ No newline at end of file + - @moderation_queue.each do |comment| + = render 'moderation_queue/comment', comment: comment \ No newline at end of file From 1eb2230b2afad89701923da7bd4fbe5cc021278d Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 25 Jan 2024 17:05:06 -0300 Subject: [PATCH 332/814] =?UTF-8?q?fix:=20corregida=20posici=C3=B3n=20de?= =?UTF-8?q?=20botonera=20de=20moderacion=20de=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 6 ++---- app/views/moderation_queue/index.haml | 1 + app/views/posts/_moderation_queue.haml | 4 +++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 1093a26b..639a6bae 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -5,10 +5,10 @@ %input{type: "checkbox", id: ""} .col-10 .row.border.border-white - .col.col-1.border.border-white.mr-2 + .col.col-1.border.border-white.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') # falta parsear .col.border.border-white - %span.mr-3= t('.source_profile') + %span.mr-2= t('.source_profile') %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear .row.border.border-white %p.mr-3= t('.reply_to') @@ -16,5 +16,3 @@ %a{:href => comment['inReplyTo']}= comment['inReplyTo'] .row.border.border-white %p= comment['content'] #falta parsear - .row.d-flex.justify-content-center - = render 'moderation_queue/comment_button_box' diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0c693d26..63b36a3a 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,3 +1,4 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment + = render 'moderation_queue/comment_button_box' \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index c754d51d..2528224f 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,4 +1,6 @@ .flex %h3.text-center.py-2 Comentarios - @moderation_queue.each do |comment| - = render 'moderation_queue/comment', comment: comment \ No newline at end of file + = render 'moderation_queue/comment', comment: comment + .row.d-flex.justify-content-center + = render 'moderation_queue/comment_button_box' \ No newline at end of file From 9e8a83b70665885604b287bf025ebb8412b7a116 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 26 Jan 2024 15:15:48 -0300 Subject: [PATCH 333/814] fix: html de comentarios sanitizado #15039 --- app/views/moderation_queue/_comment.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 639a6bae..d66d1187 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -15,4 +15,4 @@ %span %a{:href => comment['inReplyTo']}= comment['inReplyTo'] .row.border.border-white - %p= comment['content'] #falta parsear + %p= sanitize comment['content'] #falta parsear From 5a6b0373a2dc095a7c9b608ef73b3731c276a583 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 26 Jan 2024 15:23:38 -0300 Subject: [PATCH 334/814] feat: agregado componente caja de filtros de comentarios y compo filtro_base --- app/views/moderation_queue/_comment.haml | 4 ++-- app/views/moderation_queue/_comment_filter_box.haml | 6 ++++++ app/views/moderation_queue/_filter_base.haml | 8 ++++++++ app/views/moderation_queue/index.haml | 1 + app/views/posts/_moderation_queue.haml | 1 + config/locales/es.yml | 4 ++++ 6 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 app/views/moderation_queue/_comment_filter_box.haml create mode 100644 app/views/moderation_queue/_filter_base.haml diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d66d1187..a3f2499c 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -6,7 +6,7 @@ .col-10 .row.border.border-white .col.col-1.border.border-white.mr-5 - %p= comment['published'].to_datetime.strftime('%m/%d/%Y') # falta parsear + %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col.border.border-white %span.mr-2= t('.source_profile') %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear @@ -15,4 +15,4 @@ %span %a{:href => comment['inReplyTo']}= comment['inReplyTo'] .row.border.border-white - %p= sanitize comment['content'] #falta parsear + %p= sanitize comment['content'] diff --git a/app/views/moderation_queue/_comment_filter_box.haml b/app/views/moderation_queue/_comment_filter_box.haml new file mode 100644 index 00000000..e9abe602 --- /dev/null +++ b/app/views/moderation_queue/_comment_filter_box.haml @@ -0,0 +1,6 @@ +-# Componente Caja de Filtros + +.d-flex.py-2.justify-content-center + = render 'moderation_queue/filter_base', text: t('.text_checked') + = render 'moderation_queue/filter_base', text: t('.text_show') + = render 'moderation_queue/filter_base', text: t('.text_order') \ No newline at end of file diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml new file mode 100644 index 00000000..6b62b99d --- /dev/null +++ b/app/views/moderation_queue/_filter_base.haml @@ -0,0 +1,8 @@ +-# Componente Filtro +.dropdown.mx-4 + %button#dropdownMenuButton.btn.btn-outline-secondary.dropdown-toggle{:type => "button", "data-toggle" => "dropdown", "aria-haspopup" => "true", "aria-expanded" => "false"} + %span #{text} + .dropdown-menu{"aria-labelledby" => "dropdownMenuButton"} + %a.dropdown-item{:href => "#"} Action + %a.dropdown-item{:href => "#"} Another action + %a.dropdown-item{:href => "#"} Something else here diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 63b36a3a..dbc1297a 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,3 +1,4 @@ += render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| = render 'comment', comment: comment diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 2528224f..7daa0c8e 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,6 +1,7 @@ .flex %h3.text-center.py-2 Comentarios - @moderation_queue.each do |comment| + = render 'moderation_queue/comment_filter_box' = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 451d5fa4..d579d55e 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -18,6 +18,10 @@ es: text_accept: Aceptar Publicación text_reply: Responder text_report: Reportar + comment_filter_box: + text_order: Ordenar por + text_show: Ver + text_checked: Con los marcados dark: Oscuro es: Castellano en: English From 4b67968d3b9888ffb50dc7b2f6de499a7780e6c9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 29 Jan 2024 13:28:58 -0300 Subject: [PATCH 335/814] fix: corregido botonera de filtros en componente moderation_queue --- app/views/posts/_moderation_queue.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 7daa0c8e..80a8b11c 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,7 +1,7 @@ .flex %h3.text-center.py-2 Comentarios + = render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| - = render 'moderation_queue/comment_filter_box' = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' \ No newline at end of file From 2f803f9ea625b8f0f48b6c2e47c77058930f66a6 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 29 Jan 2024 13:48:11 -0300 Subject: [PATCH 336/814] fix: corregidas lineas segun CI --- app/views/moderation_queue/_filter_base.haml | 6 +++--- app/views/moderation_queue/_profile_button_box.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 4 ++-- app/views/moderation_queue/remote_profile.haml | 2 +- app/views/posts/_moderation_queue.haml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml index 6b62b99d..0b63e59b 100644 --- a/app/views/moderation_queue/_filter_base.haml +++ b/app/views/moderation_queue/_filter_base.haml @@ -3,6 +3,6 @@ %button#dropdownMenuButton.btn.btn-outline-secondary.dropdown-toggle{:type => "button", "data-toggle" => "dropdown", "aria-haspopup" => "true", "aria-expanded" => "false"} %span #{text} .dropdown-menu{"aria-labelledby" => "dropdownMenuButton"} - %a.dropdown-item{:href => "#"} Action - %a.dropdown-item{:href => "#"} Another action - %a.dropdown-item{:href => "#"} Something else here + %a.dropdown-item{ href: '#' } Action + %a.dropdown-item{ href: '#' } Another action + %a.dropdown-item{ href: '#' } Something else here diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml index d5852ffa..1201de05 100644 --- a/app/views/moderation_queue/_profile_button_box.haml +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -9,4 +9,4 @@ - @btn_box_params.each do |btn| - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 3a18a24a..273b7bd8 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,5 +1,5 @@ .flex.py-2.mx-2.text-center %h4= t('.profile_name') + ": " + @remote_profile['name'] %h5= t('.profile_id') + ": " + @remote_profile['id'] - %h5= t('.profile_published') + ": " + @remote_profile['published'] - = render 'moderation_queue/profile_button_box' \ No newline at end of file + %h5= t('.profile_published') + ": " + @remote_profile['published'].to_datetime.strftime('%m/%d/%Y') + = render 'moderation_queue/profile_button_box' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index 36613405..d1d20f86 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,3 @@ .flex %h1.text-center= t('.profile') - = render 'moderation_queue/remote_profile' \ No newline at end of file + = render 'moderation_queue/remote_profile' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 80a8b11c..f1b0f7ce 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -4,4 +4,4 @@ - @moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center - = render 'moderation_queue/comment_button_box' \ No newline at end of file + = render 'moderation_queue/comment_button_box' From 957e79e682e83e57704e43e01d3407f46bbf5df4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 29 Jan 2024 15:32:47 -0300 Subject: [PATCH 337/814] fix: corregidas variables en partials --- app/views/moderation_queue/_comment_button_box.haml | 4 ++-- app/views/moderation_queue/_profile_button_box.haml | 4 ++-- app/views/moderation_queue/_remote_profile.haml | 6 +++--- app/views/moderation_queue/remote_profile.haml | 2 +- app/views/posts/_moderation_queue.haml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml index 13a9c8a3..a22f46d5 100644 --- a/app/views/moderation_queue/_comment_button_box.haml +++ b/app/views/moderation_queue/_comment_button_box.haml @@ -3,12 +3,12 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - @btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], + - btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], [t('.text_reject'), 'btn-outline-info', ''], [t('.text_accept'), 'bg-blue white', ''], [t('.text_reply'), 'btn-outline-dark', ''], [t('.text_report'), 'btn-outline-danger', '']] - - @btn_box_params.each do |btn| + - btn_box_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml index 1201de05..9de64e12 100644 --- a/app/views/moderation_queue/_profile_button_box.haml +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -3,10 +3,10 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - @btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], + - btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] - - @btn_box_params.each do |btn| + - btn_box_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 273b7bd8..b665dcf2 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,5 +1,5 @@ .flex.py-2.mx-2.text-center - %h4= t('.profile_name') + ": " + @remote_profile['name'] - %h5= t('.profile_id') + ": " + @remote_profile['id'] - %h5= t('.profile_published') + ": " + @remote_profile['published'].to_datetime.strftime('%m/%d/%Y') + %h4= t('.profile_name') + ': ' + remote_profile['name'] + %h5= t('.profile_id') + ': ' + remote_profile['id'] + %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') = render 'moderation_queue/profile_button_box' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index d1d20f86..3eab5e35 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,3 @@ .flex %h1.text-center= t('.profile') - = render 'moderation_queue/remote_profile' + = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index f1b0f7ce..513632cd 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,7 +1,7 @@ .flex %h3.text-center.py-2 Comentarios = render 'moderation_queue/comment_filter_box' - - @moderation_queue.each do |comment| + - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' From 1b0fb009f49a02dd5c9ed68cf77a81b9ef5d41c7 Mon Sep 17 00:00:00 2001 From: maki Date: Mon, 29 Jan 2024 16:35:53 -0300 Subject: [PATCH 338/814] =?UTF-8?q?feat:=20traer=20informaci=C3=B3n=20de?= =?UTF-8?q?=20perfil=20remoto=20vinculado=20al=20comentario=20#15039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 4 ++++ app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/index.haml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index eb39dae6..4a65f136 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -5,6 +5,10 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + @moderation_queue.each do |activity| + activity['attributedTo'] = @remote_profile + end end # Perfil remoto de usuarie diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index a3f2499c..d443802d 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -9,7 +9,7 @@ %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col.border.border-white %span.mr-2= t('.source_profile') - %a{:href => comment['attributedTo']}= comment['attributedTo'] #falta parsear + %a{:href => comment['attributedTo']}= profile['preferredUsername'] .row.border.border-white %p.mr-3= t('.reply_to') %span diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index dbc1297a..a3897417 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,5 +1,5 @@ = render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| - = render 'comment', comment: comment + = render 'comment', comment: comment, profile: @remote_profile = render 'moderation_queue/comment_button_box' \ No newline at end of file From b7630844747b0fb0ec122e2597158ed99cd7093e Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:41:12 -0300 Subject: [PATCH 339/814] feat: dummy data #15076 --- app/controllers/application_controller.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2746ab10..903d3642 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,6 +27,15 @@ class ApplicationController < ActionController::Base end private + # Traer datos de muestra de la cola de moderación + def dummy_data + @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) + @moderation_queue.each do |activity| + activity['attributedTo'] = @remote_profile + end + end def notify_unconfirmed_email return unless current_usuarie @@ -117,4 +126,5 @@ class ApplicationController < ActionController::Base sites_path end + end From b233a74f61ef522d7f4cd99e8ffba1dc8b2f02e7 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:47:19 -0300 Subject: [PATCH 340/814] =?UTF-8?q?fix:=20agregada=20dummy=5Fdata=20en=20e?= =?UTF-8?q?l=20m=C3=A9todo=20edit=20de=20posts=5Fcontroller=20#15076=20#15?= =?UTF-8?q?039?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/posts_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 12b3ab55..8839de52 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -83,6 +83,7 @@ class PostsController < ApplicationController breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + dummy_data end def update From 836687651e1f922fe71847d5864158fb93a59e5e Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:51:53 -0300 Subject: [PATCH 341/814] =?UTF-8?q?fix:=20c=C3=B3digo=20dem=C3=A1s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/posts_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 8839de52..5be56acc 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -82,7 +82,6 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) dummy_data end From 4f6464837ac8a0b8a446353ac4eacb80a1e39d2c Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 31 Jan 2024 15:53:05 -0300 Subject: [PATCH 342/814] fix: a ver si esto arregla --- app/views/posts/_moderation_queue.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 513632cd..b861d67d 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -2,6 +2,6 @@ %h3.text-center.py-2 Comentarios = render 'moderation_queue/comment_filter_box' - moderation_queue.each do |comment| - = render 'moderation_queue/comment', comment: comment + = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center = render 'moderation_queue/comment_button_box' From 94a86eca9b61efc7c8b5327f0c08f1893a728c18 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 31 Jan 2024 17:10:34 -0300 Subject: [PATCH 343/814] fix: corregidos colores botonera de comentarios #15028 --- app/views/moderation_queue/_comment_button_box.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml index a22f46d5..bd367e09 100644 --- a/app/views/moderation_queue/_comment_button_box.haml +++ b/app/views/moderation_queue/_comment_button_box.haml @@ -3,10 +3,10 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - btn_box_params = [[t('.text_pause'), 'btn-outline-secondary disabled', ''], - [t('.text_reject'), 'btn-outline-info', ''], + - btn_box_params = [[t('.text_pause'), 'btn-secondary', ''], + [t('.text_reject'), 'btn-primary', ''], [t('.text_accept'), 'bg-blue white', ''], - [t('.text_reply'), 'btn-outline-dark', ''], + [t('.text_reply'), 'btn-outline-primary', ''], [t('.text_report'), 'btn-outline-danger', '']] - btn_box_params.each do |btn| From 819ed25e29a2559bcb2a541b3c46cb887e348fc4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 1 Feb 2024 12:02:40 -0300 Subject: [PATCH 344/814] fix: eliminadas botoneras de comentarios y remote_profile y unificadas en componente button_box #15028 --- app/controllers/application_controller.rb | 13 +++++++++++++ app/controllers/moderation_queue_controller.rb | 1 + app/controllers/posts_controller.rb | 1 + app/views/moderation_queue/_button_box.haml | 6 ++++++ .../moderation_queue/_comment_button_box.haml | 14 -------------- .../moderation_queue/_profile_button_box.haml | 4 ++-- app/views/moderation_queue/index.haml | 2 +- app/views/posts/_moderation_queue.haml | 2 +- config/locales/es.yml | 2 +- 9 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 app/views/moderation_queue/_button_box.haml delete mode 100644 app/views/moderation_queue/_comment_button_box.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 903d3642..360a9b2d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,6 +37,19 @@ class ApplicationController < ActionController::Base end end + # parámetros de botones + # text: [texto del botón] + # class: [clases css] + # href: [href del botón] + def botoneras_moderation_queue + # botones de comentarios + @comment_btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], + [t('moderation_queue.button_box.text_reject'), 'btn-primary', ''], + [t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''], + [t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''], + [t('moderation_queue.button_box.text_report'), 'btn-danger', '']] + end + def notify_unconfirmed_email return unless current_usuarie return if current_usuarie.confirmed? diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 4a65f136..04a31389 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -9,6 +9,7 @@ class ModerationQueueController < ApplicationController @moderation_queue.each do |activity| activity['attributedTo'] = @remote_profile end + botoneras_moderation_queue end # Perfil remoto de usuarie diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 5be56acc..36d17339 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -83,6 +83,7 @@ class PostsController < ApplicationController breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' dummy_data + botoneras_moderation_queue end def update diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml new file mode 100644 index 00000000..a56b2552 --- /dev/null +++ b/app/views/moderation_queue/_button_box.haml @@ -0,0 +1,6 @@ +-# Componente Botonera de Moderación + +.d-flex.py-2.justify-content-center + - comment_btn_params.each do |btn| + - @class = btn[1] + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_comment_button_box.haml b/app/views/moderation_queue/_comment_button_box.haml deleted file mode 100644 index bd367e09..00000000 --- a/app/views/moderation_queue/_comment_button_box.haml +++ /dev/null @@ -1,14 +0,0 @@ --# Componente Botonera de Moderación - -.d-flex.py-2.justify-content-center - -# parámetros de botones - -# text, class, href - - btn_box_params = [[t('.text_pause'), 'btn-secondary', ''], - [t('.text_reject'), 'btn-primary', ''], - [t('.text_accept'), 'bg-blue white', ''], - [t('.text_reply'), 'btn-outline-primary', ''], - [t('.text_report'), 'btn-outline-danger', '']] - - - btn_box_params.each do |btn| - - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml index 9de64e12..d15b6ed0 100644 --- a/app/views/moderation_queue/_profile_button_box.haml +++ b/app/views/moderation_queue/_profile_button_box.haml @@ -3,10 +3,10 @@ .d-flex.py-2.justify-content-center -# parámetros de botones -# text, class, href - - btn_box_params = [[t('.text_deny'), 'btn-outline-info', ''], + - comment_btn_params = [[t('.text_deny'), 'btn-outline-info', ''], [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] - - btn_box_params.each do |btn| + - comment_btn_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index a3897417..39ac74a3 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -2,4 +2,4 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/comment_button_box' \ No newline at end of file + = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index b861d67d..e4eb422c 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -4,4 +4,4 @@ - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center - = render 'moderation_queue/comment_button_box' + = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params diff --git a/config/locales/es.yml b/config/locales/es.yml index d579d55e..7850bcf7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -12,7 +12,7 @@ es: text_deny: Bloquear que te siga text_allow: Permitir que te siga text_report: Reportar - comment_button_box: + button_box: text_pause: Pausa text_reject: Rechazar text_accept: Aceptar Publicación From bbd5426da53c7d3677fcc72f17da0f74b42e519e Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 1 Feb 2024 12:17:51 -0300 Subject: [PATCH 345/814] fix: eliminada botonera remote_profile_box para usar componente general button_box #15028 --- app/controllers/application_controller.rb | 7 ++++++- app/controllers/moderation_queue_controller.rb | 1 + app/views/moderation_queue/_profile_button_box.haml | 12 ------------ app/views/moderation_queue/_remote_profile.haml | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) delete mode 100644 app/views/moderation_queue/_profile_button_box.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 360a9b2d..bcbf0bc2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,7 +37,7 @@ class ApplicationController < ActionController::Base end end - # parámetros de botones + # parámetros de botones: # text: [texto del botón] # class: [clases css] # href: [href del botón] @@ -48,6 +48,11 @@ class ApplicationController < ActionController::Base [t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''], [t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''], [t('moderation_queue.button_box.text_report'), 'btn-danger', '']] + + #botones de remote_profile (cuentas) + @profile_btn_params = [[t('moderation_queue.profile_button_box.text_deny'), 'btn-outline-info', ''], + [t('moderation_queue.profile_button_box.text_allow'), 'btn-success', 'https://sutty.nl/'], + [t('moderation_queue.profile_button_box.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] end def notify_unconfirmed_email diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 04a31389..5141990e 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -15,6 +15,7 @@ class ModerationQueueController < ApplicationController # Perfil remoto de usuarie def remote_profile @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + botoneras_moderation_queue end # todon.nl está usando /api/v2/instance diff --git a/app/views/moderation_queue/_profile_button_box.haml b/app/views/moderation_queue/_profile_button_box.haml deleted file mode 100644 index d15b6ed0..00000000 --- a/app/views/moderation_queue/_profile_button_box.haml +++ /dev/null @@ -1,12 +0,0 @@ --# Componente Botonera de Profile - -.d-flex.py-2.justify-content-center - -# parámetros de botones - -# text, class, href - - comment_btn_params = [[t('.text_deny'), 'btn-outline-info', ''], - [t('.text_allow'), 'btn-success', 'https://sutty.nl/'], - [t('.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] - - - comment_btn_params.each do |btn| - - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index b665dcf2..a8d60c60 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -2,4 +2,4 @@ %h4= t('.profile_name') + ': ' + remote_profile['name'] %h5= t('.profile_id') + ': ' + remote_profile['id'] %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') - = render 'moderation_queue/profile_button_box' + = render 'moderation_queue/button_box', comment_btn_params: @profile_btn_params From e9552776af79f8608bed502eef779f609238a532 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 1 Feb 2024 14:40:14 -0300 Subject: [PATCH 346/814] =?UTF-8?q?feat:=20pantalla=20de=20actividades=20d?= =?UTF-8?q?e=20moderaci=C3=B3n=20dividida=20en=20desplegables=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comments.haml | 5 +++++ app/views/moderation_queue/index.haml | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 app/views/moderation_queue/_comments.haml diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml new file mode 100644 index 00000000..39ac74a3 --- /dev/null +++ b/app/views/moderation_queue/_comments.haml @@ -0,0 +1,5 @@ += render 'moderation_queue/comment_filter_box' +- @moderation_queue.each do |comment| + + = render 'comment', comment: comment, profile: @remote_profile + = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 39ac74a3..e2adb13b 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,5 +1,8 @@ -= render 'moderation_queue/comment_filter_box' -- @moderation_queue.each do |comment| +.row.justify-content-center + .col-md-8 + - @summary = t('posts.edit.moderation_queue') + = render 'layouts/details', summary: @summary do + = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue + + - = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file From 683062da02094a362a56bc13751065503b1d8237 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 1 Feb 2024 14:47:40 -0300 Subject: [PATCH 347/814] =?UTF-8?q?feat:=20textos=20con=20traducciones=20p?= =?UTF-8?q?ara=20los=20t=C3=ADtulos=20de=20los=20details=20de=20actividade?= =?UTF-8?q?s=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 2 +- config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index e2adb13b..8f4ed5fb 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,6 +1,6 @@ .row.justify-content-center .col-md-8 - - @summary = t('posts.edit.moderation_queue') + - @summary = t('moderation_queue.index.comments') = render 'layouts/details', summary: @summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/config/locales/en.yml b/config/locales/en.yml index ef14f51f..9b8bb92b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,5 +1,9 @@ en: moderation_queue: + index: + instances: Instances + accounts: Accounts + comments: Comments remote_profile: user: Username button_box: diff --git a/config/locales/es.yml b/config/locales/es.yml index 7850bcf7..ddf8f7f7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,5 +1,9 @@ es: moderation_queue: + index: + instances: Instancias + accounts: Cuentas + comments: Comentarios comment: source_profile: Cuenta de Origen reply_to: En respuesta a From a9efe78c0b93b44fed443c83a363d3e13b6fb60f Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 1 Feb 2024 14:53:25 -0300 Subject: [PATCH 348/814] =?UTF-8?q?feat:=20aparecen=20todos=20los=20detail?= =?UTF-8?q?s=20en=20actividades=20de=20moderaci=C3=B3n,=20con=20los=20t?= =?UTF-8?q?=C3=ADtulos=20correspondientes,=20sin=20contenido=20(salvo=20co?= =?UTF-8?q?mentarios)=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_accounts.haml | 0 app/views/moderation_queue/_instances.haml | 0 app/views/moderation_queue/index.haml | 6 ++++++ 3 files changed, 6 insertions(+) create mode 100644 app/views/moderation_queue/_accounts.haml create mode 100644 app/views/moderation_queue/_instances.haml diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml new file mode 100644 index 00000000..e69de29b diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml new file mode 100644 index 00000000..e69de29b diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 8f4ed5fb..d89c30b4 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,5 +1,11 @@ .row.justify-content-center .col-md-8 + - @summary = t('moderation_queue.index.instances') + = render 'layouts/details', summary: @summary do + = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + - @summary = t('moderation_queue.index.accounts') + = render 'layouts/details', summary: @summary do + = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue - @summary = t('moderation_queue.index.comments') = render 'layouts/details', summary: @summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue From b2483634a47f6cbc301955ff729d5a6016f5ba3d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 1 Feb 2024 18:18:50 -0300 Subject: [PATCH 349/814] feat: empresa recuperada #15092 --- db/seeds/designs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/db/seeds/designs.yml b/db/seeds/designs.yml index d1ae458e..2b7b6492 100644 --- a/db/seeds/designs.yml +++ b/db/seeds/designs.yml @@ -91,6 +91,14 @@ description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)" description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)" priority: '3' +- name_en: 'Worker-recovered factory' + name_es: 'Empresa recuperada' + gem: 'empresa-recuperada-jekyll-theme' + url: 'https://empresa-recuperada.sutty.nl/' + disabled: true + description_en: "A template for [empresas recuperadas](https://en.wikipedia.org/wiki/Workers%27_self-management#Empresas_recuperadas_movement). We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)" + description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)" + priority: '3' - name_en: 'More themes' name_es: 'Más plantillas' gem: 'sutty-theme-own' From da1f7f775447e2d8f50dd9973628fb93353c308c Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 2 Feb 2024 14:45:25 -0300 Subject: [PATCH 350/814] fix: corregida botonera remote_profile #15080 --- app/controllers/application_controller.rb | 9 +++++---- app/views/moderation_queue/_button_box.haml | 4 ++-- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 10 +++++++--- app/views/posts/_moderation_queue.haml | 2 +- config/locales/es.yml | 6 ++++-- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bcbf0bc2..ba5dd4bd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -43,16 +43,17 @@ class ApplicationController < ActionController::Base # href: [href del botón] def botoneras_moderation_queue # botones de comentarios - @comment_btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], + @btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], [t('moderation_queue.button_box.text_reject'), 'btn-primary', ''], [t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''], [t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''], [t('moderation_queue.button_box.text_report'), 'btn-danger', '']] #botones de remote_profile (cuentas) - @profile_btn_params = [[t('moderation_queue.profile_button_box.text_deny'), 'btn-outline-info', ''], - [t('moderation_queue.profile_button_box.text_allow'), 'btn-success', 'https://sutty.nl/'], - [t('moderation_queue.profile_button_box.text_report'), 'btn-outline-danger', 'https://sutty.nl/']] + @profile_btn_params = [[t('moderation_queue.profile_button_box.text_approve'), 'btn-success', ''], + [t('moderation_queue.profile_button_box.text_check'), 'btn-outline-success', ''], + [t('moderation_queue.profile_button_box.text_deny'), 'bg-blue white', ''], + [t('moderation_queue.profile_button_box.text_report'), 'btn-danger', '']] end def notify_unconfirmed_email diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index a56b2552..46963b0f 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -1,6 +1,6 @@ -# Componente Botonera de Moderación -.d-flex.py-2.justify-content-center - - comment_btn_params.each do |btn| +.d-flex.py-4.justify-content-center + - btn_params.each do |btn| - @class = btn[1] = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 39ac74a3..fb83fbd9 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -2,4 +2,4 @@ - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params \ No newline at end of file + = render 'moderation_queue/button_box', btn_params: @btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index a8d60c60..94737a34 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,5 +1,9 @@ +-# Componente Remote_Profile + .flex.py-2.mx-2.text-center - %h4= t('.profile_name') + ': ' + remote_profile['name'] - %h5= t('.profile_id') + ': ' + remote_profile['id'] + %h4.mb-2= t('.profile_name') + ': ' + remote_profile['name'] + %h5= t('.profile_id') + ': ' + remote_profile['id'] %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') - = render 'moderation_queue/button_box', comment_btn_params: @profile_btn_params + %h5= t('.profile_summary') + ':' + %p= sanitize remote_profile['summary'] + = render 'moderation_queue/button_box', btn_params: @profile_btn_params diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e4eb422c..b259cf3e 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -4,4 +4,4 @@ - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center - = render 'moderation_queue/button_box', comment_btn_params: @comment_btn_params + = render 'moderation_queue/button_box', btn_params: @btn_params diff --git a/config/locales/es.yml b/config/locales/es.yml index ddf8f7f7..feca0897 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -12,9 +12,11 @@ es: profile_name: Nombre de la Cuenta profile_id: ID profile_published: Publicada + profile_summary: Resumen profile_button_box: - text_deny: Bloquear que te siga - text_allow: Permitir que te siga + text_approve: Aprovar siempre + text_check: Revisar siempre + text_deny: Bloquear text_report: Reportar button_box: text_pause: Pausa From cfae99ca7b3a001c735a45ac207288d8f57f606d Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 2 Feb 2024 15:06:36 -0300 Subject: [PATCH 351/814] feat: agregada botonera instancias #15081 --- app/controllers/application_controller.rb | 5 +++++ config/locales/es.yml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ba5dd4bd..fd714a41 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -54,6 +54,11 @@ class ApplicationController < ActionController::Base [t('moderation_queue.profile_button_box.text_check'), 'btn-outline-success', ''], [t('moderation_queue.profile_button_box.text_deny'), 'bg-blue white', ''], [t('moderation_queue.profile_button_box.text_report'), 'btn-danger', '']] + + #botones de instances (instancias) + @instances_btn_params = [[t('moderation_queue.instances_button_box.text_check'), 'btn-outline-success', ''], + [t('moderation_queue.instances_button_box.text_allow'), 'btn-success', ''], + [t('moderation_queue.instances_button_box.text_deny'), 'btn-danger', '']] end def notify_unconfirmed_email diff --git a/config/locales/es.yml b/config/locales/es.yml index feca0897..476d75b3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -28,6 +28,10 @@ es: text_order: Ordenar por text_show: Ver text_checked: Con los marcados + instances_button_box: + text_check: Moderar caso por caso + text_allow: Permitir todo + text_deny: Bloquear instancia dark: Oscuro es: Castellano en: English From 40346df76dd0c047dee905091a8223ec9d35f7a4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 12:22:23 -0300 Subject: [PATCH 352/814] fix: movidas arrays de parametros de botones y filtros a helper moderation_queue_helper.rb #15077 --- app/controllers/application_controller.rb | 26 +--------- .../moderation_queue_controller.rb | 2 - app/controllers/posts_controller.rb | 1 - app/helpers/moderation_queue_helper.rb | 47 +++++++++++++++++++ .../moderation_queue/_comment_filter_box.haml | 6 --- app/views/moderation_queue/_comments.haml | 4 +- app/views/moderation_queue/_filter_base.haml | 7 ++- app/views/moderation_queue/_filter_box.haml | 6 +++ .../moderation_queue/_remote_profile.haml | 1 + app/views/posts/_moderation_queue.haml | 4 +- config/locales/es.yml | 7 ++- 11 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 app/helpers/moderation_queue_helper.rb delete mode 100644 app/views/moderation_queue/_comment_filter_box.haml create mode 100644 app/views/moderation_queue/_filter_box.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fd714a41..f673ee83 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,31 +36,7 @@ class ApplicationController < ActionController::Base activity['attributedTo'] = @remote_profile end end - - # parámetros de botones: - # text: [texto del botón] - # class: [clases css] - # href: [href del botón] - def botoneras_moderation_queue - # botones de comentarios - @btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], - [t('moderation_queue.button_box.text_reject'), 'btn-primary', ''], - [t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''], - [t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''], - [t('moderation_queue.button_box.text_report'), 'btn-danger', '']] - - #botones de remote_profile (cuentas) - @profile_btn_params = [[t('moderation_queue.profile_button_box.text_approve'), 'btn-success', ''], - [t('moderation_queue.profile_button_box.text_check'), 'btn-outline-success', ''], - [t('moderation_queue.profile_button_box.text_deny'), 'bg-blue white', ''], - [t('moderation_queue.profile_button_box.text_report'), 'btn-danger', '']] - - #botones de instances (instancias) - @instances_btn_params = [[t('moderation_queue.instances_button_box.text_check'), 'btn-outline-success', ''], - [t('moderation_queue.instances_button_box.text_allow'), 'btn-success', ''], - [t('moderation_queue.instances_button_box.text_deny'), 'btn-danger', '']] - end - + def notify_unconfirmed_email return unless current_usuarie return if current_usuarie.confirmed? diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 5141990e..4a65f136 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -9,13 +9,11 @@ class ModerationQueueController < ApplicationController @moderation_queue.each do |activity| activity['attributedTo'] = @remote_profile end - botoneras_moderation_queue end # Perfil remoto de usuarie def remote_profile @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) - botoneras_moderation_queue end # todon.nl está usando /api/v2/instance diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 36d17339..5be56acc 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -83,7 +83,6 @@ class PostsController < ApplicationController breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' dummy_data - botoneras_moderation_queue end def update diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb new file mode 100644 index 00000000..9c0a3ced --- /dev/null +++ b/app/helpers/moderation_queue_helper.rb @@ -0,0 +1,47 @@ +module ModerationQueueHelper + + # parámetros de botones: + # text: [texto del botón] + # class: [clases css] + # href: [href del botón] + def botoneras_moderation_queue + # botones de comentarios + @btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], + [t('moderation_queue.button_box.text_reject'), 'btn-primary', ''], + [t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''], + [t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''], + [t('moderation_queue.button_box.text_report'), 'btn-danger', '']] + + #botones de remote_profile (cuentas) + @profile_btn_params = [[t('moderation_queue.profile_button_box.text_approve'), 'btn-success', ''], + [t('moderation_queue.profile_button_box.text_check'), 'btn-outline-success', ''], + [t('moderation_queue.profile_button_box.text_deny'), 'bg-blue white', ''], + [t('moderation_queue.profile_button_box.text_report'), 'btn-danger', '']] + + #botones de instances (instancias) + @instances_btn_params = [[t('moderation_queue.instances_button_box.text_check'), 'btn-outline-success', ''], + [t('moderation_queue.instances_button_box.text_allow'), 'btn-success', ''], + [t('moderation_queue.instances_button_box.text_deny'), 'btn-danger', '']] + end + + # parámetros de filtros: + # text: [texto del botón] + # href: [href del botón] + def filtros_moderation_queue + @comment_filter_params = { + t('moderation_queue.filter_box.text_checked') => + [ + [t('moderation_queue.filter_box.submenu_pause'), '/sutty.nl'], + [t('moderation_queue.filter_box.submenu_reject'), '#reject'], + [t('moderation_queue.filter_box.submenu_accept'),'#accept'] + ], + t('moderation_queue.filter_box.text_show') => + [ + [t('moderation_queue.filter_box.submenu_pause'), '#pause'], + [t('moderation_queue.filter_box.submenu_reject'), '#reject'], + [t('moderation_queue.filter_box.submenu_accept'),'#accept'], + [t('moderation_queue.filter_box.submenu_report'), '#report'] + ] + } + end +end \ No newline at end of file diff --git a/app/views/moderation_queue/_comment_filter_box.haml b/app/views/moderation_queue/_comment_filter_box.haml deleted file mode 100644 index e9abe602..00000000 --- a/app/views/moderation_queue/_comment_filter_box.haml +++ /dev/null @@ -1,6 +0,0 @@ --# Componente Caja de Filtros - -.d-flex.py-2.justify-content-center - = render 'moderation_queue/filter_base', text: t('.text_checked') - = render 'moderation_queue/filter_base', text: t('.text_show') - = render 'moderation_queue/filter_base', text: t('.text_order') \ No newline at end of file diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index fb83fbd9..217919bd 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,4 +1,6 @@ -= render 'moderation_queue/comment_filter_box' +- filtros_moderation_queue +- botoneras_moderation_queue += render 'moderation_queue/filter_box', filter_params: @comment_filter_params - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml index 0b63e59b..01d50641 100644 --- a/app/views/moderation_queue/_filter_base.haml +++ b/app/views/moderation_queue/_filter_base.haml @@ -1,8 +1,7 @@ -# Componente Filtro .dropdown.mx-4 %button#dropdownMenuButton.btn.btn-outline-secondary.dropdown-toggle{:type => "button", "data-toggle" => "dropdown", "aria-haspopup" => "true", "aria-expanded" => "false"} - %span #{text} + %span= text .dropdown-menu{"aria-labelledby" => "dropdownMenuButton"} - %a.dropdown-item{ href: '#' } Action - %a.dropdown-item{ href: '#' } Another action - %a.dropdown-item{ href: '#' } Something else here + - menu.each do |subm| + %a.dropdown-item{ href: subm[1] } subm[0] diff --git a/app/views/moderation_queue/_filter_box.haml b/app/views/moderation_queue/_filter_box.haml new file mode 100644 index 00000000..4ebef670 --- /dev/null +++ b/app/views/moderation_queue/_filter_box.haml @@ -0,0 +1,6 @@ +-# Componente Caja de Filtros + +.d-flex.py-2.justify-content-center + - filter_params.each do |filter, submenu| + = render 'moderation_queue/filter_base', text: filter, menu: submenu + diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 94737a34..548e2d5b 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,6 +1,7 @@ -# Componente Remote_Profile .flex.py-2.mx-2.text-center + - botoneras_moderation_queue %h4.mb-2= t('.profile_name') + ': ' + remote_profile['name'] %h5= t('.profile_id') + ': ' + remote_profile['id'] %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index b259cf3e..34af2ac6 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,6 +1,8 @@ .flex %h3.text-center.py-2 Comentarios - = render 'moderation_queue/comment_filter_box' + - botoneras_moderation_queue + - filtros_moderation_queue + = render 'moderation_queue/filter_box', filter_params: @comment_filter_params - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center diff --git a/config/locales/es.yml b/config/locales/es.yml index 476d75b3..20696af0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -24,10 +24,13 @@ es: text_accept: Aceptar Publicación text_reply: Responder text_report: Reportar - comment_filter_box: - text_order: Ordenar por + filter_box: text_show: Ver text_checked: Con los marcados + submenu_pause: Pausado + submenu_reject: Rechazado + submenu_accept: Aceptado + submenu_report: Reportado instances_button_box: text_check: Moderar caso por caso text_allow: Permitir todo From c668c3ad3f735760fd05a9fce9a49af3c201d78a Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 12:30:13 -0300 Subject: [PATCH 353/814] fix: corregido submenu en partial filter_base #15079 --- app/views/moderation_queue/_filter_base.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml index 01d50641..67bb4b0c 100644 --- a/app/views/moderation_queue/_filter_base.haml +++ b/app/views/moderation_queue/_filter_base.haml @@ -4,4 +4,4 @@ %span= text .dropdown-menu{"aria-labelledby" => "dropdownMenuButton"} - menu.each do |subm| - %a.dropdown-item{ href: subm[1] } subm[0] + %a.dropdown-item{ href: subm[1] }= subm[0] From cfe90c531ea9be1429cf146db39df3ad0528c26e Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 13:03:29 -0300 Subject: [PATCH 354/814] feat: agregado filtros instancias #15083 --- app/helpers/moderation_queue_helper.rb | 16 ++++++++++++++++ app/views/moderation_queue/_accounts.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 6 ++++++ config/locales/es.yml | 2 ++ 4 files changed, 28 insertions(+) diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb index 9c0a3ced..16be2a51 100644 --- a/app/helpers/moderation_queue_helper.rb +++ b/app/helpers/moderation_queue_helper.rb @@ -28,6 +28,7 @@ module ModerationQueueHelper # text: [texto del botón] # href: [href del botón] def filtros_moderation_queue + #filtros de comentarios @comment_filter_params = { t('moderation_queue.filter_box.text_checked') => [ @@ -43,5 +44,20 @@ module ModerationQueueHelper [t('moderation_queue.filter_box.submenu_report'), '#report'] ] } + + #filtros de instancias + @instances_filter_params = { + t('moderation_queue.filter_box.text_checked') => + [ + [t('moderation_queue.filter_box.submenu_case'), '#case_by_case'], + [t('moderation_queue.filter_box.submenu_allow'), '#allow'], + [t('moderation_queue.filter_box.submenu_reject'),'#reject'] + ], + t('moderation_queue.filter_box.text_show') => + [ + [t('moderation_queue.filter_box.submenu_allow'), '#allow'], + [t('moderation_queue.filter_box.submenu_reject'), '#reject'] + ] + } end end \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e69de29b..8ee71e7f 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -0,0 +1,4 @@ +- filtros_moderation_queue +- botoneras_moderation_queue + += render 'moderation_queue/button_box', btn_params: @profile_btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e69de29b..a814c1da 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -0,0 +1,6 @@ +- filtros_moderation_queue +- botoneras_moderation_queue + += render 'moderation_queue/filter_box', filter_params: @instances_filter_params + += render 'moderation_queue/button_box', btn_params: @instances_btn_params \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 20696af0..b4b7b1f4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -31,6 +31,8 @@ es: submenu_reject: Rechazado submenu_accept: Aceptado submenu_report: Reportado + submenu_case: Moderar caso por caso + submenu_allow: Permitir todo instances_button_box: text_check: Moderar caso por caso text_allow: Permitir todo From 600a87c5ec2d4d4b4af2f9d2c40505b75269bcc8 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 13:13:06 -0300 Subject: [PATCH 355/814] feat: agregado filtros de cuentas #15102 --- app/views/moderation_queue/_accounts.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 8ee71e7f..ae87a9d7 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,4 +1,6 @@ - filtros_moderation_queue - botoneras_moderation_queue += render 'moderation_queue/filter_box', filter_params: @instances_filter_params + = render 'moderation_queue/button_box', btn_params: @profile_btn_params \ No newline at end of file From 58ee39828a4cf048642c931b9c6c9607b6ceecfe Mon Sep 17 00:00:00 2001 From: f Date: Mon, 5 Feb 2024 13:16:57 -0300 Subject: [PATCH 356/814] feat: dropdown #15097 implement #15097 --- .../controllers/dropdown_controller.js | 106 ++++++++++++++++++ app/views/components/_dropdown.haml | 34 ++++++ app/views/components/_dropdown_item.haml | 4 + 3 files changed, 144 insertions(+) create mode 100644 app/javascript/controllers/dropdown_controller.js create mode 100644 app/views/components/_dropdown.haml create mode 100644 app/views/components/_dropdown_item.haml diff --git a/app/javascript/controllers/dropdown_controller.js b/app/javascript/controllers/dropdown_controller.js new file mode 100644 index 00000000..e2b657fd --- /dev/null +++ b/app/javascript/controllers/dropdown_controller.js @@ -0,0 +1,106 @@ +import { Controller } from "stimulus"; + +// https://getbootstrap.com/docs/4.6/components/dropdowns/#single-button +export default class extends Controller { + static targets = ["dropdown", "button", "item"]; + + // Al iniciar el controlador + connect() { + // Llevar la cuenta del item con foco + this.data.set("item", -1); + + // Gestionar las teclas + this.keydownEvent = this.keydown.bind(this); + this.element.addEventListener("keydown", this.keydownEvent); + + // Gestionar el foco + this.focusinEvent = this.focusin.bind(this); + } + + // Al eliminar el controlador (al pasar a otra página) + disconnect() { + // Eliminar la gestión de teclas + this.element.removeEventListener("keydown", this.keydownEvent); + // Eliminar la gestión del foco + document.removeEventListener("focusin", this.focusinEvent); + } + + // Mostrar u ocultar + toggle(event) { + (this.buttonTarget.ariaExpanded === "false") ? this.show() : this.hide(); + } + + // Mostrar + show() { + this.buttonTarget.ariaExpanded = "true"; + this.element.classList.add("show"); + this.dropdownTarget.classList.add("show"); + + // Activar la gestión del foco + document.addEventListener("focusin", this.focusinEvent); + } + + // Ocultar + hide() { + this.buttonTarget.ariaExpanded = "false"; + this.element.classList.remove("show"); + this.dropdownTarget.classList.remove("show"); + // Volver al inicio el foco de items + this.data.set("item", -1); + + // Desactivar la gestión del foco + document.removeEventListener("focusin", this.focusinEvent); + } + + // Gestionar el foco + focusin(event) { + const item = this.itemTargets.find(x => x === event.target); + + // Si el foco se coloca sobre elementos del controlador, no hacer + // nada + if (event.target === this.buttonTarget || item) { + // Si es un item, el comportamiento de las flechas verticales y el + // Tab tiene que ser igual + if (item) this.data.set("item", this.itemTargets.indexOf(item)); + + return; + } + + // De lo contrario, ocultar + this.hide(); + } + + // Gestionar las teclas + keydown(event) { + const initial = parseInt(this.data.get("item")); + let item = initial; + + switch (event.keyCode) { + case 27: + // Esc cierra el menú y devuelve el foco + this.hide(); + this.buttonTarget.focus(); + break; + case 38: + // Moverse hacia arriba con tope en el primer item + if (item > -1) item--; + + break; + case 40: + // Moverse hacia abajo con tope en el último ítem, si el + // dropdown estaba cerrado, abrirlo. + if (item === -1) this.show(); + if (item <= this.itemTargets.length) item++; + + break; + } + + // Si cambió la posición del ítem, darle foco y actualizar el + // contador. + if (initial !== item) { + this.itemTargets[item]?.focus(); + + this.data.set("item", item); + } + } +} diff --git a/app/views/components/_dropdown.haml b/app/views/components/_dropdown.haml new file mode 100644 index 00000000..54ddcffb --- /dev/null +++ b/app/views/components/_dropdown.haml @@ -0,0 +1,34 @@ +-# + @param :text [String] Contenido del botón + @param :button_classes [Array] Clases para el botón + @param :dropdown_classes [Array] Clases para el listado + @yield Un bloque que renderiza components/dropdown_item +- button_classes = local_assigns[:button_classes]&.join(' ') +- dropdown_classes = local_assigns[:dropdown_classes]&.join(' ') + +.btn-group{ + data: { + controller: 'dropdown' + } + } + %button.btn.dropdown-toggle{ + type: 'button', + class: button_classes, + data: { + toggle: 'true', + display: 'static', + action: 'dropdown#toggle', + target: 'dropdown.button' + }, + aria: { + expanded: 'false' + } + } + = text + .dropdown-menu{ + class: dropdown_classes, + data: { + target: 'dropdown.dropdown' + } + } + = yield diff --git a/app/views/components/_dropdown_item.haml b/app/views/components/_dropdown_item.haml new file mode 100644 index 00000000..3f79403d --- /dev/null +++ b/app/views/components/_dropdown_item.haml @@ -0,0 +1,4 @@ +-# + @param :text [String] Contenido del link + @param :path [String] Link += link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' } From f9952792987bd12ec81ab4542d5c7647b5c1121d Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 14:51:17 -0300 Subject: [PATCH 357/814] fix: corregidos filtros desplegables de comentarios, cuentas e instancias #15097 --- app/views/moderation_queue/_accounts.haml | 9 ++++++++- app/views/moderation_queue/_comments.haml | 13 +++++++++++-- app/views/moderation_queue/_filter_base.haml | 7 ------- app/views/moderation_queue/_filter_box.haml | 6 ------ app/views/moderation_queue/_instances.haml | 10 ++++++++-- app/views/moderation_queue/_remote_profile.haml | 14 +++++++++++++- app/views/posts/_moderation_queue.haml | 13 +++++++++++-- 7 files changed, 51 insertions(+), 21 deletions(-) delete mode 100644 app/views/moderation_queue/_filter_base.haml delete mode 100644 app/views/moderation_queue/_filter_box.haml diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index ae87a9d7..6a371eff 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,13 @@ - filtros_moderation_queue - botoneras_moderation_queue -= render 'moderation_queue/filter_box', filter_params: @instances_filter_params +.d-flex.py-2.justify-content-center + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' = render 'moderation_queue/button_box', btn_params: @profile_btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 217919bd..3daddf44 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,6 +1,15 @@ -- filtros_moderation_queue - botoneras_moderation_queue -= render 'moderation_queue/filter_box', filter_params: @comment_filter_params +.d-flex.py-2.justify-content-center + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' + - @moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile diff --git a/app/views/moderation_queue/_filter_base.haml b/app/views/moderation_queue/_filter_base.haml deleted file mode 100644 index 67bb4b0c..00000000 --- a/app/views/moderation_queue/_filter_base.haml +++ /dev/null @@ -1,7 +0,0 @@ --# Componente Filtro -.dropdown.mx-4 - %button#dropdownMenuButton.btn.btn-outline-secondary.dropdown-toggle{:type => "button", "data-toggle" => "dropdown", "aria-haspopup" => "true", "aria-expanded" => "false"} - %span= text - .dropdown-menu{"aria-labelledby" => "dropdownMenuButton"} - - menu.each do |subm| - %a.dropdown-item{ href: subm[1] }= subm[0] diff --git a/app/views/moderation_queue/_filter_box.haml b/app/views/moderation_queue/_filter_box.haml deleted file mode 100644 index 4ebef670..00000000 --- a/app/views/moderation_queue/_filter_box.haml +++ /dev/null @@ -1,6 +0,0 @@ --# Componente Caja de Filtros - -.d-flex.py-2.justify-content-center - - filter_params.each do |filter, submenu| - = render 'moderation_queue/filter_base', text: filter, menu: submenu - diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a814c1da..15b933d6 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,6 +1,12 @@ -- filtros_moderation_queue - botoneras_moderation_queue -= render 'moderation_queue/filter_box', filter_params: @instances_filter_params +.d-flex.py-2.justify-content-center + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' = render 'moderation_queue/button_box', btn_params: @instances_btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 548e2d5b..7256f41d 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -2,7 +2,19 @@ .flex.py-2.mx-2.text-center - botoneras_moderation_queue - %h4.mb-2= t('.profile_name') + ': ' + remote_profile['name'] + + .d-flex.py-2.justify-content-center + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' + + %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] %h5= t('.profile_id') + ': ' + remote_profile['id'] %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %h5= t('.profile_summary') + ':' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 34af2ac6..f805dfe8 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,8 +1,17 @@ .flex %h3.text-center.py-2 Comentarios - botoneras_moderation_queue - - filtros_moderation_queue - = render 'moderation_queue/filter_box', filter_params: @comment_filter_params + .d-flex.py-2.justify-content-center + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' + = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' + = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' + - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center From 6374a616d49f725f273da08bd44bbb7b5e209725 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 15:22:28 -0300 Subject: [PATCH 358/814] feat: agregado componente listas de bloqueo de instancias #15103 --- app/views/moderation_queue/_block_lists.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 6 +++++- config/locales/es.yml | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 app/views/moderation_queue/_block_lists.haml diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml new file mode 100644 index 00000000..186452fa --- /dev/null +++ b/app/views/moderation_queue/_block_lists.haml @@ -0,0 +1,4 @@ +.flex + .card + .card-body + %h4.text-center.red= t('moderation_queue.instances.block_lists') \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 15b933d6..57d4be34 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,4 +9,8 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' -= render 'moderation_queue/button_box', btn_params: @instances_btn_params \ No newline at end of file += render 'moderation_queue/button_box', btn_params: @instances_btn_params + +%h3.cyan.mt-5= t('moderation_queue.instances.title') +%p.pb-2= t('moderation_queue.instances.description') += render 'moderation_queue/block_lists' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index b4b7b1f4..6c608fff 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -37,6 +37,10 @@ es: text_check: Moderar caso por caso text_allow: Permitir todo text_deny: Bloquear instancia + instances: + title: Mis listas de bloqueo + description: Descripción de listas de bloqueo + block_lists: Listas de bloqueo dark: Oscuro es: Castellano en: English From db0364522db129ca62451ef2d81a7f80017f50d6 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 15:39:53 -0300 Subject: [PATCH 359/814] fix: agregado checkbox a compo listas de bloqueo #15103 --- app/views/moderation_queue/_block_lists.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 186452fa..55dc56d7 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,4 +1,5 @@ .flex .card - .card-body - %h4.text-center.red= t('moderation_queue.instances.block_lists') \ No newline at end of file + .card-body + %input{type: 'checkbox', value: '', class: 'ml-5'} + %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') \ No newline at end of file From b949855f08f6b2dfdc7fed3f0255eabfa2429f43 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 5 Feb 2024 16:19:35 -0300 Subject: [PATCH 360/814] feat: creado componente lista personalizada de bloqueo de instancias #15104 --- app/views/moderation_queue/_block_instances_textarea.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 3 ++- config/locales/es.yml | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 app/views/moderation_queue/_block_instances_textarea.haml diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml new file mode 100644 index 00000000..42001504 --- /dev/null +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -0,0 +1,4 @@ +.form-group + .d-flex.flex-column.mt-5 + %textarea.red.mb-3{name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } + %button.col-4.offset-md-8.rounded{type: 'submit', class: 'btn btn-primary'}= t('moderation_queue.instances.submit') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 57d4be34..c03055fa 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -13,4 +13,5 @@ %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') -= render 'moderation_queue/block_lists' \ No newline at end of file += render 'moderation_queue/block_lists' += render 'moderation_queue/block_instances_textarea' \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index 6c608fff..96f068f3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -41,6 +41,8 @@ es: title: Mis listas de bloqueo description: Descripción de listas de bloqueo block_lists: Listas de bloqueo + custom_block: Lista personalizada de bloqueo + submit: Guardar lista de bloqueo dark: Oscuro es: Castellano en: English From fc99ec79d3bd74d01084b25b3c25baa1b5ef2ca2 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 6 Feb 2024 12:57:42 -0300 Subject: [PATCH 361/814] fix: correciones de CI varias --- app/views/layouts/_details.haml | 4 ++-- .../moderation_queue/_block_instances_textarea.haml | 5 +++-- app/views/moderation_queue/_block_lists.haml | 2 +- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_button_box.haml | 2 +- app/views/moderation_queue/_comment.haml | 10 +++++----- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_instances.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 2 +- app/views/moderation_queue/index.haml | 5 +---- app/views/posts/_moderation_queue.haml | 2 +- 11 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 4fe4d2af..1fe8d2ec 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,6 +1,6 @@ -# Detail Cola de Moderación %details.details.py-2 - %summary + %summary %h3.py-2.text-center= @summary - = yield \ No newline at end of file + = yield diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 42001504..22a63c39 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,5 @@ .form-group .d-flex.flex-column.mt-5 - %textarea.red.mb-3{name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col-4.offset-md-8.rounded{type: 'submit', class: 'btn btn-primary'}= t('moderation_queue.instances.submit') + %textarea.red.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } + %button.col-4.offset-md-8.rounded{ type: 'submit', class: 'btn btn-primary' }= t('moderation_queue.instances.submit') + diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 55dc56d7..669d451a 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,5 +1,5 @@ .flex .card .card-body - %input{type: 'checkbox', value: '', class: 'ml-5'} + %input{ type: 'checkbox', value: '', class: 'ml-5' } %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') \ No newline at end of file diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 5f4561ef..0f9d7c08 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%a.btn.btn-lg.rounded.mx-2{role: "button", href: href, class: @class} #{text} \ No newline at end of file +%a.btn.btn-lg.rounded.mx-2{role: 'button', href: href, class: @class} #{text} diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml index 46963b0f..8971a780 100644 --- a/app/views/moderation_queue/_button_box.haml +++ b/app/views/moderation_queue/_button_box.haml @@ -3,4 +3,4 @@ .d-flex.py-4.justify-content-center - btn_params.each do |btn| - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] \ No newline at end of file + = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d443802d..d3532734 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -2,17 +2,17 @@ .flex.mx-4.my-5 .row.no-gutters .col-1 - %input{type: "checkbox", id: ""} + %input{ type: 'checkbox', id: '' } .col-10 .row.border.border-white .col.col-1.border.border-white.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col.border.border-white %span.mr-2= t('.source_profile') - %a{:href => comment['attributedTo']}= profile['preferredUsername'] - .row.border.border-white + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + .row.border.border-white %p.mr-3= t('.reply_to') %span - %a{:href => comment['inReplyTo']}= comment['inReplyTo'] - .row.border.border-white + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + .row.border.border-white %p= sanitize comment['content'] diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 3daddf44..39c8cfae 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -10,7 +10,7 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' -- @moderation_queue.each do |comment| +- moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile = render 'moderation_queue/button_box', btn_params: @btn_params \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index c03055fa..811aeaec 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -14,4 +14,4 @@ %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') = render 'moderation_queue/block_lists' -= render 'moderation_queue/block_instances_textarea' \ No newline at end of file += render 'moderation_queue/block_instances_textarea' diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 7256f41d..b50d63e6 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -15,7 +15,7 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] - %h5= t('.profile_id') + ': ' + remote_profile['id'] + %h5= t('.profile_id') + ': ' + remote_profile['id'] %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %h5= t('.profile_summary') + ':' %p= sanitize remote_profile['summary'] diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index d89c30b4..1a9838de 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -2,13 +2,10 @@ .col-md-8 - @summary = t('moderation_queue.index.instances') = render 'layouts/details', summary: @summary do - = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue - @summary = t('moderation_queue.index.accounts') = render 'layouts/details', summary: @summary do = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue - @summary = t('moderation_queue.index.comments') = render 'layouts/details', summary: @summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue - - - diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index f805dfe8..34e30538 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -11,7 +11,7 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' - + - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile .row.d-flex.justify-content-center From 462d9a698eb69db27ec01bd1d4b2a36c119d9284 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 13:56:20 -0300 Subject: [PATCH 362/814] para pullear --- app/views/moderation_queue/_accounts.haml | 3 +++ app/views/moderation_queue/_instances.haml | 1 + 2 files changed, 4 insertions(+) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e69de29b..5250ae87 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -0,0 +1,3 @@ += render 'moderation_queue/comment_filter_box' +- @moderation_queue.each do |comment| + = render 'account', comment: comment, profile: @remote_profile \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e69de29b..e279f484 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -0,0 +1 @@ += render 'moderation_queue/comment_filter_box' From c8267c44e85369a9d1ac9319b3816bcc4fa69934 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 14:08:15 -0300 Subject: [PATCH 363/814] =?UTF-8?q?fix:=20error=20de=20merge=20y=20error?= =?UTF-8?q?=20de=20indentaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 0 app/views/moderation_queue/_accounts.haml | 3 +-- app/views/moderation_queue/_instances.haml | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 app/views/moderation_queue/_account.haml diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml new file mode 100644 index 00000000..e69de29b diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 9300665b..26485119 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,5 @@ -= render 'moderation_queue/comment_filter_box' - @moderation_queue.each do |comment| - = render 'account', comment: comment, profile: @remote_profile + = render 'account', comment: comment, profile: @remote_profile - filtros_moderation_queue - botoneras_moderation_queue diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1d083d27..811aeaec 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,4 +1,3 @@ -= render 'moderation_queue/comment_filter_box' - botoneras_moderation_queue .d-flex.py-2.justify-content-center From 6b0d2ded91f2dbbb7286457ae3b094af8d87a130 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 16:50:26 -0300 Subject: [PATCH 364/814] =?UTF-8?q?feat:=20apartado=20de=20cuentas=20dentr?= =?UTF-8?q?o=20de=20actividades=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 10 +++------- app/views/moderation_queue/_account.haml | 2 ++ app/views/moderation_queue/_accounts.haml | 5 ++--- config/locales/es.yml | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 4a65f136..eec0c70f 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -4,21 +4,17 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) - @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) - @moderation_queue.each do |activity| - activity['attributedTo'] = @remote_profile - end + dummy_data end # Perfil remoto de usuarie def remote_profile - @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) + dummy_data end # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances - @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) + dummy_data end end diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index e69de29b..751d0c0e 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -0,0 +1,2 @@ +%a{href: profile['id']}= profile['preferredUsername'] +%p= sanitize profile['summary'] \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 26485119..fcdfdce6 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,3 @@ -- @moderation_queue.each do |comment| - = render 'account', comment: comment, profile: @remote_profile -- filtros_moderation_queue - botoneras_moderation_queue .d-flex.py-2.justify-content-center @@ -12,4 +9,6 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' +- @moderation_queue.map{|c| c['attributedTo']}.uniq.each do |remote_profile| + = render 'account', profile: remote_profile = render 'moderation_queue/button_box', btn_params: @profile_btn_params diff --git a/config/locales/es.yml b/config/locales/es.yml index 96f068f3..8828ee9f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -14,7 +14,7 @@ es: profile_published: Publicada profile_summary: Resumen profile_button_box: - text_approve: Aprovar siempre + text_approve: Aprobar siempre text_check: Revisar siempre text_deny: Bloquear text_report: Reportar From ab1186d08a12c4adc10c3cb3f1b548b70b6030b1 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 17:22:44 -0300 Subject: [PATCH 365/814] =?UTF-8?q?feat:=20apartado=20de=20instancias=20de?= =?UTF-8?q?ntro=20de=20actividades=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_instance.haml | 11 +++++++++++ app/views/moderation_queue/_instances.haml | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 app/views/moderation_queue/_instance.haml diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml new file mode 100644 index 00000000..d3b56a03 --- /dev/null +++ b/app/views/moderation_queue/_instance.haml @@ -0,0 +1,11 @@ +- host = instance['domain'] +- host ||= instance['uri'] +- host = "https://#{host}" + + +%a{href: host}= instance['title'] +%p= instance['description'] +%span Users: +%span + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 811aeaec..88a1e11c 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,7 +9,9 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' -= render 'moderation_queue/button_box', btn_params: @instances_btn_params +- @instances.each do |instance| + = render 'moderation_queue/instance', instance: instance + = render 'moderation_queue/button_box', btn_params: @instances_btn_params %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') From f9a7d8d21ac031720d41fe0f6fce28475fc95304 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 6 Feb 2024 17:27:07 -0300 Subject: [PATCH 366/814] =?UTF-8?q?feat:=20t=C3=ADtulo=20para=20actividade?= =?UTF-8?q?s=20de=20moderaci=C3=B3n=20#15091?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 2 ++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 4 insertions(+) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 1a9838de..43b83b83 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,3 +1,5 @@ +.row.justify-content-center.mb-5 + %h1= t('moderation_queue.index.title') .row.justify-content-center .col-md-8 - @summary = t('moderation_queue.index.instances') diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b8bb92b..9b06a78d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,6 +1,7 @@ en: moderation_queue: index: + title: Moderation instances: Instances accounts: Accounts comments: Comments diff --git a/config/locales/es.yml b/config/locales/es.yml index 8828ee9f..f1b5f2e5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,6 +1,7 @@ es: moderation_queue: index: + title: Actividades de moderación instances: Instancias accounts: Cuentas comments: Comentarios From dbdce703c3e40065e7b9588e44ec38420e990bfd Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 14:42:25 -0300 Subject: [PATCH 367/814] fix: corregidos botones en comentarios, instancias y cuentas #15028 --- app/helpers/moderation_queue_helper.rb | 63 ------------------- app/views/moderation_queue/_accounts.haml | 15 ++++- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_button_box.haml | 6 -- app/views/moderation_queue/_comments.haml | 16 ++++- app/views/moderation_queue/_instances.haml | 14 ++++- .../moderation_queue/_remote_profile.haml | 15 ++++- app/views/posts/_moderation_queue.haml | 17 ++++- 8 files changed, 64 insertions(+), 84 deletions(-) delete mode 100644 app/helpers/moderation_queue_helper.rb delete mode 100644 app/views/moderation_queue/_button_box.haml diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb deleted file mode 100644 index 16be2a51..00000000 --- a/app/helpers/moderation_queue_helper.rb +++ /dev/null @@ -1,63 +0,0 @@ -module ModerationQueueHelper - - # parámetros de botones: - # text: [texto del botón] - # class: [clases css] - # href: [href del botón] - def botoneras_moderation_queue - # botones de comentarios - @btn_params = [[t('moderation_queue.button_box.text_pause'), 'btn-secondary', ''], - [t('moderation_queue.button_box.text_reject'), 'btn-primary', ''], - [t('moderation_queue.button_box.text_accept'), 'bg-blue white', ''], - [t('moderation_queue.button_box.text_reply'), 'btn-outline-primary', ''], - [t('moderation_queue.button_box.text_report'), 'btn-danger', '']] - - #botones de remote_profile (cuentas) - @profile_btn_params = [[t('moderation_queue.profile_button_box.text_approve'), 'btn-success', ''], - [t('moderation_queue.profile_button_box.text_check'), 'btn-outline-success', ''], - [t('moderation_queue.profile_button_box.text_deny'), 'bg-blue white', ''], - [t('moderation_queue.profile_button_box.text_report'), 'btn-danger', '']] - - #botones de instances (instancias) - @instances_btn_params = [[t('moderation_queue.instances_button_box.text_check'), 'btn-outline-success', ''], - [t('moderation_queue.instances_button_box.text_allow'), 'btn-success', ''], - [t('moderation_queue.instances_button_box.text_deny'), 'btn-danger', '']] - end - - # parámetros de filtros: - # text: [texto del botón] - # href: [href del botón] - def filtros_moderation_queue - #filtros de comentarios - @comment_filter_params = { - t('moderation_queue.filter_box.text_checked') => - [ - [t('moderation_queue.filter_box.submenu_pause'), '/sutty.nl'], - [t('moderation_queue.filter_box.submenu_reject'), '#reject'], - [t('moderation_queue.filter_box.submenu_accept'),'#accept'] - ], - t('moderation_queue.filter_box.text_show') => - [ - [t('moderation_queue.filter_box.submenu_pause'), '#pause'], - [t('moderation_queue.filter_box.submenu_reject'), '#reject'], - [t('moderation_queue.filter_box.submenu_accept'),'#accept'], - [t('moderation_queue.filter_box.submenu_report'), '#report'] - ] - } - - #filtros de instancias - @instances_filter_params = { - t('moderation_queue.filter_box.text_checked') => - [ - [t('moderation_queue.filter_box.submenu_case'), '#case_by_case'], - [t('moderation_queue.filter_box.submenu_allow'), '#allow'], - [t('moderation_queue.filter_box.submenu_reject'),'#reject'] - ], - t('moderation_queue.filter_box.text_show') => - [ - [t('moderation_queue.filter_box.submenu_allow'), '#allow'], - [t('moderation_queue.filter_box.submenu_reject'), '#reject'] - ] - } - end -end \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index fcdfdce6..825b77c2 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,5 +1,4 @@ -- botoneras_moderation_queue - +-# Filtros .d-flex.py-2.justify-content-center = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' @@ -11,4 +10,14 @@ - @moderation_queue.map{|c| c['attributedTo']}.uniq.each do |remote_profile| = render 'account', profile: remote_profile -= render 'moderation_queue/button_box', btn_params: @profile_btn_params + +-# Botones de Moderación +.d-flex.py-4.justify-content-center + - @class = 'btn-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' + - @class = 'btn-outline-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 0f9d7c08..41349ec5 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%a.btn.btn-lg.rounded.mx-2{role: 'button', href: href, class: @class} #{text} +%button.btn.btn-lg.rounded.mx-2{ href: href, class: @class } #{text} diff --git a/app/views/moderation_queue/_button_box.haml b/app/views/moderation_queue/_button_box.haml deleted file mode 100644 index 8971a780..00000000 --- a/app/views/moderation_queue/_button_box.haml +++ /dev/null @@ -1,6 +0,0 @@ --# Componente Botonera de Moderación - -.d-flex.py-4.justify-content-center - - btn_params.each do |btn| - - @class = btn[1] - = render 'moderation_queue/btn_base', href: btn[2], class: @class, text: btn[0] diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 39c8cfae..8bb11eec 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,4 +1,4 @@ -- botoneras_moderation_queue +-# Filtros .d-flex.py-2.justify-content-center = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' @@ -13,4 +13,16 @@ - moderation_queue.each do |comment| = render 'comment', comment: comment, profile: @remote_profile - = render 'moderation_queue/button_box', btn_params: @btn_params \ No newline at end of file + + -# Botones moderación + .d-flex.py-4.justify-content-center + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' + - @class = 'btn-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' + - @class = 'btn-outline-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 88a1e11c..7af106ee 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,5 +1,4 @@ -- botoneras_moderation_queue - +-# Filtros .d-flex.py-2.justify-content-center = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' @@ -11,7 +10,16 @@ - @instances.each do |instance| = render 'moderation_queue/instance', instance: instance - = render 'moderation_queue/button_box', btn_params: @instances_btn_params + + + -# Botones moderación + .d-flex.py-4.justify-content-center + - @class = 'btn-outline-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' + - @class = 'btn-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index b50d63e6..a972b051 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,8 +1,7 @@ -# Componente Remote_Profile .flex.py-2.mx-2.text-center - - botoneras_moderation_queue - + -# Filtros .d-flex.py-2.justify-content-center = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' @@ -19,4 +18,14 @@ %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %h5= t('.profile_summary') + ':' %p= sanitize remote_profile['summary'] - = render 'moderation_queue/button_box', btn_params: @profile_btn_params + +-# Botones de Moderación +.d-flex.py-4.justify-content-center + - @class = 'btn-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' + - @class = 'btn-outline-success' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 34e30538..e7bbfd22 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,6 +1,6 @@ .flex %h3.text-center.py-2 Comentarios - - botoneras_moderation_queue + -# Filtros .d-flex.py-2.justify-content-center = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' @@ -14,5 +14,16 @@ - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile - .row.d-flex.justify-content-center - = render 'moderation_queue/button_box', btn_params: @btn_params + + -# Botones moderación + .d-flex.py-4.justify-content-center + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' + - @class = 'btn-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' + - @class = 'bg-blue white' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' + - @class = 'btn-outline-primary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' + - @class = 'btn-danger' + = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' From 9ffd49aae2d116e6077341e20409b4f6a082590f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 15:03:48 -0300 Subject: [PATCH 368/814] fix: corregida vista remote_profile --- app/views/moderation_queue/_remote_profile.haml | 4 ++++ config/locales/es.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index a972b051..4a5e806f 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -19,6 +19,10 @@ %h5= t('.profile_summary') + ':' %p= sanitize remote_profile['summary'] + = render 'moderation_queue/comments', moderation_queue: @moderation_queue + +%h3.text-center.pt-4= t('.profile') +%h4.my-2.text-center= t('.profile_name') + ': ' + remote_profile['name'] -# Botones de Moderación .d-flex.py-4.justify-content-center - @class = 'btn-success' diff --git a/config/locales/es.yml b/config/locales/es.yml index f1b5f2e5..1127f357 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -9,7 +9,7 @@ es: source_profile: Cuenta de Origen reply_to: En respuesta a remote_profile: - profile: Cuentas + profile: Cuenta de Origen profile_name: Nombre de la Cuenta profile_id: ID profile_published: Publicada From 60950400086691f7cb38d3356baa25a773dfef2f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 15:06:04 -0300 Subject: [PATCH 369/814] fix: corregidos filtros vista remote_profile --- app/views/moderation_queue/_remote_profile.haml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 4a5e806f..6afa2ed0 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,17 +1,6 @@ -# Componente Remote_Profile .flex.py-2.mx-2.text-center - -# Filtros - .d-flex.py-2.justify-content-center - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] %h5= t('.profile_id') + ': ' + remote_profile['id'] From 471b82969078e24db1b1243349f57fe6438bc5f2 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 7 Feb 2024 16:24:52 -0300 Subject: [PATCH 370/814] feat: actualizar cliente de DP --- Gemfile | 2 +- Gemfile.lock | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 466ec079..80051e93 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,7 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' -gem 'distributed-press-api-client', '~> 0.3.0rc0' +gem 'distributed-press-api-client', '~> 0.4.0rc0' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 78563c84..90bf6d98 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -157,11 +157,12 @@ GEM devise_invitable (2.0.8) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.3.0rc0) + distributed-press-api-client (0.4.0rc0) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema httparty (~> 0.18) + httparty-cache json (~> 2.1, >= 2.1.0) jwt (~> 2.6.0) dotenv (2.8.1) @@ -259,6 +260,8 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) + httparty-cache (0.0.1) + httparty (~> 0.18) i18n (1.14.1) concurrent-ruby (~> 1.0) icalendar (2.8.0) @@ -600,7 +603,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.3.0rc0) + distributed-press-api-client (~> 0.4.0rc0) dotenv-rails down ed25519 From d5bfbc578f9751d778695eb4c0c99b55fe6a4ba9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 17:12:00 -0300 Subject: [PATCH 371/814] fix: correcciones varias de CI --- app/views/moderation_queue/_accounts.haml | 3 ++- app/views/moderation_queue/_block_lists.haml | 6 +++--- app/views/moderation_queue/_instance.haml | 7 +++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 825b77c2..5c58f88b 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -8,7 +8,7 @@ = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' -- @moderation_queue.map{|c| c['attributedTo']}.uniq.each do |remote_profile| +- @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| = render 'account', profile: remote_profile -# Botones de Moderación @@ -21,3 +21,4 @@ = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - @class = 'btn-danger' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' + \ No newline at end of file diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 669d451a..fdb3f044 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,5 +1,5 @@ -.flex - .card +.flex + .card .card-body %input{ type: 'checkbox', value: '', class: 'ml-5' } - %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') \ No newline at end of file + %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index d3b56a03..80114985 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -2,10 +2,9 @@ - host ||= instance['uri'] - host = "https://#{host}" - -%a{href: host}= instance['title'] +%a{ href: host }= instance['title'] %p= instance['description'] %span Users: %span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') From a32a3ce7db29636ba854eecea3d5bc18d22d41cc Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 7 Feb 2024 17:59:57 -0300 Subject: [PATCH 372/814] fix: corregidos colores de botones y details --- app/assets/stylesheets/application.scss | 19 +++---------------- app/views/moderation_queue/_accounts.haml | 8 ++++---- .../_block_instances_textarea.haml | 2 +- app/views/moderation_queue/_comments.haml | 8 ++++---- app/views/moderation_queue/_instances.haml | 10 +++++----- .../moderation_queue/_remote_profile.haml | 8 ++++---- app/views/posts/_moderation_queue.haml | 8 ++++---- 7 files changed, 25 insertions(+), 38 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index c0a666ab..836d647f 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -3,7 +3,6 @@ $white: white; $grey: grey; $cyan: #13fefe; $magenta: #f206f9; -$blue: blue; $colors: ( "black": $black, @@ -15,7 +14,6 @@ $colors: ( // Redefinir variables de Bootstrap $primary: $magenta; $secondary: $black; -$info: $blue; $jumbotron-bg: transparent; $enable-rounded: false; $form-feedback-valid-color: $black; @@ -569,26 +567,15 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); &::after { content: '▶'; - font-size: 2rem; + font-size: 1.7rem; position: absolute; left: 97%; - bottom: 2%; - transform: rotate(55deg); - color: $magenta - } - - &:focus { - background-color: #13FEFE; - color: black + bottom: 3%; + transform: rotate(58deg); } } .details[open] > summary::after { transform: rotate(90deg) translatey(-0.1em); - color: $magenta } -.bg-blue { - background-color: $azul; -} - diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 5c58f88b..540d13a2 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -13,12 +13,12 @@ -# Botones de Moderación .d-flex.py-4.justify-content-center - - @class = 'btn-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-outline-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 22a63c39..4f294f0b 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,5 @@ .form-group .d-flex.flex-column.mt-5 %textarea.red.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col-4.offset-md-8.rounded{ type: 'submit', class: 'btn btn-primary' }= t('moderation_queue.instances.submit') + %button.col-4.offset-md-8.rounded{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 8bb11eec..d7d300b7 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -18,11 +18,11 @@ .d-flex.py-4.justify-content-center - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-outline-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 7af106ee..ed5d2404 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -14,12 +14,12 @@ -# Botones moderación .d-flex.py-4.justify-content-center - - @class = 'btn-outline-success' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - - @class = 'btn-success' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: @class, href: '' + - @class = 'btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: @class, href: '' %h3.cyan.mt-5= t('moderation_queue.instances.title') %p.pb-2= t('moderation_queue.instances.description') diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 6afa2ed0..755e96fd 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -14,11 +14,11 @@ %h4.my-2.text-center= t('.profile_name') + ': ' + remote_profile['name'] -# Botones de Moderación .d-flex.py-4.justify-content-center - - @class = 'btn-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-outline-success' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e7bbfd22..f2acb818 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -19,11 +19,11 @@ .d-flex.py-4.justify-content-center - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'bg-blue white' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-outline-primary' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-danger' + - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' From 33cf101b5953fa18c82047a30d1f8593ff6ff26a Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 8 Feb 2024 14:41:50 -0300 Subject: [PATCH 373/814] =?UTF-8?q?fix:=20quitada=20alineaci=C3=B3n=20cent?= =?UTF-8?q?rada=20varios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 4 ++-- app/controllers/posts_controller.rb | 2 +- app/views/layouts/_details.haml | 2 +- app/views/moderation_queue/_accounts.haml | 7 ++----- .../moderation_queue/_block_instances_textarea.haml | 5 +++-- app/views/moderation_queue/_block_lists.haml | 2 +- app/views/moderation_queue/_btn_base.haml | 2 +- app/views/moderation_queue/_comments.haml | 8 ++------ app/views/moderation_queue/_instances.haml | 12 +++++------- app/views/moderation_queue/_remote_profile.haml | 12 +++++------- app/views/moderation_queue/remote_profile.haml | 2 +- app/views/posts/_moderation_queue.haml | 6 +++--- 12 files changed, 27 insertions(+), 37 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 836d647f..5419bcdd 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -567,11 +567,11 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); &::after { content: '▶'; - font-size: 1.7rem; + font-size: 1.8rem; position: absolute; left: 97%; bottom: 3%; - transform: rotate(58deg); + transform: rotate(64deg); } } diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 5be56acc..99dc6f7d 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -38,7 +38,7 @@ class PostsController < ApplicationController @usuarie = site.usuarie? current_usuarie @site_stat = SiteStat.new(site) - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) + dummy_data end def show diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 1fe8d2ec..ac1d7c82 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,5 +2,5 @@ %details.details.py-2 %summary - %h3.py-2.text-center= @summary + %h3.py-2= @summary = yield diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 540d13a2..1885059e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,5 +1,5 @@ -# Filtros -.d-flex.py-2.justify-content-center +.d-flex.py-2 = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' @@ -12,13 +12,10 @@ = render 'account', profile: remote_profile -# Botones de Moderación -.d-flex.py-4.justify-content-center +.d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 4f294f0b..34eb1e5d 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,6 @@ .form-group .d-flex.flex-column.mt-5 - %textarea.red.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col-4.offset-md-8.rounded{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') + %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } + .d-flex.justify-content-end + %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index fdb3f044..577af12e 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -2,4 +2,4 @@ .card .card-body %input{ type: 'checkbox', value: '', class: 'ml-5' } - %h4.d-inline.red.ml-5= t('moderation_queue.instances.block_lists') + %h4.d-inline.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml index 41349ec5..7f6233cd 100644 --- a/app/views/moderation_queue/_btn_base.haml +++ b/app/views/moderation_queue/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%button.btn.btn-lg.rounded.mx-2{ href: href, class: @class } #{text} +%button.btn.btn-lg.mx-2{ href: href, class: @class }= text diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index d7d300b7..9a9c9454 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,5 @@ -# Filtros -.d-flex.py-2.justify-content-center +.d-flex.py-2 = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' @@ -15,14 +15,10 @@ = render 'comment', comment: comment, profile: @remote_profile -# Botones moderación - .d-flex.py-4.justify-content-center + .d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index ed5d2404..38f4ad51 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,5 +1,5 @@ -# Filtros -.d-flex.py-2.justify-content-center +.d-flex.py-2 = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' @@ -13,15 +13,13 @@ -# Botones moderación - .d-flex.py-4.justify-content-center - - @class = 'btn-secondary' + .d-flex.py-4 + - @class = 'btn btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: @class, href: '' -%h3.cyan.mt-5= t('moderation_queue.instances.title') -%p.pb-2= t('moderation_queue.instances.description') +%h3.mt-5= t('moderation_queue.instances.title') +%p= t('moderation_queue.instances.description') = render 'moderation_queue/block_lists' = render 'moderation_queue/block_instances_textarea' diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 755e96fd..965f8854 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,6 +1,6 @@ -# Componente Remote_Profile -.flex.py-2.mx-2.text-center +.flex.py-2.mx-2 %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] %h5= t('.profile_id') + ': ' + remote_profile['id'] @@ -10,15 +10,13 @@ = render 'moderation_queue/comments', moderation_queue: @moderation_queue -%h3.text-center.pt-4= t('.profile') -%h4.my-2.text-center= t('.profile_name') + ': ' + remote_profile['name'] +%h3.pt-4= t('.profile') +%h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] + -# Botones de Moderación -.d-flex.py-4.justify-content-center +.d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index 3eab5e35..ed66a394 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,3 @@ .flex - %h1.text-center= t('.profile') + %h1= t('.profile') = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index f2acb818..6db885bb 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,7 +1,7 @@ .flex - %h3.text-center.py-2 Comentarios + %h3.py-2 Comentarios -# Filtros - .d-flex.py-2.justify-content-center + .d-flex.py-2 = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' @@ -16,7 +16,7 @@ = render 'moderation_queue/comment', comment: comment, profile: @remote_profile -# Botones moderación - .d-flex.py-4.justify-content-center + .d-flex.py-4 - @class = 'btn-secondary' = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - @class = 'btn-secondary' From ffc3f4a72aa9514e061799d6b33971eba87de8ae Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 8 Feb 2024 15:02:09 -0300 Subject: [PATCH 374/814] fix: corregido texto de comentarios en componente moderation_queue --- app/views/posts/_moderation_queue.haml | 1 - config/locales/es.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 6db885bb..fa6adfef 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,5 +1,4 @@ .flex - %h3.py-2 Comentarios -# Filtros .d-flex.py-2 = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do diff --git a/config/locales/es.yml b/config/locales/es.yml index 1127f357..fd1626e3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -566,7 +566,7 @@ es: ar: 'árabe' posts: edit: - moderation_queue: Cola de Moderación + moderation_queue: Comentarios post: Contenido prev: Página anterior next: Página siguiente From 47de966f69a4558980080a1c5c97d6b8857aa0df Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 8 Feb 2024 17:59:10 -0300 Subject: [PATCH 375/814] fix: cambiadas variables globales por locales --- app/views/layouts/_details.haml | 2 +- app/views/moderation_queue/_comments.haml | 11 +---------- app/views/moderation_queue/index.haml | 14 +++++++------- app/views/posts/edit.haml | 8 ++++---- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index ac1d7c82..306986bf 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,5 +2,5 @@ %details.details.py-2 %summary - %h3.py-2= @summary + %h3.py-2= summary = yield diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 9a9c9454..e4285326 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,5 @@ -# Filtros -.d-flex.py-2 - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' += render 'moderation_queue/filter_box' - moderation_queue.each do |comment| diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 43b83b83..b361c085 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,13 +1,13 @@ .row.justify-content-center.mb-5 - %h1= t('moderation_queue.index.title') + %h1= t('.title') .row.justify-content-center .col-md-8 - - @summary = t('moderation_queue.index.instances') - = render 'layouts/details', summary: @summary do + - summary = t('.instances') + = render 'layouts/details', summary: summary do = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue - - @summary = t('moderation_queue.index.accounts') - = render 'layouts/details', summary: @summary do + - summary = t('.accounts') + = render 'layouts/details', summary: summary do = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue - - @summary = t('moderation_queue.index.comments') - = render 'layouts/details', summary: @summary do + - summary = t('.comments') + = render 'layouts/details', summary: summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 5234f257..2e46590e 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,8 +1,8 @@ .row.justify-content-center .col-md-8 - - @summary = t('posts.edit.post') - = render 'layouts/details', summary: @summary do + - summary = t('posts.edit.post') + = render 'layouts/details', summary: summary do = render 'posts/form', site: @site, post: @post - - @summary = t('posts.edit.moderation_queue') - = render 'layouts/details', summary: @summary do + - summary = t('posts.edit.moderation_queue') + = render 'layouts/details', summary: summary do = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue From 111f2d65030bae4ce010e26b09eac2bfdfe60c86 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 12:01:04 -0300 Subject: [PATCH 376/814] fix: creados componentes de filtros para comentarios, cuentas e instancias --- .../components/_comments_checked_submenu.haml | 3 ++ app/views/components/_comments_filters.haml | 6 +++ .../components/_comments_show_submenu.haml | 4 ++ .../_instances_checked_submenu.haml | 3 ++ app/views/components/_instances_filters.haml | 6 +++ .../components/_instances_show_submenu.haml | 2 + .../components/_profiles_checked_submenu.haml | 4 ++ app/views/components/_profiles_filters.haml | 6 +++ .../components/_profiles_show_submenu.haml | 3 ++ app/views/moderation_queue/_accounts.haml | 9 +--- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_instances.haml | 10 +--- app/views/posts/_moderation_queue.haml | 11 +---- config/locales/es.yml | 47 +++++++++++++++---- 14 files changed, 79 insertions(+), 37 deletions(-) create mode 100644 app/views/components/_comments_checked_submenu.haml create mode 100644 app/views/components/_comments_filters.haml create mode 100644 app/views/components/_comments_show_submenu.haml create mode 100644 app/views/components/_instances_checked_submenu.haml create mode 100644 app/views/components/_instances_filters.haml create mode 100644 app/views/components/_instances_show_submenu.haml create mode 100644 app/views/components/_profiles_checked_submenu.haml create mode 100644 app/views/components/_profiles_filters.haml create mode 100644 app/views/components/_profiles_show_submenu.haml diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml new file mode 100644 index 00000000..4998e5c7 --- /dev/null +++ b/app/views/components/_comments_checked_submenu.haml @@ -0,0 +1,3 @@ += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml new file mode 100644 index 00000000..7c453088 --- /dev/null +++ b/app/views/components/_comments_filters.haml @@ -0,0 +1,6 @@ +.d-flex.py-2 + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/comments_checked_submenu' + + = render 'components/dropdown', text: t('.text_show') do + = render 'components/comments_show_submenu' \ No newline at end of file diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml new file mode 100644 index 00000000..0308b926 --- /dev/null +++ b/app/views/components/_comments_show_submenu.haml @@ -0,0 +1,4 @@ += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_report'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml new file mode 100644 index 00000000..f0b76185 --- /dev/null +++ b/app/views/components/_instances_checked_submenu.haml @@ -0,0 +1,3 @@ += render 'components/dropdown_item', text: t('.submenu_case'), path: '/' += render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml new file mode 100644 index 00000000..213bb7c0 --- /dev/null +++ b/app/views/components/_instances_filters.haml @@ -0,0 +1,6 @@ +.d-flex.py-2 + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/instances_checked_submenu' + + = render 'components/dropdown', text: t('.text_show') do + = render 'components/comments_show_submenu' diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml new file mode 100644 index 00000000..1074cc3f --- /dev/null +++ b/app/views/components/_instances_show_submenu.haml @@ -0,0 +1,2 @@ += render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml new file mode 100644 index 00000000..8d8f8940 --- /dev/null +++ b/app/views/components/_profiles_checked_submenu.haml @@ -0,0 +1,4 @@ += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' += render 'components/dropdown_item', text: t('.submenu_block'), path: '/' diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml new file mode 100644 index 00000000..0088afef --- /dev/null +++ b/app/views/components/_profiles_filters.haml @@ -0,0 +1,6 @@ +.d-flex.py-2 + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/profiles_checked_submenu' + + = render 'components/dropdown', text: t('.text_show') do + = render 'components/profiles_show_submenu' \ No newline at end of file diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml new file mode 100644 index 00000000..2ba949b1 --- /dev/null +++ b/app/views/components/_profiles_show_submenu.haml @@ -0,0 +1,3 @@ += render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' += render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' += render 'components/dropdown_item', text: t('.submenu_block'), path: '/' \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 1885059e..e954d2f3 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,12 +1,5 @@ -# Filtros -.d-flex.py-2 - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' += render 'components/profiles_filters' - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| = render 'account', profile: remote_profile diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index e4285326..c5f7ae5d 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,5 @@ -# Filtros -= render 'moderation_queue/filter_box' += render 'components/comments_filters' - moderation_queue.each do |comment| diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 38f4ad51..e50a6e02 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,17 +1,9 @@ -# Filtros -.d-flex.py-2 - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_case'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_allow'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' += render 'components/instances_filters' - @instances.each do |instance| = render 'moderation_queue/instance', instance: instance - -# Botones moderación .d-flex.py-4 - @class = 'btn btn-secondary' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index fa6adfef..df17b1ff 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,15 +1,6 @@ .flex -# Filtros - .d-flex.py-2 - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_checked') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' - = render 'components/dropdown', text: t('moderation_queue.filter_box.text_show') do - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_pause'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_reject'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_accept'), path: '/' - = render 'components/dropdown_item', text: t('moderation_queue.filter_box.submenu_report'), path: '/' + = render 'components/comments_filters' - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: @remote_profile diff --git a/config/locales/es.yml b/config/locales/es.yml index fd1626e3..7cd59cbf 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,39 @@ es: + components: + instances_filters: + text_show: Ver + text_checked: Con los marcados + instances_checked_submenu: + submenu_case: Moderar caso por caso + submenu_allow: Permitir todo + submenu_reject: Rechazado + instances_show_submenu: + submenu_allow: Permitido + submenu_reject: Rechazado + comments_filters: + text_show: Ver + text_checked: Con los marcados + comments_checked_submenu: + submenu_pause: Pausado + submenu_accept: Aceptado + submenu_reject: Rechazado + comments_show_submenu: + submenu_pause: Pausado + submenu_accept: Aceptado + submenu_report: Reportado + submenu_reject: Rechazado + profiles_filters: + text_show: Ver + text_checked: Con los marcados + profiles_checked_submenu: + submenu_pause: Pausado + submenu_accept: Aceptado + submenu_reject: Rechazado + submenu_block: Bloqueado + profiles_show_submenu: + submenu_accept: Aceptado + submenu_block: Bloqueado + submenu_reject: Rechazado moderation_queue: index: title: Actividades de moderación @@ -25,15 +60,6 @@ es: text_accept: Aceptar Publicación text_reply: Responder text_report: Reportar - filter_box: - text_show: Ver - text_checked: Con los marcados - submenu_pause: Pausado - submenu_reject: Rechazado - submenu_accept: Aceptado - submenu_report: Reportado - submenu_case: Moderar caso por caso - submenu_allow: Permitir todo instances_button_box: text_check: Moderar caso por caso text_allow: Permitir todo @@ -44,6 +70,9 @@ es: block_lists: Listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo + comments_filter_box: + text_show: Ver + text_checked: Con los marcados dark: Oscuro es: Castellano en: English From 754538024efdde09cceaab35ea1680d3fe6d57c3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 13:17:00 -0300 Subject: [PATCH 377/814] feat: agregado componente checkbox --- app/views/components/_checkbox.haml | 2 ++ app/views/moderation_queue/_block_lists.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 app/views/components/_checkbox.haml diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml new file mode 100644 index 00000000..ccf22e84 --- /dev/null +++ b/app/views/components/_checkbox.haml @@ -0,0 +1,2 @@ +.custom-control.custom-checkbox + %input{ type: 'checkbox', id: '', class: '' } \ No newline at end of file diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml index 577af12e..14dd770e 100644 --- a/app/views/moderation_queue/_block_lists.haml +++ b/app/views/moderation_queue/_block_lists.haml @@ -1,5 +1,5 @@ .flex .card .card-body - %input{ type: 'checkbox', value: '', class: 'ml-5' } + = render 'components/checkbox' %h4.d-inline.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index d3532734..463f47c7 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -2,7 +2,7 @@ .flex.mx-4.my-5 .row.no-gutters .col-1 - %input{ type: 'checkbox', id: '' } + = render 'components/checkbox' .col-10 .row.border.border-white .col.col-1.border.border-white.mr-5 From 31294ccbc7f3bba6e61d99b23fc762bdbd9bd333 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 14:15:11 -0300 Subject: [PATCH 378/814] fix: movido componente block_lists a app/views/components y corregido es.yml --- app/views/components/_block_lists.haml | 7 +++++++ app/views/moderation_queue/_block_lists.haml | 5 ----- app/views/moderation_queue/_instances.haml | 10 +++++----- config/locales/es.yml | 3 ++- 4 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 app/views/components/_block_lists.haml delete mode 100644 app/views/moderation_queue/_block_lists.haml diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml new file mode 100644 index 00000000..7764dfa5 --- /dev/null +++ b/app/views/components/_block_lists.haml @@ -0,0 +1,7 @@ +-# Componente Listas de bloqueo de Instancias +.flex + .card + .card-body + .d-flex.flex-row + = render 'components/checkbox' + %h4.ml-5= t('.title') diff --git a/app/views/moderation_queue/_block_lists.haml b/app/views/moderation_queue/_block_lists.haml deleted file mode 100644 index 14dd770e..00000000 --- a/app/views/moderation_queue/_block_lists.haml +++ /dev/null @@ -1,5 +0,0 @@ -.flex - .card - .card-body - = render 'components/checkbox' - %h4.d-inline.ml-5= t('moderation_queue.instances.block_lists') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e50a6e02..fc249e46 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -6,12 +6,12 @@ -# Botones moderación .d-flex.py-4 - - @class = 'btn btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: @class, href: '' + - btn_class = 'btn btn-secondary' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: btn_class, href: '' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: btn_class, href: '' + = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: btn_class, href: '' %h3.mt-5= t('moderation_queue.instances.title') %p= t('moderation_queue.instances.description') -= render 'moderation_queue/block_lists' += render 'components/block_lists' = render 'moderation_queue/block_instances_textarea' diff --git a/config/locales/es.yml b/config/locales/es.yml index 7cd59cbf..4aad1cc7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -34,6 +34,8 @@ es: submenu_accept: Aceptado submenu_block: Bloqueado submenu_reject: Rechazado + block_lists: + title: Listas de bloqueo moderation_queue: index: title: Actividades de moderación @@ -67,7 +69,6 @@ es: instances: title: Mis listas de bloqueo description: Descripción de listas de bloqueo - block_lists: Listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo comments_filter_box: From 3f288ab6e4a7806c29d472dd71f34d8d8265dd2f Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 14:45:12 -0300 Subject: [PATCH 379/814] fix: creados componentes botoneras de comentarios, instancias y cuentas, y movidos a app/views/components --- app/views/components/_btn_base.haml | 3 ++ app/views/components/_checkbox.haml | 3 +- app/views/components/_comments_btn_box.haml | 9 ++++++ app/views/components/_instances_btn_box.haml | 6 ++++ app/views/components/_profiles_btn_box.haml | 7 +++++ app/views/moderation_queue/_accounts.haml | 6 +--- app/views/moderation_queue/_btn_base.haml | 3 -- app/views/moderation_queue/_comments.haml | 8 +---- app/views/moderation_queue/_instances.haml | 7 ++--- .../moderation_queue/_remote_profile.haml | 7 +---- app/views/moderation_queue/index.haml | 6 ++-- app/views/posts/_moderation_queue.haml | 11 +------ app/views/posts/edit.haml | 4 +-- config/locales/es.yml | 30 +++++++++---------- 14 files changed, 53 insertions(+), 57 deletions(-) create mode 100644 app/views/components/_btn_base.haml create mode 100644 app/views/components/_comments_btn_box.haml create mode 100644 app/views/components/_instances_btn_box.haml create mode 100644 app/views/components/_profiles_btn_box.haml delete mode 100644 app/views/moderation_queue/_btn_base.haml diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml new file mode 100644 index 00000000..2985d646 --- /dev/null +++ b/app/views/components/_btn_base.haml @@ -0,0 +1,3 @@ +-# Componente Botón general Moderación + +%button.btn.btn-lg.mx-2{ href: href, class: local_assigns[:class] }= text diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index ccf22e84..33630780 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,2 +1,3 @@ +-# Componente Checkbox .custom-control.custom-checkbox - %input{ type: 'checkbox', id: '', class: '' } \ No newline at end of file + %input{ type: 'checkbox', id: '', class: '' } diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml new file mode 100644 index 00000000..aa755dcc --- /dev/null +++ b/app/views/components/_comments_btn_box.haml @@ -0,0 +1,9 @@ +-# Componente Botonera de Comentarios + +.d-flex.py-4 +- btn_class = 'btn-secondary' += render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file diff --git a/app/views/components/_instances_btn_box.haml b/app/views/components/_instances_btn_box.haml new file mode 100644 index 00000000..854262c0 --- /dev/null +++ b/app/views/components/_instances_btn_box.haml @@ -0,0 +1,6 @@ +-# Componente botonera de moderación de Instancias + +- btn_class = 'btn btn-secondary' += render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_allow'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' \ No newline at end of file diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml new file mode 100644 index 00000000..2c63ce3a --- /dev/null +++ b/app/views/components/_profiles_btn_box.haml @@ -0,0 +1,7 @@ +-# Componente Botonera de Moderación de Cuentas (Remote_profile) + +- @class = 'btn-secondary' += render 'components/btn_base', text: t('.text_approve'), class: @class, href: '' += render 'components/btn_base', text: t('.text_check'), class: @class, href: '' += render 'components/btn_base', text: t('.text_deny'), class: @class, href: '' += render 'components/btn_base', text: t('.text_report'), class: @class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e954d2f3..e92c3a20 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -6,9 +6,5 @@ -# Botones de Moderación .d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' + = render 'components/profiles_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_btn_base.haml b/app/views/moderation_queue/_btn_base.haml deleted file mode 100644 index 7f6233cd..00000000 --- a/app/views/moderation_queue/_btn_base.haml +++ /dev/null @@ -1,3 +0,0 @@ --# Componente Botón general Moderación - -%button.btn.btn-lg.mx-2{ href: href, class: @class }= text diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index c5f7ae5d..d5f2b3bd 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -6,10 +6,4 @@ = render 'comment', comment: comment, profile: @remote_profile -# Botones moderación - .d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' \ No newline at end of file + = render 'components/comments_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index fc249e46..26caaeca 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,11 +5,8 @@ = render 'moderation_queue/instance', instance: instance -# Botones moderación - .d-flex.py-4 - - btn_class = 'btn btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_check'), class: btn_class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_allow'), class: btn_class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.instances_button_box.text_deny'), class: btn_class, href: '' + .d-flex.py-5 + = render 'components/instances_btn_box' %h3.mt-5= t('moderation_queue.instances.title') %p= t('moderation_queue.instances.description') diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 965f8854..ab29ae4d 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -14,9 +14,4 @@ %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] -# Botones de Moderación -.d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_approve'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_check'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_deny'), class: @class, href: '' - = render 'moderation_queue/btn_base', text: t('moderation_queue.profile_button_box.text_report'), class: @class, href: '' += render 'components/comments_btn_box' diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index b361c085..eae3b5a5 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,7 +1,7 @@ -.row.justify-content-center.mb-5 +.row.mb-5 %h1= t('.title') -.row.justify-content-center - .col-md-8 +.row + .col-md-10 - summary = t('.instances') = render 'layouts/details', summary: summary do = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index df17b1ff..e4a9683c 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -7,13 +7,4 @@ -# Botones moderación .d-flex.py-4 - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_pause'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reject'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_accept'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_reply'), class: @class, href: '' - - @class = 'btn-secondary' - = render 'moderation_queue/btn_base', text: t('moderation_queue.button_box.text_report'), class: @class, href: '' + = render 'components/comments_btn_box' diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 2e46590e..a83c72af 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,5 +1,5 @@ -.row.justify-content-center - .col-md-8 +.row + .col-md-10 - summary = t('posts.edit.post') = render 'layouts/details', summary: summary do = render 'posts/form', site: @site, post: @post diff --git a/config/locales/es.yml b/config/locales/es.yml index 4aad1cc7..868f8fc6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -36,6 +36,21 @@ es: submenu_reject: Rechazado block_lists: title: Listas de bloqueo + comments_btn_box: + text_pause: Pausa + text_reject: Rechazar + text_accept: Aceptar Publicación + text_reply: Responder + text_report: Reportar + instances_btn_box: + text_check: Moderar caso por caso + text_allow: Permitir todo + text_deny: Bloquear instancia + profiles_btn_box: + text_approve: Aprobar siempre + text_check: Revisar siempre + text_deny: Bloquear + text_report: Reportar moderation_queue: index: title: Actividades de moderación @@ -51,21 +66,6 @@ es: profile_id: ID profile_published: Publicada profile_summary: Resumen - profile_button_box: - text_approve: Aprobar siempre - text_check: Revisar siempre - text_deny: Bloquear - text_report: Reportar - button_box: - text_pause: Pausa - text_reject: Rechazar - text_accept: Aceptar Publicación - text_reply: Responder - text_report: Reportar - instances_button_box: - text_check: Moderar caso por caso - text_allow: Permitir todo - text_deny: Bloquear instancia instances: title: Mis listas de bloqueo description: Descripción de listas de bloqueo From ba26b505e499f0c2e139c5778c53c0c10607978f Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 15:03:47 -0300 Subject: [PATCH 380/814] =?UTF-8?q?fix:=20corregidos=20m=C3=A1rgenes=20en?= =?UTF-8?q?=20vistas=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 27 ++++++++++--------- .../moderation_queue/remote_profile.haml | 7 ++--- app/views/posts/edit.haml | 4 +-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index eae3b5a5..982a41c8 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -1,13 +1,14 @@ -.row.mb-5 - %h1= t('.title') -.row - .col-md-10 - - summary = t('.instances') - = render 'layouts/details', summary: summary do - = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue - - summary = t('.accounts') - = render 'layouts/details', summary: summary do - = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue - - summary = t('.comments') - = render 'layouts/details', summary: summary do - = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue +.row.justify-content-center + .col-md-8 + %h1= t('.title') + .row + .col + - summary = t('.instances') + = render 'layouts/details', summary: summary do + = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + - summary = t('.accounts') + = render 'layouts/details', summary: summary do + = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue + - summary = t('.comments') + = render 'layouts/details', summary: summary do + = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml index ed66a394..ba0fc257 100644 --- a/app/views/moderation_queue/remote_profile.haml +++ b/app/views/moderation_queue/remote_profile.haml @@ -1,3 +1,4 @@ -.flex - %h1= t('.profile') - = render 'moderation_queue/remote_profile', remote_profile: @remote_profile +.row.justify-content-center + .col-md-8 + %h1= t('.profile') + = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index a83c72af..2e46590e 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,5 +1,5 @@ -.row - .col-md-10 +.row.justify-content-center + .col-md-8 - summary = t('posts.edit.post') = render 'layouts/details', summary: summary do = render 'posts/form', site: @site, post: @post From 529711c47dbb823665a0f2685d0b7681792f3d9e Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 9 Feb 2024 16:54:16 -0300 Subject: [PATCH 381/814] fix: corregido compo _remote_profile para hacerlo semantico con dl --- app/views/moderation_queue/_remote_profile.haml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index ab29ae4d..fae38dec 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -1,12 +1,18 @@ -# Componente Remote_Profile .flex.py-2.mx-2 + %dl + %dt= t('.profile_name') + %dd= remote_profile['name'] - %h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] - %h5= t('.profile_id') + ': ' + remote_profile['id'] - %h5= t('.profile_published') + ': ' + remote_profile['published'].to_datetime.strftime('%m/%d/%Y') - %h5= t('.profile_summary') + ':' - %p= sanitize remote_profile['summary'] + %dt= t('.profile_id') + %dd= remote_profile['id'] + + %dt= t('.profile_published') + %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') + + %dt= t('.profile_summary') + %dd= remote_profile['summary'] = render 'moderation_queue/comments', moderation_queue: @moderation_queue From faf3bf3fcf6e590c0984ef0819febc01119b2592 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 12 Feb 2024 11:27:24 -0300 Subject: [PATCH 382/814] fix: corregido codigo de details en application.scss --- app/assets/stylesheets/application.scss | 27 ++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 5419bcdd..c05c49fe 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -559,7 +559,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } // details styles - +/* .details summary { list-style: none; cursor: default; @@ -578,4 +578,29 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); .details[open] > summary::after { transform: rotate(90deg) translatey(-0.1em); } +*/ + +.details { + summary { + list-style: none; + cursor: default; + position: relative; + } + summary::after { + content: '▶'; + font-size: 1.8rem; + position: absolute; + left: 97%; + bottom: 3%; + transform: rotate(64deg); + } +} + .details[open] { + & > summary { + &::after { + transform: rotate(90deg) translatey(-0.1em); + } + } + } + From 8bfdf3ed0a81fa5b332b2e53c0d7647325851a6a Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 12 Feb 2024 11:29:00 -0300 Subject: [PATCH 383/814] fix: corregido cursor de apertura de details --- app/assets/stylesheets/application.scss | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index c05c49fe..a411c124 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -559,26 +559,6 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } // details styles -/* -.details summary { - list-style: none; - cursor: default; - position: relative; - - &::after { - content: '▶'; - font-size: 1.8rem; - position: absolute; - left: 97%; - bottom: 3%; - transform: rotate(64deg); - } - } - -.details[open] > summary::after { - transform: rotate(90deg) translatey(-0.1em); - } -*/ .details { summary { @@ -592,7 +572,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); position: absolute; left: 97%; bottom: 3%; - transform: rotate(64deg); + transform: rotate(60deg); } } .details[open] { From d829b5b4ae8b5a7d6fd6ecd9f9b1f7bb675b40b1 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 12 Feb 2024 12:02:06 -0300 Subject: [PATCH 384/814] feat: agregada traducciones en en.yml --- config/locales/en.yml | 71 +++++++++++++++++++++++++++++++++++++++---- config/locales/es.yml | 4 +-- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b06a78d..b1243091 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,18 +1,77 @@ en: + components: + instances_filters: + text_show: Show + text_checked: With the checked + instances_checked_submenu: + submenu_case: Check case by case + submenu_allow: Allow everything + submenu_reject: Reject + instances_show_submenu: + submenu_allow: Allow + submenu_reject: Reject + comments_filters: + text_show: Sho + text_checked: With the checked + comments_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + comments_show_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_report: Report + submenu_reject: Reject + profiles_filters: + text_show: Show + text_checked: With the checked + profiles_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + submenu_block: Block + profiles_show_submenu: + submenu_accept: Accept + submenu_block: Block + submenu_reject: Reject + block_lists: + title: Block lists + comments_btn_box: + text_pause: Pause + text_reject: Reject + text_accept: Accept + text_reply: Reply + text_report: Report + instances_btn_box: + text_check: Check case by case + text_allow: Allow everything + text_deny: Block instance + profiles_btn_box: + text_approve: Always approve + text_check: Always check + text_deny: Block + text_report: Report moderation_queue: index: title: Moderation instances: Instances accounts: Accounts comments: Comments + comment: + source_profile: Source Profile + reply_to: Reply to remote_profile: user: Username - button_box: - text_pause: Pause - text_reject: Reject - text_accept: Accept Publication - text_reply: Reply - text_report: Report + profile: Profile + profile_name: Profile name + profile_id: ID + profile_published: Published + profile_summary: Summary + instances: + title: My block lists + description: Description + custom_block: Custom block lists + submit: Save block lists dark: Dark dir: ltr en: English diff --git a/config/locales/es.yml b/config/locales/es.yml index 868f8fc6..4b68f968 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -61,6 +61,7 @@ es: source_profile: Cuenta de Origen reply_to: En respuesta a remote_profile: + user: Nombre de usuario profile: Cuenta de Origen profile_name: Nombre de la Cuenta profile_id: ID @@ -71,9 +72,6 @@ es: description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo - comments_filter_box: - text_show: Ver - text_checked: Con los marcados dark: Oscuro es: Castellano en: English From fb19938361ca88216f7f94e74cb18e30213e08bf Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:38:34 -0300 Subject: [PATCH 385/814] fix: quitar bordes blancos de _comment.haml --- app/views/moderation_queue/_comment.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 463f47c7..26cfbe29 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -4,15 +4,15 @@ .col-1 = render 'components/checkbox' .col-10 - .row.border.border-white - .col.col-1.border.border-white.mr-5 + .row + .col.col-1.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') - .col.border.border-white + .col %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - .row.border.border-white + .row %p.mr-3= t('.reply_to') %span %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] - .row.border.border-white + .row %p= sanitize comment['content'] From 58012f662e84fd2e7b67498e22a23ebc91496cae Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:44:33 -0300 Subject: [PATCH 386/814] fix: row sin col --- app/views/moderation_queue/_comment.haml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 26cfbe29..5f50c996 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -11,8 +11,10 @@ %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] .row - %p.mr-3= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + .col.p-0 + %span.mr-3= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row - %p= sanitize comment['content'] + .col.p-0 + %p= sanitize comment['content'] From fdc6ad95b82975ae59ca7f2ab6fa61142e22af58 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:51:27 -0300 Subject: [PATCH 387/814] fix: span sin p en _comment.haml --- app/views/moderation_queue/_comment.haml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 5f50c996..ed77d40f 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -8,13 +8,15 @@ .col.col-1.mr-5 %p= comment['published'].to_datetime.strftime('%m/%d/%Y') .col - %span.mr-2= t('.source_profile') - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + %p + %span.mr-2= t('.source_profile') + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] .row .col.p-0 - %span.mr-3= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + %p + %span.mr-3= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 %p= sanitize comment['content'] From 8dfa3860a5a6fcaae872bd627e16fe363dd88cc5 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 14:58:10 -0300 Subject: [PATCH 388/814] fix: span sin p y texto hardcodeado en _instance.haml --- app/views/moderation_queue/_instance.haml | 9 +++++---- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 80114985..6f0df926 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -4,7 +4,8 @@ %a{ href: host }= instance['title'] %p= instance['description'] -%span Users: -%span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') +%p + %span= t('.users') + %span + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') diff --git a/config/locales/en.yml b/config/locales/en.yml index b1243091..5a8877fd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -72,6 +72,7 @@ en: description: Description custom_block: Custom block lists submit: Save block lists + users: "Users:" dark: Dark dir: ltr en: English diff --git a/config/locales/es.yml b/config/locales/es.yml index 4b68f968..bd20d3f0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -72,6 +72,7 @@ es: description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo + users: "Usuaries:" dark: Oscuro es: Castellano en: English From 1deb4053a70142afc00b9c76a24561b15e84bb72 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 14 Feb 2024 15:10:18 -0300 Subject: [PATCH 389/814] fix: condicional en En Respuesta A en _comment.haml --- app/views/moderation_queue/_comment.haml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index ed77d40f..2666d005 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -13,10 +13,11 @@ %a{ href: comment['attributedTo'] }= profile['preferredUsername'] .row .col.p-0 - %p - %span.mr-3= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + - if comment['inReplyTo'] + %p + %span.mr-3= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 %p= sanitize comment['content'] From 2de756867685455218763a1fdbc09b65d72d51d3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 15:05:27 -0300 Subject: [PATCH 390/814] fix: corregido cuenta de origen de comentarios --- app/views/moderation_queue/_comments.haml | 3 +-- app/views/moderation_queue/_remote_profile.haml | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index d5f2b3bd..76e08559 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -2,8 +2,7 @@ = render 'components/comments_filters' - moderation_queue.each do |comment| - - = render 'comment', comment: comment, profile: @remote_profile + = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación = render 'components/comments_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index fae38dec..744d6445 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -12,12 +12,13 @@ %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %dt= t('.profile_summary') - %dd= remote_profile['summary'] + %dd= sanitize remote_profile['summary'] = render 'moderation_queue/comments', moderation_queue: @moderation_queue -%h3.pt-4= t('.profile') -%h4.my-2= t('.profile_name') + ': ' + remote_profile['name'] +%dl.mt-5 + %dt= t('.profile_name') + %dd= remote_profile['name'] -# Botones de Moderación = render 'components/comments_btn_box' From d0e1d87c98fbc63eaa64272be1c26e6e59b15f8d Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 15:14:11 -0300 Subject: [PATCH 391/814] fix: quitada sanitizacion en comentarios y remote_profile --- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_remote_profile.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 2666d005..213aa220 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -20,4 +20,4 @@ %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 - %p= sanitize comment['content'] + %p= comment['content'] diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 744d6445..e8635cc6 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -12,7 +12,7 @@ %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %dt= t('.profile_summary') - %dd= sanitize remote_profile['summary'] + %dd= remote_profile['summary'] = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 68b8aee1f22cf80707b67bb506ce78fae5411d2a Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:06:49 -0300 Subject: [PATCH 392/814] fix: quitada sanitizacion y quitado row extra --- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_block_instances_textarea.haml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 751d0c0e..01c1fbf9 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,2 @@ %a{href: profile['id']}= profile['preferredUsername'] -%p= sanitize profile['summary'] \ No newline at end of file +%p= profile['summary'] \ No newline at end of file diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 34eb1e5d..339bd25c 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,6 +1,4 @@ .form-group .d-flex.flex-column.mt-5 %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - .d-flex.justify-content-end - %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') - + %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') From 700e71ff97c5886283c6012366eb9318f44767d1 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:15:57 -0300 Subject: [PATCH 393/814] fix: corregido details en application.scss --- app/assets/stylesheets/application.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a411c124..ef36c3be 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -574,13 +574,14 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); bottom: 3%; transform: rotate(60deg); } -} - .details[open] { + &[open] { & > summary { &::after { - transform: rotate(90deg) translatey(-0.1em); + transform: rotate(90deg); } } } +} + From f2724c27fb3e24616d376dd920d78dbec0048add Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:20:46 -0300 Subject: [PATCH 394/814] =?UTF-8?q?fix:=20corregidos=20par=C3=A1metros=20d?= =?UTF-8?q?e=20compo=20checkbox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_checkbox.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 33630780..cbc5cb2d 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,3 +1,3 @@ -# Componente Checkbox .custom-control.custom-checkbox - %input{ type: 'checkbox', id: '', class: '' } + %input{ type: 'checkbox', id: local_assigns[:id], class: local_assigns[:class] } From 643139aaffb0bec5c833bd49649cd1b52cadaa86 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:24:06 -0300 Subject: [PATCH 395/814] fix: corregida indentacion en botones de comentarios --- app/views/components/_comments_btn_box.haml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index aa755dcc..0487c3db 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,9 +1,9 @@ -# Componente Botonera de Comentarios .d-flex.py-4 -- btn_class = 'btn-secondary' -= render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file + - btn_class = 'btn-secondary' + = render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' + = render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' + = render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' + = render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' + = render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file From e11de6c835091610513aec479c4d6771386bae8d Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 16:27:05 -0300 Subject: [PATCH 396/814] fix: cambiada variable global por local en botonera de profiles --- app/views/components/_profiles_btn_box.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 2c63ce3a..06faa8a1 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,7 +1,7 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) -- @class = 'btn-secondary' -= render 'components/btn_base', text: t('.text_approve'), class: @class, href: '' -= render 'components/btn_base', text: t('.text_check'), class: @class, href: '' -= render 'components/btn_base', text: t('.text_deny'), class: @class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: @class, href: '' \ No newline at end of file +- btn_class = 'btn-secondary' += render 'components/btn_base', text: t('.text_approve'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file From 243a998451f793d1438aea514b9666ef78e26c7e Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 16:46:04 -0300 Subject: [PATCH 397/814] =?UTF-8?q?fix:=20row=20va=20dentro=20del=20if=20p?= =?UTF-8?q?ara=20no=20quedar=20vac=C3=ADa=20si=20false?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 2666d005..b92b3b11 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -11,9 +11,10 @@ %p %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - .row - .col.p-0 - - if comment['inReplyTo'] + + - if comment['inReplyTo'] + .row + .col.p-0 %p %span.mr-3= t('.reply_to') %span From 90b14ce2b2589fe80b1329bac314ac626f78ba37 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:07:36 -0300 Subject: [PATCH 398/814] fix: cambio de p por lead --- app/views/moderation_queue/_instances.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 26caaeca..c34bc022 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,6 +9,6 @@ = render 'components/instances_btn_box' %h3.mt-5= t('moderation_queue.instances.title') -%p= t('moderation_queue.instances.description') +%lead= t('moderation_queue.instances.description') = render 'components/block_lists' = render 'moderation_queue/block_instances_textarea' From e3cdafe2a6f7c68dae8813127ee4381ed3464ab9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 17:17:06 -0300 Subject: [PATCH 399/814] fix: corregida clase en compo textarea --- app/views/moderation_queue/_block_instances_textarea.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 339bd25c..0c0f55ca 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,4 @@ .form-group .d-flex.flex-column.mt-5 %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col{ type: 'submit', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') + %button.col.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') From 78e478c00453c7e75ac7a321f4a7ec8fbc459100 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:18:38 -0300 Subject: [PATCH 400/814] =?UTF-8?q?fix:=20fecha=20con=20formato=20seg?= =?UTF-8?q?=C3=BAn=20idioma?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 2 +- config/locales/en.yml | 49 ++++++++++++++++++++++++ config/locales/es.yml | 49 ++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index e525de8f..daf68290 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -6,7 +6,7 @@ .col-10 .row .col.col-1.mr-5 - %p= comment['published'].to_datetime.strftime('%m/%d/%Y') + %p= comment['published'].to_datetime.strftime(t('date.format')) .col %p %span.mr-2= t('.source_profile') diff --git a/config/locales/en.yml b/config/locales/en.yml index 5a8877fd..d6a15d4b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,4 +1,53 @@ en: + date: + format: '%m/%d/%Y' + published_at: "Published at" + last_modified_at: "Last modification" + abbr_day_names: + - Mon + - Tue + - Wed + - Thu + - Fri + - Sat + - Sun + day_names: + - Monday + - Tuesday + - Wednesday + - Thursday + - Friday + - Saturday + - Sunday + abbr_month_names: + - Jan + - Feb + - Mar + - Apr + - May + - Jun + - Jul + - Aug + - Sep + - Oct + - Nov + - Dec + month_names: + - January + - February + - March + - April + - May + - June + - July + - August + - September + - October + - November + - December + time: + am: am + pm: pm components: instances_filters: text_show: Show diff --git a/config/locales/es.yml b/config/locales/es.yml index bd20d3f0..65df27bf 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1,4 +1,53 @@ es: + date: + format: '%d/%m/%Y' + published_at: "Publicado en" + last_modified_at: "Última modificación" + abbr_day_names: + - Lun + - Mar + - Mié + - Jue + - Vie + - Sáb + - Dom + day_names: + - Lunes + - Martes + - Miércoles + - Jueves + - Viernes + - Sábado + - Domingo + abbr_month_names: + - Ene + - Feb + - Mar + - Abr + - May + - Jun + - Jul + - Ago + - Sep + - Oct + - Nov + - Dic + month_names: + - Enero + - Febrero + - Marzo + - Abril + - Mayo + - Junio + - Julio + - Agosto + - Septiembre + - Octubre + - Noviembre + - Diciembre + time: + am: am + pm: pm components: instances_filters: text_show: Ver From 564dc060f0d2ee1f53c33be215bc9fcf72d1a3bf Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 15 Feb 2024 17:24:25 -0300 Subject: [PATCH 401/814] fix: quitado flex de compo block_lists --- app/views/components/_block_lists.haml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 7764dfa5..7d9d741d 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,7 +1,6 @@ -# Componente Listas de bloqueo de Instancias -.flex - .card - .card-body - .d-flex.flex-row - = render 'components/checkbox' - %h4.ml-5= t('.title') +.card.mt-3 + .card-body + .d-flex.flex-row + = render 'components/checkbox' + %h4.ml-5= t('.title') From 476f0c005fc10224163442df3d369732676f5ab2 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:47:04 -0300 Subject: [PATCH 402/814] fix: remote profile asociado al comentario dentro de posts/_moderation_queue.haml --- app/views/posts/_moderation_queue.haml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index e4a9683c..6921acbb 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,10 +1,9 @@ -.flex - -# Filtros - = render 'components/comments_filters' +-# Filtros += render 'components/comments_filters' - - moderation_queue.each do |comment| - = render 'moderation_queue/comment', comment: comment, profile: @remote_profile +- moderation_queue.each do |comment| + = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] - -# Botones moderación - .d-flex.py-4 - = render 'components/comments_btn_box' + -# Botones moderación + .d-flex.py-4 + = render 'components/comments_btn_box' From 9634f758704887550b45980bd967e3fe9a8a6361 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 17:56:12 -0300 Subject: [PATCH 403/814] fix: html_safe en comentarios y descripciones --- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_instance.haml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 01c1fbf9..28bba0e9 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,2 @@ %a{href: profile['id']}= profile['preferredUsername'] -%p= profile['summary'] \ No newline at end of file +%p= profile['summary'].html_safe \ No newline at end of file diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index daf68290..98679a9f 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -21,4 +21,4 @@ %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row .col.p-0 - %p= comment['content'] + %p= comment['content'].html_safe diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 6f0df926..eb5d6581 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -3,7 +3,7 @@ - host = "https://#{host}" %a{ href: host }= instance['title'] -%p= instance['description'] +%p= instance['description'].html_safe %p %span= t('.users') %span From e769c6ed5c36c4499989b8877d57a7126c005972 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 15 Feb 2024 18:14:37 -0300 Subject: [PATCH 404/814] fix: responsive de moderation_queue/_comment.haml --- app/views/components/_checkbox.haml | 2 +- app/views/moderation_queue/_comment.haml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index cbc5cb2d..3444720e 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,3 +1,3 @@ -# Componente Checkbox -.custom-control.custom-checkbox +.custom-control.custom-checkbox.p-0 %input{ type: 'checkbox', id: local_assigns[:id], class: local_assigns[:class] } diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 98679a9f..aa8d777d 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -4,10 +4,10 @@ .col-1 = render 'components/checkbox' .col-10 - .row - .col.col-1.mr-5 + .row.no-gutters + .col.col-4 %p= comment['published'].to_datetime.strftime(t('date.format')) - .col + .col.col-8 %p %span.mr-2= t('.source_profile') %a{ href: comment['attributedTo'] }= profile['preferredUsername'] From 6841945b398cd04a38b859715fcaedb26e51bf81 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 16 Feb 2024 14:52:37 -0300 Subject: [PATCH 405/814] feat: dependencias --- Gemfile | 5 ++++- Gemfile.lock | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 80051e93..3cf01934 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,9 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' -gem 'distributed-press-api-client', '~> 0.4.0rc0' +gem 'redis-client' +gem 'hiredis-client' +gem 'distributed-press-api-client', '~> 0.4.0rc2' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' @@ -65,6 +67,7 @@ gem 'redis', '~> 4.0', require: %w[redis redis/connection/hiredis] gem 'redis-rails' gem 'rollups', git: 'https://github.com/fauno/rollup.git', branch: 'update' gem 'rubyzip' +gem 'ruby-brs' gem 'rugged', '1.5.0.1' gem 'git_clone_url' gem 'concurrent-ruby-ext' diff --git a/Gemfile.lock b/Gemfile.lock index 90bf6d98..5b8ca619 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,6 +88,7 @@ GEM zeitwerk (~> 2.3) addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) + adsp (1.0.10) ast (2.4.2) autoprefixer-rails (10.4.13.0) execjs (~> 2) @@ -157,12 +158,12 @@ GEM devise_invitable (2.0.8) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.4.0rc0) + distributed-press-api-client (0.4.0rc2) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema httparty (~> 0.18) - httparty-cache + httparty-cache (~> 0.0.4) json (~> 2.1, >= 2.1.0) jwt (~> 2.6.0) dotenv (2.8.1) @@ -256,11 +257,13 @@ GEM heapy (0.2.0) thor hiredis (0.6.3-x86_64-linux-musl) + hiredis-client (0.14.1-x86_64-linux-musl) + redis-client (= 0.14.1) http_parser.rb (0.8.0-x86_64-linux-musl) httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - httparty-cache (0.0.1) + httparty-cache (0.0.4) httparty (~> 0.18) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -450,6 +453,8 @@ GEM redis-activesupport (5.3.0) activesupport (>= 3, < 8) redis-store (>= 1.3, < 2) + redis-client (0.14.1) + connection_pool redis-rack (2.1.4) rack (>= 2.0.8, < 3) redis-store (>= 1.2, < 2) @@ -487,6 +492,8 @@ GEM activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) + ruby-brs (1.3.3-x86_64-linux-musl) + adsp (~> 1.0) ruby-filemagic (0.7.3-x86_64-linux-musl) ruby-progressbar (1.13.0) ruby-statistics (3.0.2) @@ -603,7 +610,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.4.0rc0) + distributed-press-api-client (~> 0.4.0rc2) dotenv-rails down ed25519 @@ -619,6 +626,7 @@ DEPENDENCIES haml-lint hamlit-rails hiredis + hiredis-client httparty icalendar image_processing @@ -652,10 +660,12 @@ DEPENDENCIES rails-i18n rails_warden redis (~> 4.0) + redis-client redis-rails rgl rollups! rubocop-rails + ruby-brs rubyzip rugged (= 1.5.0.1) safe_yaml From cdf0685c67721e0f4686e205379a00883506800f Mon Sep 17 00:00:00 2001 From: f Date: Fri, 16 Feb 2024 14:53:05 -0300 Subject: [PATCH 406/814] feat: asociar rol con deploy nos permite acceder al token --- app/models/deploy.rb | 2 ++ app/models/rol.rb | 1 + .../20240216170202_add_rol_to_deploys.rb | 18 ++++++++++++++++++ db/structure.sql | 6 ++++-- 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240216170202_add_rol_to_deploys.rb diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 1f087eb3..8f28f214 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -10,6 +10,8 @@ require 'open3' # :attributes`. class Deploy < ApplicationRecord belongs_to :site + belongs_to :rol + has_many :build_stats, dependent: :destroy DEPENDENCIES = [] diff --git a/app/models/rol.rb b/app/models/rol.rb index 37332400..c9a92515 100644 --- a/app/models/rol.rb +++ b/app/models/rol.rb @@ -11,6 +11,7 @@ class Rol < ApplicationRecord belongs_to :usuarie belongs_to :site + has_many :deploys validates_inclusion_of :rol, in: ROLES diff --git a/db/migrate/20240216170202_add_rol_to_deploys.rb b/db/migrate/20240216170202_add_rol_to_deploys.rb new file mode 100644 index 00000000..5f629432 --- /dev/null +++ b/db/migrate/20240216170202_add_rol_to_deploys.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Establece una relación entre roles y deploys +class AddRolToDeploys < ActiveRecord::Migration[6.1] + def up + add_column :deploys, :rol_id, :integer, index: true + + Deploy.find_each do |deploy| + rol_id = deploy.site.roles.find_by(rol: 'usuarie', temporal: false).id + + deploy.update_column(:rol_id, rol_id) if rol_id + end + end + + def down + remove_column :deploys, :rol_id + end +end diff --git a/db/structure.sql b/db/structure.sql index cb085f63..dede286d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -759,7 +759,8 @@ CREATE TABLE public.deploys ( updated_at timestamp without time zone NOT NULL, site_id integer, type character varying, - "values" text + "values" text, + rol_id integer ); @@ -2318,6 +2319,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230731195050'), ('20230829204127'), ('20230921155401'), -('20230927153926'); +('20230927153926'), +('20240216170202'); From 6d0ea6fa5d864ae9969d43fa2fef5caf54888548 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 16 Feb 2024 14:54:50 -0300 Subject: [PATCH 407/814] feat: acceder a la social inbox desde el sitio --- app/models/site/social_distributed_press.rb | 11 ++++- app/models/social_inbox.rb | 52 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 app/models/social_inbox.rb diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 3be6404e..1193ca76 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'distributed_press/v1/social/client' + class Site # Agrega soporte para Social Distributed Press en los sitios module SocialDistributedPress @@ -10,13 +12,20 @@ class Site before_save :generate_private_key_pem!, unless: :private_key_pem? + # @return [SocialInbox] + def social_inbox + @social_inbox ||= SocialInbox.new(site: self) + end + private # Genera la llave privada y la almacena # # @return [nil] def generate_private_key_pem! - self.private_key_pem ||= ::DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export + self.private_key_pem ||= DistributedPress::V1::Social::Client.new( + public_key_url: nil, + key_size: 2048).private_key.export end end end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb new file mode 100644 index 00000000..47c3457c --- /dev/null +++ b/app/models/social_inbox.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'distributed_press/v1/social/client' + +# Gestiona la Social Inbox de un sitio +class SocialInbox + # @return [Site] + attr_reader :site + + # @param :site [Site] + def initialize(site:) + @site = site + end + + # @return [String] + def actor + @actor ||= + begin + user = site.config.dig('activity_pub', 'username') + user ||= hostname.split('.', 2).first + + "@#{user}@#{hostname}" + end + end + + # @return [DistributedPress::V1::Social::Client] + def client + @client ||= DistributedPress::V1::Social::Client.new( + url: site.config.dig('activity_pub', 'url'), + public_key_url: public_key_url, + private_key_pem: site.private_key_pem, + logger: Rails.logger, + cache_store: :redis + ) + end + + # @return [String] + def public_key_url + @public_key_url ||= URI("https://#{hostname}").tap do |uri| + uri.path = '/about.jsonld' + uri.fragment = 'main-key' + end.to_s + end + + def hostname + @hostname ||= + begin + host = site.config.dig('activity_pub', 'hostname') + host ||= site.hostname + end + end +end From e7595b86887764080dd60503b005dd1ea33534a7 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 16 Feb 2024 15:33:28 -0300 Subject: [PATCH 408/814] =?UTF-8?q?fix:=20la=20descripci=C3=B3n=20ya=20tra?= =?UTF-8?q?=C3=ADa=20etiqueta=20p,=20redundancia=20borrada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 28bba0e9..85fe96d5 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,2 @@ %a{href: profile['id']}= profile['preferredUsername'] -%p= profile['summary'].html_safe \ No newline at end of file +=profile['summary'].html_safe \ No newline at end of file From 4114c1abe6cd4f4fa33c84f2f6d758ec338f6381 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 16 Feb 2024 15:35:26 -0300 Subject: [PATCH 409/814] fix: p reemplazado por dl --- app/views/moderation_queue/_comment.haml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index aa8d777d..5b0f01a6 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -8,9 +8,10 @@ .col.col-4 %p= comment['published'].to_datetime.strftime(t('date.format')) .col.col-8 - %p - %span.mr-2= t('.source_profile') - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + %dl + %dt.d-inline.mr-2= t('.source_profile') + %dd.d-inline + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - if comment['inReplyTo'] .row From 2c61f3baa2e2466179d7089a1a8abd2747049159 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 16 Feb 2024 15:38:26 -0300 Subject: [PATCH 410/814] =?UTF-8?q?fix:=20comments=5Fbtn=5Fbox=20recibe=20?= =?UTF-8?q?comment=20como=20par=C3=A1metro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comments.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 76e08559..d51909a3 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -5,4 +5,4 @@ = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - = render 'components/comments_btn_box' \ No newline at end of file + = render 'components/comments_btn_box', comment: comment \ No newline at end of file From b792cb2d43a6ac145bb8a3afea6f0ccb1841eab5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 16 Feb 2024 15:59:37 -0300 Subject: [PATCH 411/814] feat: poder reutilizar webhooks --- .../api/v1/concerns/webhook_concern.rb | 71 +++++++++++++++++++ app/controllers/api/v1/webhooks_controller.rb | 56 +-------------- config/routes.rb | 4 +- 3 files changed, 75 insertions(+), 56 deletions(-) create mode 100644 app/controllers/api/v1/concerns/webhook_concern.rb diff --git a/app/controllers/api/v1/concerns/webhook_concern.rb b/app/controllers/api/v1/concerns/webhook_concern.rb new file mode 100644 index 00000000..59d48b28 --- /dev/null +++ b/app/controllers/api/v1/concerns/webhook_concern.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +module Api + module V1 + # Helpers para webhooks + module WebhookConcern + extend ActiveSupport::Concern + + included do + # Responde con forbidden si falla la validación del token + rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + + private + + # Valida el token que envía la plataforma en el webhook + # + # @return [String] + def token + @token ||= + begin + _headers = request.headers + _token ||= _headers['X-Gitlab-Token'].presence + _token ||= token_from_signature(_headers['X-Gitea-Signature'].presence) + _token ||= token_from_signature(_headers['X-Hub-Signature-256'].presence, 'sha256=') + _token + ensure + raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if _token.blank? + end + end + + # Valida token a partir de firma + # + # @param signature [String,nil] + # @param prepend [String] + # @return [String, nil] + def token_from_signature(signature, prepend = '') + return if signature.nil? + + payload = request.raw_post + + site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| + new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) + + ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s) + end + end + + # Encuentra el sitio a partir de la URL + # + # @return [Site] + def site + @site ||= Site.find_by_name!(params[:site_id]) + end + + # Encuentra le usuarie + # + # @return [Site] + def usuarie + @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie + end + + # Respuesta de error a plataformas + def platforms_answer(exception) + ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h }) + + head :forbidden + end + end + end + end +end diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 6e7b7022..f64fa93c 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -4,8 +4,7 @@ module Api module V1 # Recibe webhooks y lanza un PullJob class WebhooksController < BaseController - # responde con forbidden si falla la validación del token - rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + include WebhookConcern # Trae los cambios a partir de un post de Webhooks: # (Gitlab, Github, Gitea, etc) @@ -19,59 +18,6 @@ module Api GitPullJob.perform_later(site, usuarie, message) head :ok end - - private - - # encuentra el sitio a partir de la url - def site - @site ||= Site.find_by_name!(params[:site_id]) - end - - # valida el token que envía la plataforma del webhook - # - # @return [String] - def token - @token ||= - begin - # Gitlab - if request.headers['X-Gitlab-Token'].present? - request.headers['X-Gitlab-Token'] - # Github - elsif request.headers['X-Hub-Signature-256'].present? - token_from_signature(request.headers['X-Hub-Signature-256'], 'sha256=') - # Gitea - elsif request.headers['X-Gitea-Signature'].present? - token_from_signature(request.headers['X-Gitea-Signature']) - else - raise ActiveRecord::RecordNotFound, 'proveedor no soportado' - end - end - end - - # valida token a partir de firma de webhook - # - # @return [String, Boolean] - def token_from_signature(signature, prepend = '') - payload = request.body.read - site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| - new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) - ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s) - end.tap do |t| - raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil? - end - end - - # encuentra le usuarie - def usuarie - @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end - - # respuesta de error a plataformas - def platforms_answer(exception) - ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h }) - - head :forbidden - end end end end diff --git a/config/routes.rb b/config/routes.rb index 635be07a..8186b64e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,7 +18,9 @@ Rails.application.routes.draw do get :'contact/cookie', to: 'invitades#contact_cookie' post :'contact/:form', to: 'contact#receive', as: :contact - post :'webhooks/pull', to: 'webhooks#pull' + namespace :webhooks do + post :pull, to: 'webhooks#pull' + end end end end From b24f49fe2611791eb377a56d4f7e9cdbeafafbd4 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 16 Feb 2024 16:01:17 -0300 Subject: [PATCH 412/814] feat: crear webhooks en la social inbox #15109 --- .../api/v1/social_inbox_controller.rb | 22 +++++++++++ app/models/deploy_social_distributed_press.rb | 39 +++++++++++++++++++ app/models/social_inbox.rb | 6 +++ config/application.rb | 3 ++ config/routes.rb | 6 +++ 5 files changed, 76 insertions(+) create mode 100644 app/controllers/api/v1/social_inbox_controller.rb diff --git a/app/controllers/api/v1/social_inbox_controller.rb b/app/controllers/api/v1/social_inbox_controller.rb new file mode 100644 index 00000000..3881b6bc --- /dev/null +++ b/app/controllers/api/v1/social_inbox_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Api + module V1 + # Recibe webhooks de la Social Inbox + class SocialInboxController < BaseController + include WebhookConcern + + def moderationqueued + head :accepted + end + + def onapproved + head :accepted + end + + def onrejected + head :accepted + end + end + end +end diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index db555ab7..f5c38a22 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -7,6 +7,8 @@ class DeploySocialDistributedPress < Deploy # Solo luego de publicar remotamente DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync] + after_save :create_hooks! + # Envía las notificaciones def deploy(output: false) with_tempfile(site.private_key_pem) do |file| @@ -52,4 +54,41 @@ class DeploySocialDistributedPress < Deploy def flags_for_build(**args) "--key #{Shellwords.escape args[:private_key].path}" end + + private + + # Obtiene el hostname de la API de Sutty + # + # @return [String] + def api_hostname + Rails.application.routes.default_url_options[:host].sub('panel', 'api') + end + + # Crea los hooks en la Social Inbox para que nos avise de actividades + # nuevas + # + # @return [nil] + def create_hooks! + hook_client = site.social_inbox.hook + + hook_client.class::EVENTS.each do |event| + event_url = :"v1_site_webhooks_social_inbox_#{event}_url" + + webhook = DistributedPress::V1::Social::Schemas::Webhook.new.call({ + method: 'POST', + url: Rails.application.routes.url_helpers.public_send(event_url, site_id: site.name, host: api_hostname), + headers: { + 'X-Social-Inbox': rol.token + } + }) + + raise ArgumentError, webhook.errors.messages if webhook.failure? + + response = hook_client.put(event: event, hook: webhook) + + raise ArgumentError, response.parsed_body unless response.ok? + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { site_id: site.name, usuarie_id: rol.usuarie_id }) + end + end end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 47c3457c..8aa5b504 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'distributed_press/v1/social/client' +require 'distributed_press/v1/social/hook' # Gestiona la Social Inbox de un sitio class SocialInbox @@ -34,6 +35,11 @@ class SocialInbox ) end + # @return [DistributedPress::V1::Social::Hook] + def hook + @hook ||= DistributedPress::V1::Social::Hook.new(client: client, actor: actor) + end + # @return [String] def public_key_url @public_key_url ||= URI("https://#{hostname}").tap do |uri| diff --git a/config/application.rb b/config/application.rb index 529e341a..73a7a884 100644 --- a/config/application.rb +++ b/config/application.rb @@ -2,6 +2,9 @@ require_relative 'boot' +require 'redis-client' +require 'hiredis-client' +require 'brs' require 'rails' # Pick the frameworks you want: require 'active_model/railtie' diff --git a/config/routes.rb b/config/routes.rb index 8186b64e..f6f081f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,6 +20,12 @@ Rails.application.routes.draw do namespace :webhooks do post :pull, to: 'webhooks#pull' + + namespace :social_inbox do + post :moderationqueued, to: 'social_inbox#moderationqueued' + post :onapproved, to: 'social_inbox#onapproved' + post :onrejected, to: 'social_inbox#onrejected' + end end end end From b4117d7c348b63b0af2efa86bbb3b79d582ec1ad Mon Sep 17 00:00:00 2001 From: f Date: Sat, 17 Feb 2024 14:11:17 -0300 Subject: [PATCH 413/814] chore: rubocop --- .../api/v1/concerns/webhook_concern.rb | 13 ++++++------ app/models/deploy.rb | 8 ++++---- app/models/deploy_social_distributed_press.rb | 20 +++++++++++-------- app/models/site/social_distributed_press.rb | 3 ++- app/models/social_inbox.rb | 5 +---- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/app/controllers/api/v1/concerns/webhook_concern.rb b/app/controllers/api/v1/concerns/webhook_concern.rb index 59d48b28..9960e550 100644 --- a/app/controllers/api/v1/concerns/webhook_concern.rb +++ b/app/controllers/api/v1/concerns/webhook_concern.rb @@ -18,13 +18,14 @@ module Api def token @token ||= begin - _headers = request.headers - _token ||= _headers['X-Gitlab-Token'].presence - _token ||= token_from_signature(_headers['X-Gitea-Signature'].presence) - _token ||= token_from_signature(_headers['X-Hub-Signature-256'].presence, 'sha256=') - _token + header = request.headers + token = header['X-Social-Inbox'].presence + token ||= header['X-Gitlab-Token'].presence + token ||= token_from_signature(header['X-Gitea-Signature'].presence) + token ||= token_from_signature(header['X-Hub-Signature-256'].presence, 'sha256=') + token ensure - raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if _token.blank? + raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if token.blank? end end diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 8f28f214..77646034 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -14,8 +14,8 @@ class Deploy < ApplicationRecord has_many :build_stats, dependent: :destroy - DEPENDENCIES = [] - SOFT_DEPENDENCIES = [] + DEPENDENCIES = [].freeze + SOFT_DEPENDENCIES = [].freeze def deploy(**) raise NotImplementedError @@ -74,7 +74,7 @@ class Deploy < ApplicationRecord 'HOME' => home_dir, 'PATH' => paths.join(':'), 'JEKYLL_ENV' => Rails.env, - 'LANG' => ENV['LANG'], + 'LANG' => ENV.fetch('LANG', nil) }) end @@ -139,7 +139,7 @@ class Deploy < ApplicationRecord # provisto con el archivo como parámetro # # @param :content [String] - def with_tempfile(content, &block) + def with_tempfile(content) Tempfile.create(SecureRandom.hex) do |file| file.write content.to_s file.rewind diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index f5c38a22..fc0e01d5 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -5,7 +5,7 @@ require 'distributed_press/v1/social/client' # Publicar novedades al Fediverso class DeploySocialDistributedPress < Deploy # Solo luego de publicar remotamente - DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync] + DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync].freeze after_save :create_hooks! @@ -70,17 +70,21 @@ class DeploySocialDistributedPress < Deploy # @return [nil] def create_hooks! hook_client = site.social_inbox.hook + webhook_class = DistributedPress::V1::Social::Schemas::Webhook hook_client.class::EVENTS.each do |event| event_url = :"v1_site_webhooks_social_inbox_#{event}_url" - webhook = DistributedPress::V1::Social::Schemas::Webhook.new.call({ - method: 'POST', - url: Rails.application.routes.url_helpers.public_send(event_url, site_id: site.name, host: api_hostname), - headers: { - 'X-Social-Inbox': rol.token - } - }) + webhook = + webhook_class.new.call({ + method: 'POST', + url: Rails.application.routes.url_helpers.public_send( + event_url, site_id: site.name, host: api_hostname + ), + headers: { + 'X-Social-Inbox': rol.token + } + }) raise ArgumentError, webhook.errors.messages if webhook.failure? diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 1193ca76..d3ebf579 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -25,7 +25,8 @@ class Site def generate_private_key_pem! self.private_key_pem ||= DistributedPress::V1::Social::Client.new( public_key_url: nil, - key_size: 2048).private_key.export + key_size: 2048 + ).private_key.export end end end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 8aa5b504..24f749be 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -50,9 +50,6 @@ class SocialInbox def hostname @hostname ||= - begin - host = site.config.dig('activity_pub', 'hostname') - host ||= site.hostname - end + site.config.dig('activity_pub', 'hostname') || site.hostname end end From 9554ad1627b1167c140799202ac5c9081e5df885 Mon Sep 17 00:00:00 2001 From: maki Date: Mon, 19 Feb 2024 13:57:39 -0300 Subject: [PATCH 414/814] fix: sintaxis --- app/views/moderation_queue/_comment.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 5b0f01a6..fea4570f 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -3,23 +3,23 @@ .row.no-gutters .col-1 = render 'components/checkbox' - .col-10 + .col-11 .row.no-gutters - .col.col-4 + .col-4 %p= comment['published'].to_datetime.strftime(t('date.format')) - .col.col-8 + .col-8 %dl %dt.d-inline.mr-2= t('.source_profile') %dd.d-inline %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - if comment['inReplyTo'] - .row + .row.no-gutters .col.p-0 %p %span.mr-3= t('.reply_to') %span %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] - .row + .row.no-gutters .col.p-0 %p= comment['content'].html_safe From ecab598595130d8cd498161572902dd2cb1a57ca Mon Sep 17 00:00:00 2001 From: maki Date: Mon, 19 Feb 2024 14:21:32 -0300 Subject: [PATCH 415/814] =?UTF-8?q?fix:=20no=20se=20ve=C3=ADan=20los=20bot?= =?UTF-8?q?ones=20en=20modo=20oscuro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/dark.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/stylesheets/dark.scss b/app/assets/stylesheets/dark.scss index 59e15180..f7f3a09d 100644 --- a/app/assets/stylesheets/dark.scss +++ b/app/assets/stylesheets/dark.scss @@ -8,6 +8,10 @@ $cyan: #13fefe; --color: #{$cyan}; } +.btn { + background-color: $white; +} + .btn-secondary { background-color: $white; color: $black; @@ -26,3 +30,5 @@ $cyan: #13fefe; box-shadow: 0 0 0 0.2rem $cyan; } } + + From 5ee9c49529c479625f3c1eee606d3ba3053a6421 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 20 Feb 2024 14:23:16 -0300 Subject: [PATCH 416/814] fix: corregidos botones y espacios en details de instancias --- app/views/components/_btn_base.haml | 2 +- app/views/components/_comments_btn_box.haml | 13 ++++++------- app/views/moderation_queue/_instance.haml | 19 ++++++++++++------- app/views/moderation_queue/_instances.haml | 3 ++- app/views/posts/_moderation_queue.haml | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 2985d646..ccc7ce35 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%button.btn.btn-lg.mx-2{ href: href, class: local_assigns[:class] }= text +%button.btn.mx-2{ href: href, class: local_assigns[:class] }= text diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 0487c3db..7932068f 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,9 +1,8 @@ -# Componente Botonera de Comentarios -.d-flex.py-4 - - btn_class = 'btn-secondary' - = render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' - = render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' - = render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' - = render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' - = render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file +- btn_class = 'btn-secondary' += render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' += render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index eb5d6581..74bda75b 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -2,10 +2,15 @@ - host ||= instance['uri'] - host = "https://#{host}" -%a{ href: host }= instance['title'] -%p= instance['description'].html_safe -%p - %span= t('.users') - %span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox' + .col-11 + %h4 + %a{ href: host }= instance['title'] + %p= instance['description'].html_safe + %p + %span= t('.users') + %span + = instance.dig('usage', 'users', 'active_month') + = instance.dig('stats', 'user_count') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index c34bc022..d19ef8ed 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,8 +5,9 @@ = render 'moderation_queue/instance', instance: instance -# Botones moderación - .d-flex.py-5 + .d-flex.pb-4 = render 'components/instances_btn_box' + %hr %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 6921acbb..2be35f7f 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -5,5 +5,5 @@ = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - .d-flex.py-4 + .d-flex = render 'components/comments_btn_box' From 9064325f7f8d52b98932a88afb14cd2cb7e8e2a3 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:26:55 -0300 Subject: [PATCH 417/814] fix: flecha del details apunta donde tiene que apuntar --- app/assets/stylesheets/application.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index ef36c3be..f40af493 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -572,7 +572,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); position: absolute; left: 97%; bottom: 3%; - transform: rotate(60deg); + transform: rotate(0deg); } &[open] { & > summary { From f968c60bdf554acf69c95d4791fd68c9636932c3 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:29:48 -0300 Subject: [PATCH 418/814] =?UTF-8?q?fix:=20l=C3=ADneas=20de=20separaci?= =?UTF-8?q?=C3=B3n=20entre=20secciones=20de=20Actividades=20de=20moderaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/index.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 982a41c8..ab98ee30 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -6,9 +6,11 @@ - summary = t('.instances') = render 'layouts/details', summary: summary do = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue + %hr - summary = t('.comments') = render 'layouts/details', summary: summary do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue From 195fdb56723fd1805deb97ac7962e8549b9cf42d Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:52:23 -0300 Subject: [PATCH 419/814] =?UTF-8?q?fix:=20que=20el=20separador=20entre=20d?= =?UTF-8?q?etails=20se=20vea=20en=20modo=20oscuro=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f40af493..054faee9 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -584,4 +584,6 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } - +hr { + border-bottom: 1px solid #dee2e6; +} \ No newline at end of file From 3d543a22fdf5d302c534388cdb49adcb1be50576 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 14:58:59 -0300 Subject: [PATCH 420/814] =?UTF-8?q?fix:=20la=20flecha=20del=20details=20te?= =?UTF-8?q?n=C3=ADa=20que=20apuntar=20para=20la=20izq=20ups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 054faee9..240e61a5 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -572,7 +572,7 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); position: absolute; left: 97%; bottom: 3%; - transform: rotate(0deg); + transform: rotate(180deg); } &[open] { & > summary { From 5c2f2b9c614eacfc5b9cdaacdb96216d2be412cb Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 20 Feb 2024 15:12:42 -0300 Subject: [PATCH 421/814] =?UTF-8?q?fix:=20agregada=20l=C3=ADnea=20de=20sep?= =?UTF-8?q?araci=C3=B3n=20de=20tarjetas=20en=20compo=20accounts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 9 +++++++-- app/views/moderation_queue/_accounts.haml | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 85fe96d5..ab4fc4c7 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,2 +1,7 @@ -%a{href: profile['id']}= profile['preferredUsername'] -=profile['summary'].html_safe \ No newline at end of file +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox' + .col-11 + %h4 + %a{href: profile['id']}= profile['preferredUsername'] + =profile['summary'].html_safe diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index e92c3a20..9a6738bd 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -2,9 +2,10 @@ = render 'components/profiles_filters' - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| + %hr = render 'account', profile: remote_profile -# Botones de Moderación -.d-flex.py-4 +.d-flex.pb-4 = render 'components/profiles_btn_box' - \ No newline at end of file + From 71d0985a39dc9b5dc126b57f560f3c580864d7d3 Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 15:13:54 -0300 Subject: [PATCH 422/814] =?UTF-8?q?fix:=20bot=C3=B3n=20no=20deber=C3=ADa?= =?UTF-8?q?=20ocupar=20todo=20el=20ancho=20del=20div?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_block_instances_textarea.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 0c0f55ca..ff8f9286 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,4 @@ .form-group .d-flex.flex-column.mt-5 %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.col.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') + %button.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') From bd41144ecf5939fa5a11e5607f8ca2317744051e Mon Sep 17 00:00:00 2001 From: maki Date: Tue, 20 Feb 2024 15:41:49 -0300 Subject: [PATCH 423/814] fix: textarea --- app/views/components/_block_lists.haml | 2 +- app/views/moderation_queue/_block_instances_textarea.haml | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 7d9d741d..8cdcd43b 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,5 +1,5 @@ -# Componente Listas de bloqueo de Instancias -.card.mt-3 +.card.mt-3.mb-3 .card-body .d-flex.flex-row = render 'components/checkbox' diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index ff8f9286..9b388a0d 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,4 +1,5 @@ .form-group - .d-flex.flex-column.mt-5 - %textarea.mb-3{ name: '', id: '', placeholder: t('moderation_queue.instances.custom_block') } - %button.btn.btn-secondary{ type: 'submit' }= t('moderation_queue.instances.submit') + = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') + = text_area_tag "custom_blocklist", nil, class: 'form-control' + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') + From 27c0ca655eef45d61523f577dc9cc34cee0d0afe Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 14:44:52 -0300 Subject: [PATCH 424/814] feat: modelo de datos de activitypub #15109 --- app/models/activity_pub.rb | 33 ++++ app/models/activity_pub/activity.rb | 24 +++ app/models/activity_pub/activity/create.rb | 3 + app/models/activity_pub/activity/delete.rb | 3 + app/models/activity_pub/activity/flag.rb | 3 + app/models/activity_pub/activity/follow.rb | 7 + app/models/activity_pub/activity/generic.rb | 3 + app/models/activity_pub/activity/undo.rb | 8 + app/models/activity_pub/activity/update.rb | 3 + app/models/activity_pub/actor.rb | 14 ++ .../activity_pub/concerns/json_ld_concern.rb | 32 ++++ app/models/activity_pub/instance.rb | 21 +++ app/models/activity_pub/object.rb | 11 ++ app/models/activity_pub/object/application.rb | 6 + app/models/activity_pub/object/article.rb | 6 + app/models/activity_pub/object/generic.rb | 4 + app/models/activity_pub/object/note.rb | 6 + .../activity_pub/object/organization.rb | 6 + app/models/activity_pub/object/person.rb | 6 + ...19153919_create_activity_pub_activities.rb | 16 ++ ...240219175839_create_activity_pub_actors.rb | 12 ++ .../20240219204011_create_activity_pubs.rb | 18 ++ ...40219204224_create_activity_pub_objects.rb | 17 ++ ...220161414_create_activity_pub_instances.rb | 13 ++ db/structure.sql | 161 +++++++++++++++++- 25 files changed, 435 insertions(+), 1 deletion(-) create mode 100644 app/models/activity_pub.rb create mode 100644 app/models/activity_pub/activity.rb create mode 100644 app/models/activity_pub/activity/create.rb create mode 100644 app/models/activity_pub/activity/delete.rb create mode 100644 app/models/activity_pub/activity/flag.rb create mode 100644 app/models/activity_pub/activity/follow.rb create mode 100644 app/models/activity_pub/activity/generic.rb create mode 100644 app/models/activity_pub/activity/undo.rb create mode 100644 app/models/activity_pub/activity/update.rb create mode 100644 app/models/activity_pub/actor.rb create mode 100644 app/models/activity_pub/concerns/json_ld_concern.rb create mode 100644 app/models/activity_pub/instance.rb create mode 100644 app/models/activity_pub/object.rb create mode 100644 app/models/activity_pub/object/application.rb create mode 100644 app/models/activity_pub/object/article.rb create mode 100644 app/models/activity_pub/object/generic.rb create mode 100644 app/models/activity_pub/object/note.rb create mode 100644 app/models/activity_pub/object/organization.rb create mode 100644 app/models/activity_pub/object/person.rb create mode 100644 db/migrate/20240219153919_create_activity_pub_activities.rb create mode 100644 db/migrate/20240219175839_create_activity_pub_actors.rb create mode 100644 db/migrate/20240219204011_create_activity_pubs.rb create mode 100644 db/migrate/20240219204224_create_activity_pub_objects.rb create mode 100644 db/migrate/20240220161414_create_activity_pub_instances.rb diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb new file mode 100644 index 00000000..c0474b89 --- /dev/null +++ b/app/models/activity_pub.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# = ActivityPub = +# +# El registro de actividades recibidas y su estado. Cuando recibimos +# una actividad, puede estar destinada a varies actores dentro de Sutty, +# con lo que generamos una cola para cada une. +# +# @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} +class ActivityPub < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :object, polymorphic: true + has_many :activities + + validates :site_id, presence: true + validates :object_id, presence: true + validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported deleted] } + + aasm do + # Todavía no hay una decisión sobre el objeto + state :paused, initial: true + # Le usuarie aprobó el objeto + state :approved + # Le usuarie rechazó el objeto + state :rejected + # Le usuarie reportó el objeto + state :reported + # Le actore eliminó el objeto + state :deleted + end +end diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb new file mode 100644 index 00000000..4a88c1f3 --- /dev/null +++ b/app/models/activity_pub/activity.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# = Activity = +# +# Lleva un registro de las actividades que nos piden hacer remotamente. +# +# Las actividades pueden tener distintos destinataries (sitios/actores). +# +# @todo Obtener el contenido del objeto dinámicamente si no existe +# localmente, por ejemplo cuando la actividad crea un objeto pero lo +# envía como referencia en lugar de anidarlo. +# +# @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} +class ActivityPub::Activity < ApplicationRecord + include ActivityPub::Concerns::JsonLdConcern + + belongs_to :activity_pub + has_one :object, through: :activity_pub + + validates :activity_pub_id, presence: true + + # Siempre en orden descendiente para saber el último estado + default_scope -> { order(created_at: :desc) } +end diff --git a/app/models/activity_pub/activity/create.rb b/app/models/activity_pub/activity/create.rb new file mode 100644 index 00000000..3dcba5c2 --- /dev/null +++ b/app/models/activity_pub/activity/create.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Create < ActivityPub::Activity; end diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb new file mode 100644 index 00000000..f3684a0f --- /dev/null +++ b/app/models/activity_pub/activity/delete.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Delete < ActivityPub::Activity; end diff --git a/app/models/activity_pub/activity/flag.rb b/app/models/activity_pub/activity/flag.rb new file mode 100644 index 00000000..2911911e --- /dev/null +++ b/app/models/activity_pub/activity/flag.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Flag < ActivityPub::Activity; end diff --git a/app/models/activity_pub/activity/follow.rb b/app/models/activity_pub/activity/follow.rb new file mode 100644 index 00000000..c22dfd51 --- /dev/null +++ b/app/models/activity_pub/activity/follow.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# = Follow = +# +# Una actividad de seguimiento se refiere siempre a une actore (el +# sitio) y proviene de otre actore. +class ActivityPub::Activity::Follow < ActivityPub::Activity; end diff --git a/app/models/activity_pub/activity/generic.rb b/app/models/activity_pub/activity/generic.rb new file mode 100644 index 00000000..8bf76471 --- /dev/null +++ b/app/models/activity_pub/activity/generic.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Generic < ActivityPub::Activity; end diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb new file mode 100644 index 00000000..a4915394 --- /dev/null +++ b/app/models/activity_pub/activity/undo.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# = Undo = +# +# Deshace una actividad, dependiendo de la actividad a la que se +# refiere. +class ActivityPub::Activity::Undo < ActivityPub::Activity +end diff --git a/app/models/activity_pub/activity/update.rb b/app/models/activity_pub/activity/update.rb new file mode 100644 index 00000000..8089cdcf --- /dev/null +++ b/app/models/activity_pub/activity/update.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Update < ActivityPub::Activity; end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb new file mode 100644 index 00000000..f29c382a --- /dev/null +++ b/app/models/activity_pub/actor.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# = Actor = +# +# Actor es la entidad que realiza acciones en ActivityPub +# +# @todo Obtener el perfil dinámicamente +class ActivityPub::Actor < ApplicationRecord + include ActivityPub::Concerns::JsonLdConcern + + belongs_to :instance + has_many :activity_pubs, as: :object + has_many :objects +end diff --git a/app/models/activity_pub/concerns/json_ld_concern.rb b/app/models/activity_pub/concerns/json_ld_concern.rb new file mode 100644 index 00000000..b0899606 --- /dev/null +++ b/app/models/activity_pub/concerns/json_ld_concern.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class ActivityPub + module Concerns + module JsonLdConcern + extend ActiveSupport::Concern + + included do + validates :uri, presence: true, uniqueness: true + + # Cuando asignamos contenido, obtener la URI si no lo hicimos ya + before_save :uri_from_content!, unless: :uri? + + # Obtiene un tipo de actividad a partir del tipo informado + # + # @param object [Hash] + # @return [Activity] + def self.type_from(object) + "#{self.class.name}::#{object[:type].presence || 'Generic'}".constantize + rescue NameError + self.class::Generic + end + + private + + def uri_from_content! + self.uri = content[:id] + end + end + end + end +end diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb new file mode 100644 index 00000000..fe4a777b --- /dev/null +++ b/app/models/activity_pub/instance.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# = Instance = +# +# Representa cada instancia del fediverso que interactúa con la Social +# Inbox. +class ActivityPub::Instance < ApplicationRecord + include AASM + + validates :aasm_state, presence: true, inclusion: { in: %w[paused allowed blocked] } + validates :hostname, uniqueness: true, hostname: true + + has_many :activity_pubs + has_many :actors + + aasm do + state :paused, initial: true + state :allowed + state :blocked + end +end diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb new file mode 100644 index 00000000..519749ef --- /dev/null +++ b/app/models/activity_pub/object.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# Almacena objetos de ActivityPub, como Note, Article, etc. +class ActivityPub::Object < ApplicationRecord + include ActivityPub::Concerns::JsonLdConcern + + belongs_to :actor + has_many :activity_pubs, as: :object + + validates :actor_id, presence: true +end diff --git a/app/models/activity_pub/object/application.rb b/app/models/activity_pub/object/application.rb new file mode 100644 index 00000000..e8a6f97c --- /dev/null +++ b/app/models/activity_pub/object/application.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# = Application = +# +# Una aplicación o instancia +class ActivityPub::Object::Application < ActivityPub::Object; end diff --git a/app/models/activity_pub/object/article.rb b/app/models/activity_pub/object/article.rb new file mode 100644 index 00000000..ad1a6131 --- /dev/null +++ b/app/models/activity_pub/object/article.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# = Article = +# +# Representa artículos +class ActivityPub::Object::Article < ActivityPub::Object; end diff --git a/app/models/activity_pub/object/generic.rb b/app/models/activity_pub/object/generic.rb new file mode 100644 index 00000000..f345e7a9 --- /dev/null +++ b/app/models/activity_pub/object/generic.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +# = Generic = +class ActivityPub::Object::Generic < ActivityPub::Object; end diff --git a/app/models/activity_pub/object/note.rb b/app/models/activity_pub/object/note.rb new file mode 100644 index 00000000..0f84c747 --- /dev/null +++ b/app/models/activity_pub/object/note.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# = Note = +# +# Representa notas, el tipo más común de objeto del Fediverso. +class ActivityPub::Object::Note < ActivityPub::Object; end diff --git a/app/models/activity_pub/object/organization.rb b/app/models/activity_pub/object/organization.rb new file mode 100644 index 00000000..a5327d10 --- /dev/null +++ b/app/models/activity_pub/object/organization.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# = Organization = +# +# Una organización +class ActivityPub::Object::Organization < ActivityPub::Object; end diff --git a/app/models/activity_pub/object/person.rb b/app/models/activity_pub/object/person.rb new file mode 100644 index 00000000..98a1568d --- /dev/null +++ b/app/models/activity_pub/object/person.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# = Person = +# +# Una persona, el perfil de une actore +class ActivityPub::Object::Person < ActivityPub::Object; end diff --git a/db/migrate/20240219153919_create_activity_pub_activities.rb b/db/migrate/20240219153919_create_activity_pub_activities.rb new file mode 100644 index 00000000..555656ad --- /dev/null +++ b/db/migrate/20240219153919_create_activity_pub_activities.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Actividades. Se asocian a un objeto y a una cola de moderación +class CreateActivityPubActivities < ActiveRecord::Migration[6.1] + def change + create_table :activity_pub_activities, id: :uuid do |t| + t.timestamps + + t.uuid :activity_pub_id, index: true, null: false + + t.string :type, null: false + t.string :uri, null: false + t.jsonb :content, default: {} + end + end +end diff --git a/db/migrate/20240219175839_create_activity_pub_actors.rb b/db/migrate/20240219175839_create_activity_pub_actors.rb new file mode 100644 index 00000000..656b3f63 --- /dev/null +++ b/db/migrate/20240219175839_create_activity_pub_actors.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Almacena actores de ActivityPub y los relaciona con actividades +class CreateActivityPubActors < ActiveRecord::Migration[6.1] + def change + create_table :activity_pub_actors, id: :uuid do |t| + t.timestamps + t.uuid :instance_id, index: true, null: false + t.string :uri, index: true, unique: true, null: false + end + end +end diff --git a/db/migrate/20240219204011_create_activity_pubs.rb b/db/migrate/20240219204011_create_activity_pubs.rb new file mode 100644 index 00000000..cf797fc8 --- /dev/null +++ b/db/migrate/20240219204011_create_activity_pubs.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Registro de actividades. +class CreateActivityPubs < ActiveRecord::Migration[6.1] + def change + create_table :activity_pubs, id: :uuid do |t| + t.timestamps + + t.bigint :site_id, null: false + t.uuid :object_id, null: false + t.string :object_type, null: false + + t.string :aasm_state, null: false + + t.index %i[site_id object_id object_type], unique: true + end + end +end diff --git a/db/migrate/20240219204224_create_activity_pub_objects.rb b/db/migrate/20240219204224_create_activity_pub_objects.rb new file mode 100644 index 00000000..865589ab --- /dev/null +++ b/db/migrate/20240219204224_create_activity_pub_objects.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Almacena objetos de ActivityPub. Los objetos pueden estar compartidos +# por toda la instancia. +class CreateActivityPubObjects < ActiveRecord::Migration[6.1] + def change + create_table :activity_pub_objects, id: :uuid do |t| + t.timestamps + + t.uuid :actor_id, index: true, null: false + + t.string :type, null: false + t.string :uri, null: false, unique: true + t.jsonb :content, default: {} + end + end +end diff --git a/db/migrate/20240220161414_create_activity_pub_instances.rb b/db/migrate/20240220161414_create_activity_pub_instances.rb new file mode 100644 index 00000000..feb9351d --- /dev/null +++ b/db/migrate/20240220161414_create_activity_pub_instances.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Almacena las instancias +class CreateActivityPubInstances < ActiveRecord::Migration[6.1] + def change + create_table :activity_pub_instances, id: :uuid do |t| + t.timestamps + t.string :hostname, index: true, unique: true, null: false + t.string :aasm_state, null: false + t.jsonb :content, default: {} + end + end +end diff --git a/db/structure.sql b/db/structure.sql index dede286d..723c9e99 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -473,6 +473,78 @@ CREATE SEQUENCE public.active_storage_variant_records_id_seq ALTER SEQUENCE public.active_storage_variant_records_id_seq OWNED BY public.active_storage_variant_records.id; +-- +-- Name: activity_pub_activities; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_activities ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + activity_pub_id uuid NOT NULL, + type character varying NOT NULL, + uri character varying NOT NULL, + content jsonb DEFAULT '{}'::jsonb +); + + +-- +-- Name: activity_pub_actors; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_actors ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + instance_id uuid NOT NULL, + uri character varying NOT NULL +); + + +-- +-- Name: activity_pub_instances; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_instances ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + hostname character varying NOT NULL, + aasm_state character varying NOT NULL, + content jsonb DEFAULT '{}'::jsonb +); + + +-- +-- Name: activity_pub_objects; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_objects ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + actor_id uuid NOT NULL, + type character varying NOT NULL, + uri character varying NOT NULL, + content jsonb DEFAULT '{}'::jsonb +); + + +-- +-- Name: activity_pubs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pubs ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint NOT NULL, + object_id uuid NOT NULL, + object_type character varying NOT NULL, + aasm_state character varying NOT NULL +); + + -- -- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - -- @@ -1565,6 +1637,46 @@ ALTER TABLE ONLY public.active_storage_variant_records ADD CONSTRAINT active_storage_variant_records_pkey PRIMARY KEY (id); +-- +-- Name: activity_pub_activities activity_pub_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_activities + ADD CONSTRAINT activity_pub_activities_pkey PRIMARY KEY (id); + + +-- +-- Name: activity_pub_actors activity_pub_actors_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_actors + ADD CONSTRAINT activity_pub_actors_pkey PRIMARY KEY (id); + + +-- +-- Name: activity_pub_instances activity_pub_instances_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_instances + ADD CONSTRAINT activity_pub_instances_pkey PRIMARY KEY (id); + + +-- +-- Name: activity_pub_objects activity_pub_objects_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_objects + ADD CONSTRAINT activity_pub_objects_pkey PRIMARY KEY (id); + + +-- +-- Name: activity_pubs activity_pubs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pubs + ADD CONSTRAINT activity_pubs_pkey PRIMARY KEY (id); + + -- -- Name: blazer_audits blazer_audits_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -1865,6 +1977,48 @@ CREATE UNIQUE INDEX index_active_storage_blobs_on_key_and_service_name ON public CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON public.active_storage_variant_records USING btree (blob_id, variation_digest); +-- +-- Name: index_activity_pub_activities_on_activity_pub_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_activities_on_activity_pub_id ON public.activity_pub_activities USING btree (activity_pub_id); + + +-- +-- Name: index_activity_pub_actors_on_instance_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_actors_on_instance_id ON public.activity_pub_actors USING btree (instance_id); + + +-- +-- Name: index_activity_pub_actors_on_uri; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USING btree (uri); + + +-- +-- Name: index_activity_pub_instances_on_hostname; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname); + + +-- +-- Name: index_activity_pub_objects_on_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_objects_on_actor_id ON public.activity_pub_objects USING btree (actor_id); + + +-- +-- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_activity_pubs_on_site_id_and_object_id_and_object_type ON public.activity_pubs USING btree (site_id, object_id, object_type); + + -- -- Name: index_blazer_audits_on_query_id; Type: INDEX; Schema: public; Owner: - -- @@ -2320,6 +2474,11 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230829204127'), ('20230921155401'), ('20230927153926'), -('20240216170202'); +('20240216170202'), +('20240219153919'), +('20240219175839'), +('20240219204011'), +('20240219204224'), +('20240220161414'); From 8921de81aef45c3d822144fc1f2e4bbb38fe0f3e Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 17:13:42 -0300 Subject: [PATCH 425/814] feat: rutas --- .../api/v1/concerns/webhook_concern.rb | 72 ------------------ .../api/v1/social_inbox_controller.rb | 22 ------ .../v1/webhooks/concerns/webhook_concern.rb | 76 +++++++++++++++++++ .../api/v1/webhooks/pull_controller.rb | 25 ++++++ .../v1/webhooks/social_inbox_controller.rb | 39 ++++++++++ app/controllers/api/v1/webhooks_controller.rb | 23 ------ config/routes.rb | 4 +- 7 files changed, 142 insertions(+), 119 deletions(-) delete mode 100644 app/controllers/api/v1/concerns/webhook_concern.rb delete mode 100644 app/controllers/api/v1/social_inbox_controller.rb create mode 100644 app/controllers/api/v1/webhooks/concerns/webhook_concern.rb create mode 100644 app/controllers/api/v1/webhooks/pull_controller.rb create mode 100644 app/controllers/api/v1/webhooks/social_inbox_controller.rb delete mode 100644 app/controllers/api/v1/webhooks_controller.rb diff --git a/app/controllers/api/v1/concerns/webhook_concern.rb b/app/controllers/api/v1/concerns/webhook_concern.rb deleted file mode 100644 index 9960e550..00000000 --- a/app/controllers/api/v1/concerns/webhook_concern.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -module Api - module V1 - # Helpers para webhooks - module WebhookConcern - extend ActiveSupport::Concern - - included do - # Responde con forbidden si falla la validación del token - rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer - - private - - # Valida el token que envía la plataforma en el webhook - # - # @return [String] - def token - @token ||= - begin - header = request.headers - token = header['X-Social-Inbox'].presence - token ||= header['X-Gitlab-Token'].presence - token ||= token_from_signature(header['X-Gitea-Signature'].presence) - token ||= token_from_signature(header['X-Hub-Signature-256'].presence, 'sha256=') - token - ensure - raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if token.blank? - end - end - - # Valida token a partir de firma - # - # @param signature [String,nil] - # @param prepend [String] - # @return [String, nil] - def token_from_signature(signature, prepend = '') - return if signature.nil? - - payload = request.raw_post - - site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| - new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) - - ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s) - end - end - - # Encuentra el sitio a partir de la URL - # - # @return [Site] - def site - @site ||= Site.find_by_name!(params[:site_id]) - end - - # Encuentra le usuarie - # - # @return [Site] - def usuarie - @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end - - # Respuesta de error a plataformas - def platforms_answer(exception) - ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h }) - - head :forbidden - end - end - end - end -end diff --git a/app/controllers/api/v1/social_inbox_controller.rb b/app/controllers/api/v1/social_inbox_controller.rb deleted file mode 100644 index 3881b6bc..00000000 --- a/app/controllers/api/v1/social_inbox_controller.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Api - module V1 - # Recibe webhooks de la Social Inbox - class SocialInboxController < BaseController - include WebhookConcern - - def moderationqueued - head :accepted - end - - def onapproved - head :accepted - end - - def onrejected - head :accepted - end - end - end -end diff --git a/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb b/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb new file mode 100644 index 00000000..a546a55c --- /dev/null +++ b/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module Api + module V1 + module Webhooks + module Concerns + # Helpers para webhooks + module WebhookConcern + extend ActiveSupport::Concern + + included do + # Responde con forbidden si falla la validación del token + rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + + private + + # Valida el token que envía la plataforma en el webhook + # + # @return [String] + def token + @token ||= + begin + header = request.headers + token = header['X-Social-Inbox'].presence + token ||= header['X-Gitlab-Token'].presence + token ||= token_from_signature(header['X-Gitea-Signature'].presence) + token ||= token_from_signature(header['X-Hub-Signature-256'].presence, 'sha256=') + token + ensure + raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if token.blank? + end + end + + # Valida token a partir de firma + # + # @param signature [String,nil] + # @param prepend [String] + # @return [String, nil] + def token_from_signature(signature, prepend = '') + return if signature.nil? + + payload = request.raw_post + + site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| + new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) + + ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s) + end + end + + # Encuentra el sitio a partir de la URL + # + # @return [Site] + def site + @site ||= Site.find_by_name!(params[:site_id]) + end + + # Encuentra le usuarie + # + # @return [Site] + def usuarie + @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie + end + + # Respuesta de error a plataformas + def platforms_answer(exception) + ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h }) + + head :forbidden + end + end + end + end + end + end +end diff --git a/app/controllers/api/v1/webhooks/pull_controller.rb b/app/controllers/api/v1/webhooks/pull_controller.rb new file mode 100644 index 00000000..5f0b703b --- /dev/null +++ b/app/controllers/api/v1/webhooks/pull_controller.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Api + module V1 + module Webhooks + # Recibe webhooks y lanza un PullJob + class PullController < BaseController + include WebhookConcern + + # Trae los cambios a partir de un post de Webhooks: + # (Gitlab, Github, Gitea, etc) + # + # @return [nil] + def pull + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') + end + + GitPullJob.perform_later(site, usuarie, message) + head :ok + end + end + end + end +end diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb new file mode 100644 index 00000000..bc604156 --- /dev/null +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Api + module V1 + module Webhooks + # Recibe webhooks de la Social Inbox + # + # @see {https://www.w3.org/TR/activitypub/} + class SocialInboxController < BaseController + include Api::V1::Webhooks::Concerns::WebhookConcern + + # Cuando una actividad ingresa en la cola de moderación, la + # recibimos por acá + # + # Vamos a recibir Create, Update, Delete, Follow, Undo y obtener + # el objeto dentro de cada una para guardar un estado asociado + # al sitio. + # + # El objeto del estado puede ser un objeto o une actore, + # dependiendo de la actividad. + def moderationqueued + head :accepted + end + + # Cuando aprobamos una actividad, recibimos la confirmación y + # cambiamos el estado + def onapproved + head :accepted + end + + # Cuando rechazamos una actividad, recibimos la confirmación y + # cambiamos el estado + def onrejected + head :accepted + end + end + end + end +end diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb deleted file mode 100644 index f64fa93c..00000000 --- a/app/controllers/api/v1/webhooks_controller.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Api - module V1 - # Recibe webhooks y lanza un PullJob - class WebhooksController < BaseController - include WebhookConcern - - # Trae los cambios a partir de un post de Webhooks: - # (Gitlab, Github, Gitea, etc) - # - # @return [nil] - def pull - message = I18n.with_locale(site.default_locale) do - I18n.t('webhooks.pull.message') - end - - GitPullJob.perform_later(site, usuarie, message) - head :ok - end - end - end -end diff --git a/config/routes.rb b/config/routes.rb index f6f081f7..88376dde 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,9 +19,9 @@ Rails.application.routes.draw do post :'contact/:form', to: 'contact#receive', as: :contact namespace :webhooks do - post :pull, to: 'webhooks#pull' + post :pull, to: 'pull#pull' - namespace :social_inbox do + scope :social_inbox do post :moderationqueued, to: 'social_inbox#moderationqueued' post :onapproved, to: 'social_inbox#onapproved' post :onrejected, to: 'social_inbox#onrejected' From 9fa43353144d01154dca75cf88bd27a4c879dc03 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 17:15:43 -0300 Subject: [PATCH 426/814] feat: recibir y almacenar actividades --- Gemfile | 3 + Gemfile.lock | 237 ++++++++++-------- .../v1/webhooks/social_inbox_controller.rb | 105 ++++++++ app/models/activity_pub/activity.rb | 5 + .../activity_pub/concerns/json_ld_concern.rb | 6 +- app/models/site/social_distributed_press.rb | 2 + app/models/social_inbox.rb | 19 +- 7 files changed, 262 insertions(+), 115 deletions(-) diff --git a/Gemfile b/Gemfile index 3cf01934..8e955e8f 100644 --- a/Gemfile +++ b/Gemfile @@ -80,6 +80,9 @@ gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' gem 'device_detector' +gem 'after_commit_everywhere' +gem 'aasm' + # database gem 'hairtrigger' gem 'pg' diff --git a/Gemfile.lock b/Gemfile.lock index 5b8ca619..50745140 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,74 +27,80 @@ GIT GEM remote: https://17.3.alpine.gems.sutty.nl/ specs: - actioncable (6.1.7.3) - actionpack (= 6.1.7.3) - activesupport (= 6.1.7.3) + aasm (5.5.0) + concurrent-ruby (~> 1.0) + actioncable (6.1.7.4) + actionpack (= 6.1.7.4) + activesupport (= 6.1.7.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.3) - actionpack (= 6.1.7.3) - activejob (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionmailbox (6.1.7.4) + actionpack (= 6.1.7.4) + activejob (= 6.1.7.4) + activerecord (= 6.1.7.4) + activestorage (= 6.1.7.4) + activesupport (= 6.1.7.4) mail (>= 2.7.1) - actionmailer (6.1.7.3) - actionpack (= 6.1.7.3) - actionview (= 6.1.7.3) - activejob (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionmailer (6.1.7.4) + actionpack (= 6.1.7.4) + actionview (= 6.1.7.4) + activejob (= 6.1.7.4) + activesupport (= 6.1.7.4) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.7.3) - actionview (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionpack (6.1.7.4) + actionview (= 6.1.7.4) + activesupport (= 6.1.7.4) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.3) - actionpack (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + actiontext (6.1.7.4) + actionpack (= 6.1.7.4) + activerecord (= 6.1.7.4) + activestorage (= 6.1.7.4) + activesupport (= 6.1.7.4) nokogiri (>= 1.8.5) - actionview (6.1.7.3) - activesupport (= 6.1.7.3) + actionview (6.1.7.4) + activesupport (= 6.1.7.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.7.3) - activesupport (= 6.1.7.3) + activejob (6.1.7.4) + activesupport (= 6.1.7.4) globalid (>= 0.3.6) - activemodel (6.1.7.3) - activesupport (= 6.1.7.3) - activerecord (6.1.7.3) - activemodel (= 6.1.7.3) - activesupport (= 6.1.7.3) - activestorage (6.1.7.3) - actionpack (= 6.1.7.3) - activejob (= 6.1.7.3) - activerecord (= 6.1.7.3) - activesupport (= 6.1.7.3) + activemodel (6.1.7.4) + activesupport (= 6.1.7.4) + activerecord (6.1.7.4) + activemodel (= 6.1.7.4) + activesupport (= 6.1.7.4) + activestorage (6.1.7.4) + actionpack (= 6.1.7.4) + activejob (= 6.1.7.4) + activerecord (= 6.1.7.4) + activesupport (= 6.1.7.4) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.3) + activesupport (6.1.7.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.4) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) adsp (1.0.10) + after_commit_everywhere (1.4.0) + activerecord (>= 4.2) + activesupport ast (2.4.2) autoprefixer-rails (10.4.13.0) execjs (~> 2) - bcrypt (3.1.19-x86_64-linux-musl) + bcrypt (3.1.20-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl) benchmark-ips (2.12.0) + bigdecimal (3.1.1) bindex (0.8.1-x86_64-linux-musl) blazer (2.6.5) activerecord (>= 5) @@ -105,7 +111,8 @@ GEM autoprefixer-rails (>= 9.1.0) popper_js (>= 1.16.1, < 2) sassc-rails (>= 2.0.0) - brakeman (5.4.1) + brakeman (6.1.1) + racc builder (3.2.4) bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) @@ -125,6 +132,7 @@ GEM concurrent-ruby (1.2.2) concurrent-ruby-ext (1.2.2-x86_64-linux-musl) concurrent-ruby (= 1.2.2) + connection_pool (2.4.1) crass (1.0.6) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) @@ -132,7 +140,7 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - date (3.3.3-x86_64-linux-musl) + date (3.3.4-x86_64-linux-musl) dead_end (4.0.0) derailed_benchmarks (2.1.2) benchmark-ips (~> 2) @@ -146,8 +154,8 @@ GEM rake (> 10, < 14) ruby-statistics (>= 2.1) thor (>= 0.19, < 2) - device_detector (1.1.1) - devise (4.9.2) + device_detector (1.1.2) + devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -155,7 +163,7 @@ GEM warden (~> 1.2.3) devise-i18n (1.11.0) devise (>= 4.9.0) - devise_invitable (2.0.8) + devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) distributed-press-api-client (0.4.0rc2) @@ -172,10 +180,10 @@ GEM railties (>= 3.2) down (5.4.1) addressable (~> 2.8) - dry-configurable (1.0.1) + dry-configurable (1.1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-core (1.0.0) + dry-core (1.0.1) concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) dry-inflector (1.0.0) @@ -184,7 +192,7 @@ GEM concurrent-ruby (~> 1.0) dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-schema (1.13.1) + dry-schema (1.13.3) concurrent-ruby (~> 1.0) dry-configurable (~> 1.0, >= 1.0.1) dry-core (~> 1.0, < 2) @@ -192,7 +200,8 @@ GEM dry-logic (>= 1.4, < 2) dry-types (>= 1.7, < 2) zeitwerk (~> 2.6) - dry-types (1.7.1) + dry-types (1.7.2) + bigdecimal (~> 3.0) concurrent-ruby (~> 1.0) dry-core (~> 1.0) dry-inflector (~> 1.0) @@ -225,25 +234,25 @@ GEM ffi (~> 1.0) git_clone_url (2.0.0) uri-ssh_git (>= 2.0) - globalid (1.1.0) - activesupport (>= 5.0) + globalid (1.2.1) + activesupport (>= 6.1) groupdate (6.2.1) activesupport (>= 5.2) hairtrigger (1.0.0) activerecord (>= 6.0, < 8) ruby2ruby (~> 2.4) ruby_parser (~> 3.10) - haml (6.1.2-x86_64-linux-musl) + haml (6.3.0) temple (>= 0.8.2) thor tilt haml-lint (0.999.999) haml_lint - haml_lint (0.45.0) - haml (>= 4.0, < 6.2) + haml_lint (0.53.0) + haml (>= 5.0) parallel (~> 1.10) rainbow - rubocop (>= 0.50.0) + rubocop (>= 1.0) sysexits (~> 1.1) hamlit (3.0.3-x86_64-linux-musl) temple (>= 0.8.2) @@ -296,7 +305,7 @@ GEM terminal-table (~> 2.0) jekyll-commonmark (1.4.0) commonmarker (~> 0.22) - jekyll-images (0.4.1) + jekyll-images (0.4.4) jekyll (~> 4) ruby-filemagic (~> 0.7) ruby-vips (~> 2) @@ -306,7 +315,7 @@ GEM sassc (> 2.0.1, < 3.0) jekyll-watch (2.2.1) listen (~> 3.0) - json (2.6.3-x86_64-linux-musl) + json (2.7.1-x86_64-linux-musl) jwt (2.6.0) kaminari (1.2.2) activesupport (>= 4.1.0) @@ -335,12 +344,12 @@ GEM loaf (0.10.0) railties (>= 3.2) lockbox (1.2.0) - lograge (0.12.0) + lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.21.3) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -354,36 +363,37 @@ GEM method_source (1.0.0) mini_histogram (0.3.1) mini_magick (4.12.0) - mini_mime (1.1.2) - mini_portile2 (2.8.2) - minitest (5.18.0) + mini_mime (1.1.5) + mini_portile2 (2.8.5) + minitest (5.21.1) mobility (1.2.9) i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) - net-imap (0.3.4) + net-imap (0.4.9) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.4.0) net-protocol - net-ssh (7.1.0) + net-ssh (7.2.1) netaddr (2.0.6) - nio4r (2.5.9-x86_64-linux-musl) - nokogiri (1.15.4-x86_64-linux-musl) + nio4r (2.7.0-x86_64-linux-musl) + nokogiri (1.16.0-x86_64-linux-musl) mini_portile2 (~> 2.8.2) racc (~> 1.4) orm_adapter (0.5.0) pairing_heap (3.0.1) - parallel (1.23.0) - parser (3.2.2.1) + parallel (1.24.0) + parser (3.2.2.3) ast (~> 2.4.1) + racc pathutil (0.16.2) forwardable-extended (~> 2.6) - pg (1.5.3-x86_64-linux-musl) + pg (1.5.4-x86_64-linux-musl) pg_search (2.3.6) activerecord (>= 5.2) activesupport (>= 5.2) @@ -393,55 +403,57 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.3) - puma (6.3.1-x86_64-linux-musl) + public_suffix (5.0.4) + puma (6.4.2-x86_64-linux-musl) nio4r (~> 2.0) - pundit (2.3.0) + pundit (2.3.1) activesupport (>= 3.0.0) que (2.2.1) - racc (1.7.1-x86_64-linux-musl) - rack (2.2.7) + racc (1.7.3-x86_64-linux-musl) + rack (2.2.8) rack-cors (2.0.1) rack (>= 2.0.0) rack-mini-profiler (3.1.0) rack (>= 1.2.0) - rack-proxy (0.7.6) + rack-proxy (0.7.7) rack rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.3) - actioncable (= 6.1.7.3) - actionmailbox (= 6.1.7.3) - actionmailer (= 6.1.7.3) - actionpack (= 6.1.7.3) - actiontext (= 6.1.7.3) - actionview (= 6.1.7.3) - activejob (= 6.1.7.3) - activemodel (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + rails (6.1.7.4) + actioncable (= 6.1.7.4) + actionmailbox (= 6.1.7.4) + actionmailer (= 6.1.7.4) + actionpack (= 6.1.7.4) + actiontext (= 6.1.7.4) + actionview (= 6.1.7.4) + activejob (= 6.1.7.4) + activemodel (= 6.1.7.4) + activerecord (= 6.1.7.4) + activestorage (= 6.1.7.4) + activesupport (= 6.1.7.4) bundler (>= 1.15.0) - railties (= 6.1.7.3) + railties (= 6.1.7.4) sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.5.0) - loofah (~> 2.19, >= 2.19.1) - rails-i18n (7.0.7) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + rails-i18n (7.0.8) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) rails_warden (0.6.0) warden (>= 1.2.0) - railties (6.1.7.3) - actionpack (= 6.1.7.3) - activesupport (= 6.1.7.3) + railties (6.1.7.4) + actionpack (= 6.1.7.4) + activesupport (= 6.1.7.4) method_source rake (>= 12.2) thor (~> 1.0) rainbow (3.1.1) - rake (13.0.6) + rake (13.1.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) @@ -464,13 +476,13 @@ GEM redis-store (>= 1.2, < 2) redis-store (1.9.2) redis (>= 4, < 6) - regexp_parser (2.8.0) + regexp_parser (2.9.0) request_store (1.5.1) rack (>= 1.4) - responders (3.1.0) + responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.5) + rexml (3.2.6) rgl (0.6.3) pairing_heap (>= 0.3.0) rexml (~> 3.2, >= 3.2.4) @@ -486,18 +498,19 @@ GEM rubocop-ast (>= 1.24.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.28.1) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) - rubocop-rails (2.19.1) + rubocop-rails (2.23.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-brs (1.3.3-x86_64-linux-musl) adsp (~> 1.0) ruby-filemagic (0.7.3-x86_64-linux-musl) ruby-progressbar (1.13.0) ruby-statistics (3.0.2) - ruby-vips (2.1.4) + ruby-vips (2.2.0) ffi (~> 1.12) ruby2ruby (2.5.0) ruby_parser (~> 3.1) @@ -530,14 +543,14 @@ GEM spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) spring (>= 4) - sprockets (4.2.0) + sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - sqlite3 (1.6.3-x86_64-linux-musl) + sqlite3 (1.7.0-x86_64-linux-musl) mini_portile2 (~> 2.8.0) stackprof (0.2.25-x86_64-linux-musl) stream (0.5.5) @@ -546,13 +559,13 @@ GEM jekyll (~> 4) symbol-fstring (1.0.2-x86_64-linux-musl) sysexits (1.2.0) - temple (0.10.1) + temple (0.10.3) terminal-table (2.0.0) unicode-display_width (~> 1.1, >= 1.1.1) thor (1.3.0) - tilt (2.1.0) + tilt (2.3.0) timecop (0.9.6) - timeout (0.3.2) + timeout (0.4.1) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) @@ -562,7 +575,7 @@ GEM execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext - unf_ext (0.0.8.2-x86_64-linux-musl) + unf_ext (0.0.9-x86_64-linux-musl) unicode-display_width (1.8.0) uri-ssh_git (2.0.0) validates_hostname (1.0.13) @@ -588,12 +601,14 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.34) - zeitwerk (2.6.8) + zeitwerk (2.6.12) PLATFORMS x86_64-linux-musl DEPENDENCIES + aasm + after_commit_everywhere bcrypt (~> 3.1.7) bcrypt_pbkdf blazer diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index bc604156..c8c695c1 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -19,6 +19,16 @@ module Api # El objeto del estado puede ser un objeto o une actore, # dependiendo de la actividad. def moderationqueued + # Devuelve un error si el token no es válido + usuarie.present? + + ActivityPub.transaction do + # Crea todos los registros necesarios y actualiza el estado + activity.update_activity_pub_state! + end + rescue ActiveRecord::RecordInvalid => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, usuarie: usuarie.email, activity: original_activity }) + ensure head :accepted end @@ -33,6 +43,101 @@ module Api def onrejected head :accepted end + + private + + # Si el objeto ya viene incorporado en la actividad o lo tenemos + # que traer remotamente. + # + # @return [Bool] + def object_embedded? + @object_embedded ||= original_activity[:object].is_a?(Hash) + end + + # Encuentra la URI del objeto o falla si no la encuentra. + # + # @return [String] + def object_uri + @object_uri ||= + begin + case original_activity[:object] + when String then original_activity[:object] + when Hash then original_activity.dig(:object, :id) + end + end + ensure + raise ActiveRecord::RecordNotFound, 'object id missing' unless @object_uri + end + + # Atajo a la instancia + # + # @return [ActivityPub::Instance] + def instance + actor.instance + end + + # Genera un objeto a partir de la actividad. Si el objeto ya + # existe, actualiza su contenido. + # + # @return [ActivityPub::Object] + def object + @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(actor: actor, uri: object_uri).tap do |o| + o.content = original_object if object_embedded? + o.save! + end + end + + # Genera el seguimiento del estado del objeto con respecto al + # sitio. + # + # @return [ActivityPub] + def activity_pub + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, object: object) + end + + # Crea la actividad y la vincula con el estado + # + # @return [ActivityPub::Activity] + def activity + @activity ||= ActivityPub::Activity.type_from(original_activity).new(uri: original_activity[:id], activity_pub: activity_pub).tap do |a| + a.content = original_activity.dup + a.content[:object] = object.uri + a.save! + end + end + + # Actor, si no hay instancia, la crea en el momento + # + # @return [Actor] + def actor + @actor ||= ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| + next if a.instance + + a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + a.save! + end + end + + # Descubre la actividad recibida, generando un error si la + # actividad no está dirigida a nosotres. + # + # @todo Validar formato + # @return [Hash] + def original_activity + @original_activity ||= FastJsonparser.parse(request.raw_post).tap do |activity| + raise '@context missing' unless activity[:@context].presence + raise 'id missing' unless activity[:id].presence + raise 'object missing' unless activity[:object].presence + raise 'not for us' unless [activity[:to]].flatten.include?(site.social_inbox.actor_id) + rescue RuntimeError => e + raise ActiveRecord::RecordNotFound, e.message + end + end + + # @return [Hash,String] + def original_object + @original_object ||= original_activity[:object].dup + end end end end diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index 4a88c1f3..a1f734e0 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -21,4 +21,9 @@ class ActivityPub::Activity < ApplicationRecord # Siempre en orden descendiente para saber el último estado default_scope -> { order(created_at: :desc) } + + # Cambia la máquina de estados según el tipo de actividad + def update_activity_pub_state! + nil + end end diff --git a/app/models/activity_pub/concerns/json_ld_concern.rb b/app/models/activity_pub/concerns/json_ld_concern.rb index b0899606..bc30330c 100644 --- a/app/models/activity_pub/concerns/json_ld_concern.rb +++ b/app/models/activity_pub/concerns/json_ld_concern.rb @@ -16,9 +16,11 @@ class ActivityPub # @param object [Hash] # @return [Activity] def self.type_from(object) - "#{self.class.name}::#{object[:type].presence || 'Generic'}".constantize + raise NameError unless object.is_a?(Hash) + + "#{model_name.name}::#{object[:type].presence || 'Generic'}".constantize rescue NameError - self.class::Generic + model_name.name.constantize::Generic end private diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index d3ebf579..c3abe06e 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -10,6 +10,8 @@ class Site included do encrypts :private_key_pem + has_many :activity_pubs + before_save :generate_private_key_pem!, unless: :private_key_pem? # @return [SocialInbox] diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 24f749be..78362a10 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -24,6 +24,12 @@ class SocialInbox end end + def actor_id + @actor_id ||= generate_uri do |uri| + uri.path = '/about.jsonld' + end + end + # @return [DistributedPress::V1::Social::Client] def client @client ||= DistributedPress::V1::Social::Client.new( @@ -42,14 +48,23 @@ class SocialInbox # @return [String] def public_key_url - @public_key_url ||= URI("https://#{hostname}").tap do |uri| + @public_key_url ||= generate_uri do |uri| uri.path = '/about.jsonld' uri.fragment = 'main-key' - end.to_s + end end def hostname @hostname ||= site.config.dig('activity_pub', 'hostname') || site.hostname end + + # Genera una URI dentro de este sitio + # + # @return [String] + def generate_uri(&block) + @public_key_url ||= URI("https://#{hostname}").tap do |uri| + yield uri + end.to_s + end end From 88e93e3b5bab7c8fff75062bfc4788f4b33e2453 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 17:15:57 -0300 Subject: [PATCH 427/814] feat: al eliminar una actividad, vaciar su objeto --- app/models/activity_pub.rb | 11 +++++++++++ app/models/activity_pub/activity/delete.rb | 8 +++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index c0474b89..c15998ea 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -29,5 +29,16 @@ class ActivityPub < ApplicationRecord state :reported # Le actore eliminó el objeto state :deleted + + # Recibir una acción de eliminación, eliminar el contenido de la + # base de datos. Esto elimina el contenido para todos los sitios + # porque estamos respetando lo que pidió le actore. + event :delete do + transitions to: :deleted + + after do + object.update(object: {}) + end + end end end diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index f3684a0f..1730d49d 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -1,3 +1,9 @@ # frozen_string_literal: true -class ActivityPub::Activity::Delete < ActivityPub::Activity; end +class ActivityPub::Activity::Delete < ActivityPub::Activity + # Si estamos eliminando el objeto, tenemos que vaciar su contenido y + # cambiar el estado a borrado + def update_activity_pub_state! + activity_pub.deleted! + end +end From 8ff556c9ed5f4f585c1148488bed5930d2db6d91 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 17:16:08 -0300 Subject: [PATCH 428/814] fix: al actualizar un objeto, pausar la actividad --- app/models/activity_pub/activity/update.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity/update.rb b/app/models/activity_pub/activity/update.rb index 8089cdcf..34703938 100644 --- a/app/models/activity_pub/activity/update.rb +++ b/app/models/activity_pub/activity/update.rb @@ -1,3 +1,9 @@ # frozen_string_literal: true -class ActivityPub::Activity::Update < ActivityPub::Activity; end +class ActivityPub::Activity::Update < ActivityPub::Activity + # Si estamos actualizando el objeto, tenemos que devolverlo a estado + # de moderación + def update_activity_pub_state! + activity_pub.paused! + end +end From 9a479a157b6d865cf4233c9737bf26d750934e99 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 17:18:15 -0300 Subject: [PATCH 429/814] feat: volver a pausar un objeto aprobado cuando se lo actualiza --- app/models/activity_pub.rb | 6 ++++++ app/models/activity_pub/activity/update.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index c15998ea..2a127433 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -40,5 +40,11 @@ class ActivityPub < ApplicationRecord object.update(object: {}) end end + + # Si un objeto previamente aprobado fue actualizado, volvemos a + # pausarlo. + event :pause do + transitions from: :approved, to: :paused + end end end diff --git a/app/models/activity_pub/activity/update.rb b/app/models/activity_pub/activity/update.rb index 34703938..e9203ba5 100644 --- a/app/models/activity_pub/activity/update.rb +++ b/app/models/activity_pub/activity/update.rb @@ -4,6 +4,6 @@ class ActivityPub::Activity::Update < ActivityPub::Activity # Si estamos actualizando el objeto, tenemos que devolverlo a estado # de moderación def update_activity_pub_state! - activity_pub.paused! + activity_pub.pause! if activity_pub.approved? end end From fc7a524a85189bd1cdfe2c86cffa938faa5962aa Mon Sep 17 00:00:00 2001 From: f Date: Tue, 20 Feb 2024 17:18:39 -0300 Subject: [PATCH 430/814] fix: aasm --- config/application.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/application.rb b/config/application.rb index 73a7a884..27a21cc6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -2,6 +2,7 @@ require_relative 'boot' +require 'aasm' require 'redis-client' require 'hiredis-client' require 'brs' From 051d8c6d5624486fb85f9f625eec6bf8ec854789 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 12:30:01 -0300 Subject: [PATCH 431/814] =?UTF-8?q?feat:=20obtener=20el=20contenido=20del?= =?UTF-8?q?=20objeto=20m=C3=A1s=20adelante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/webhooks/social_inbox_controller.rb | 9 +++++++-- app/jobs/activity_pub/fetch_job.rb | 18 ++++++++++++++++++ app/models/social_inbox.rb | 6 ++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 app/jobs/activity_pub/fetch_job.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c8c695c1..e51b89dd 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -77,12 +77,17 @@ module Api end # Genera un objeto a partir de la actividad. Si el objeto ya - # existe, actualiza su contenido. + # existe, actualiza su contenido. Si el objeto no viene + # incorporado, obtenemos el contenido más tarde. # # @return [ActivityPub::Object] def object @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(actor: actor, uri: object_uri).tap do |o| - o.content = original_object if object_embedded? + if object_embedded? + o.content = original_object + else + ActivityPub::FetchJob.perform_later(site: site, object: object) + end o.save! end end diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb new file mode 100644 index 00000000..526cdafb --- /dev/null +++ b/app/jobs/activity_pub/fetch_job.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Obtiene o actualiza el contenido de un objeto, usando las credenciales +# del sitio. +# +# XXX: Esto usa las credenciales del sitio para volver el objeto +# disponible para todo el CMS. Asumimos que el objeto devuelto es el +# mismo para todo el mundo y las credenciales solo son para +# autenticación. +class ActivityPub::FetchJob < ApplicationJob + def perform(site:, object:) + ActivityPub::Object.transaction do + response = site.social_inbox.dereferencer.get(uri: object.uri) + + object.update(content: FastJsonparser.parse(response.body)) if response.ok? + end + end +end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 78362a10..624ee571 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -2,6 +2,7 @@ require 'distributed_press/v1/social/client' require 'distributed_press/v1/social/hook' +require 'distributed_press/v1/social/dereferencer' # Gestiona la Social Inbox de un sitio class SocialInbox @@ -41,6 +42,11 @@ class SocialInbox ) end + # @return [DistributedPress::V1::Social::Dereferencer] + def dereferencer + @dereferencer ||= DistributedPress::V1::Social::Dereferencer.new(client: client) + end + # @return [DistributedPress::V1::Social::Hook] def hook @hook ||= DistributedPress::V1::Social::Hook.new(client: client, actor: actor) From fb4401fd537cf0071ce41963334ec919a70ada63 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 12:32:39 -0300 Subject: [PATCH 432/814] feat: no actualizar si no es necesario MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cuando la respuesta viene desde la caché, no es es necesario modificar el objeto. --- app/jobs/activity_pub/fetch_job.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 526cdafb..097a8d32 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -12,7 +12,11 @@ class ActivityPub::FetchJob < ApplicationJob ActivityPub::Object.transaction do response = site.social_inbox.dereferencer.get(uri: object.uri) - object.update(content: FastJsonparser.parse(response.body)) if response.ok? + # @todo Fallar cuando la respuesta no funcione? + return unless response.ok? + return unless response.miss? + + object.update(content: FastJsonparser.parse(response.body)) end end end From 091d5ac41d5a0bfc1ff30ae4e28a6b61c74a963c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 12:46:38 -0300 Subject: [PATCH 433/814] chore: rubocop --- .../v1/webhooks/social_inbox_controller.rb | 18 ++++++++------- app/jobs/activity_pub/fetch_job.rb | 18 ++++++++------- app/models/activity_pub/activity.rb | 22 ++++++++++--------- app/models/activity_pub/activity/create.rb | 6 ++++- app/models/activity_pub/activity/delete.rb | 14 +++++++----- app/models/activity_pub/activity/flag.rb | 6 ++++- app/models/activity_pub/activity/follow.rb | 6 ++++- app/models/activity_pub/activity/generic.rb | 6 ++++- app/models/activity_pub/activity/undo.rb | 6 ++++- app/models/activity_pub/activity/update.rb | 14 +++++++----- app/models/activity_pub/actor.rb | 12 +++++----- app/models/activity_pub/instance.rb | 22 ++++++++++--------- app/models/activity_pub/object.rb | 12 +++++----- app/models/activity_pub/object/application.rb | 6 ++++- app/models/activity_pub/object/article.rb | 6 ++++- app/models/activity_pub/object/generic.rb | 6 ++++- app/models/activity_pub/object/note.rb | 6 ++++- .../activity_pub/object/organization.rb | 6 ++++- app/models/activity_pub/object/person.rb | 6 ++++- app/models/social_inbox.rb | 4 +--- 20 files changed, 132 insertions(+), 70 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index e51b89dd..3341b33d 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -27,7 +27,9 @@ module Api activity.update_activity_pub_state! end rescue ActiveRecord::RecordInvalid => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, usuarie: usuarie.email, activity: original_activity }) + ExceptionNotifier.notify_exception(e, + data: { site: site.name, usuarie: usuarie.email, + activity: original_activity }) ensure head :accepted end @@ -59,11 +61,9 @@ module Api # @return [String] def object_uri @object_uri ||= - begin - case original_activity[:object] - when String then original_activity[:object] - when Hash then original_activity.dig(:object, :id) - end + case original_activity[:object] + when String then original_activity[:object] + when Hash then original_activity.dig(:object, :id) end ensure raise ActiveRecord::RecordNotFound, 'object id missing' unless @object_uri @@ -82,7 +82,8 @@ module Api # # @return [ActivityPub::Object] def object - @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(actor: actor, uri: object_uri).tap do |o| + @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(actor: actor, + uri: object_uri).tap do |o| if object_embedded? o.content = original_object else @@ -104,7 +105,8 @@ module Api # # @return [ActivityPub::Activity] def activity - @activity ||= ActivityPub::Activity.type_from(original_activity).new(uri: original_activity[:id], activity_pub: activity_pub).tap do |a| + @activity ||= ActivityPub::Activity.type_from(original_activity).new(uri: original_activity[:id], + activity_pub: activity_pub).tap do |a| a.content = original_activity.dup a.content[:object] = object.uri a.save! diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 097a8d32..ff14c795 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -7,16 +7,18 @@ # disponible para todo el CMS. Asumimos que el objeto devuelto es el # mismo para todo el mundo y las credenciales solo son para # autenticación. -class ActivityPub::FetchJob < ApplicationJob - def perform(site:, object:) - ActivityPub::Object.transaction do - response = site.social_inbox.dereferencer.get(uri: object.uri) +class ActivityPub + class FetchJob < ApplicationJob + def perform(site:, object:) + ActivityPub::Object.transaction do + response = site.social_inbox.dereferencer.get(uri: object.uri) - # @todo Fallar cuando la respuesta no funcione? - return unless response.ok? - return unless response.miss? + # @todo Fallar cuando la respuesta no funcione? + return unless response.ok? + return unless response.miss? - object.update(content: FastJsonparser.parse(response.body)) + object.update(content: FastJsonparser.parse(response.body)) + end end end end diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index a1f734e0..5ee3d2d1 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -11,19 +11,21 @@ # envía como referencia en lugar de anidarlo. # # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} -class ActivityPub::Activity < ApplicationRecord - include ActivityPub::Concerns::JsonLdConcern +class ActivityPub + class Activity < ApplicationRecord + include ActivityPub::Concerns::JsonLdConcern - belongs_to :activity_pub - has_one :object, through: :activity_pub + belongs_to :activity_pub + has_one :object, through: :activity_pub - validates :activity_pub_id, presence: true + validates :activity_pub_id, presence: true - # Siempre en orden descendiente para saber el último estado - default_scope -> { order(created_at: :desc) } + # Siempre en orden descendiente para saber el último estado + default_scope -> { order(created_at: :desc) } - # Cambia la máquina de estados según el tipo de actividad - def update_activity_pub_state! - nil + # Cambia la máquina de estados según el tipo de actividad + def update_activity_pub_state! + nil + end end end diff --git a/app/models/activity_pub/activity/create.rb b/app/models/activity_pub/activity/create.rb index 3dcba5c2..4acafaf2 100644 --- a/app/models/activity_pub/activity/create.rb +++ b/app/models/activity_pub/activity/create.rb @@ -1,3 +1,7 @@ # frozen_string_literal: true -class ActivityPub::Activity::Create < ActivityPub::Activity; end +class ActivityPub + module Activity + class Create < ActivityPub::Activity; end + end +end diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 1730d49d..2973f730 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -1,9 +1,13 @@ # frozen_string_literal: true -class ActivityPub::Activity::Delete < ActivityPub::Activity - # Si estamos eliminando el objeto, tenemos que vaciar su contenido y - # cambiar el estado a borrado - def update_activity_pub_state! - activity_pub.deleted! +class ActivityPub + module Activity + class Delete < ActivityPub::Activity + # Si estamos eliminando el objeto, tenemos que vaciar su contenido y + # cambiar el estado a borrado + def update_activity_pub_state! + activity_pub.deleted! + end + end end end diff --git a/app/models/activity_pub/activity/flag.rb b/app/models/activity_pub/activity/flag.rb index 2911911e..27bbe266 100644 --- a/app/models/activity_pub/activity/flag.rb +++ b/app/models/activity_pub/activity/flag.rb @@ -1,3 +1,7 @@ # frozen_string_literal: true -class ActivityPub::Activity::Flag < ActivityPub::Activity; end +class ActivityPub + module Activity + class Flag < ActivityPub::Activity; end + end +end diff --git a/app/models/activity_pub/activity/follow.rb b/app/models/activity_pub/activity/follow.rb index c22dfd51..9e32b67d 100644 --- a/app/models/activity_pub/activity/follow.rb +++ b/app/models/activity_pub/activity/follow.rb @@ -4,4 +4,8 @@ # # Una actividad de seguimiento se refiere siempre a une actore (el # sitio) y proviene de otre actore. -class ActivityPub::Activity::Follow < ActivityPub::Activity; end +class ActivityPub + module Activity + class Follow < ActivityPub::Activity; end + end +end diff --git a/app/models/activity_pub/activity/generic.rb b/app/models/activity_pub/activity/generic.rb index 8bf76471..89c26247 100644 --- a/app/models/activity_pub/activity/generic.rb +++ b/app/models/activity_pub/activity/generic.rb @@ -1,3 +1,7 @@ # frozen_string_literal: true -class ActivityPub::Activity::Generic < ActivityPub::Activity; end +class ActivityPub + module Activity + class Generic < ActivityPub::Activity; end + end +end diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb index a4915394..98233af9 100644 --- a/app/models/activity_pub/activity/undo.rb +++ b/app/models/activity_pub/activity/undo.rb @@ -4,5 +4,9 @@ # # Deshace una actividad, dependiendo de la actividad a la que se # refiere. -class ActivityPub::Activity::Undo < ActivityPub::Activity +class ActivityPub + module Activity + class Undo < ActivityPub::Activity + end + end end diff --git a/app/models/activity_pub/activity/update.rb b/app/models/activity_pub/activity/update.rb index e9203ba5..50622b93 100644 --- a/app/models/activity_pub/activity/update.rb +++ b/app/models/activity_pub/activity/update.rb @@ -1,9 +1,13 @@ # frozen_string_literal: true -class ActivityPub::Activity::Update < ActivityPub::Activity - # Si estamos actualizando el objeto, tenemos que devolverlo a estado - # de moderación - def update_activity_pub_state! - activity_pub.pause! if activity_pub.approved? +class ActivityPub + module Activity + class Update < ActivityPub::Activity + # Si estamos actualizando el objeto, tenemos que devolverlo a estado + # de moderación + def update_activity_pub_state! + activity_pub.pause! if activity_pub.approved? + end + end end end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index f29c382a..7be69602 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -5,10 +5,12 @@ # Actor es la entidad que realiza acciones en ActivityPub # # @todo Obtener el perfil dinámicamente -class ActivityPub::Actor < ApplicationRecord - include ActivityPub::Concerns::JsonLdConcern +class ActivityPub + class Actor < ApplicationRecord + include ActivityPub::Concerns::JsonLdConcern - belongs_to :instance - has_many :activity_pubs, as: :object - has_many :objects + belongs_to :instance + has_many :activity_pubs, as: :object + has_many :objects + end end diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index fe4a777b..b13b8676 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -4,18 +4,20 @@ # # Representa cada instancia del fediverso que interactúa con la Social # Inbox. -class ActivityPub::Instance < ApplicationRecord - include AASM +class ActivityPub + class Instance < ApplicationRecord + include AASM - validates :aasm_state, presence: true, inclusion: { in: %w[paused allowed blocked] } - validates :hostname, uniqueness: true, hostname: true + validates :aasm_state, presence: true, inclusion: { in: %w[paused allowed blocked] } + validates :hostname, uniqueness: true, hostname: true - has_many :activity_pubs - has_many :actors + has_many :activity_pubs + has_many :actors - aasm do - state :paused, initial: true - state :allowed - state :blocked + aasm do + state :paused, initial: true + state :allowed + state :blocked + end end end diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 519749ef..49a06772 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -1,11 +1,13 @@ # frozen_string_literal: true # Almacena objetos de ActivityPub, como Note, Article, etc. -class ActivityPub::Object < ApplicationRecord - include ActivityPub::Concerns::JsonLdConcern +class ActivityPub + class Object < ApplicationRecord + include ActivityPub::Concerns::JsonLdConcern - belongs_to :actor - has_many :activity_pubs, as: :object + belongs_to :actor + has_many :activity_pubs, as: :object - validates :actor_id, presence: true + validates :actor_id, presence: true + end end diff --git a/app/models/activity_pub/object/application.rb b/app/models/activity_pub/object/application.rb index e8a6f97c..e8d8fa0e 100644 --- a/app/models/activity_pub/object/application.rb +++ b/app/models/activity_pub/object/application.rb @@ -3,4 +3,8 @@ # = Application = # # Una aplicación o instancia -class ActivityPub::Object::Application < ActivityPub::Object; end +class ActivityPub + module Object + class Application < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/article.rb b/app/models/activity_pub/object/article.rb index ad1a6131..69fe371c 100644 --- a/app/models/activity_pub/object/article.rb +++ b/app/models/activity_pub/object/article.rb @@ -3,4 +3,8 @@ # = Article = # # Representa artículos -class ActivityPub::Object::Article < ActivityPub::Object; end +class ActivityPub + module Object + class Article < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/generic.rb b/app/models/activity_pub/object/generic.rb index f345e7a9..c16b25c6 100644 --- a/app/models/activity_pub/object/generic.rb +++ b/app/models/activity_pub/object/generic.rb @@ -1,4 +1,8 @@ # frozen_string_literal: true # = Generic = -class ActivityPub::Object::Generic < ActivityPub::Object; end +class ActivityPub + module Object + class Generic < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/note.rb b/app/models/activity_pub/object/note.rb index 0f84c747..06b969ab 100644 --- a/app/models/activity_pub/object/note.rb +++ b/app/models/activity_pub/object/note.rb @@ -3,4 +3,8 @@ # = Note = # # Representa notas, el tipo más común de objeto del Fediverso. -class ActivityPub::Object::Note < ActivityPub::Object; end +class ActivityPub + module Object + class Note < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/organization.rb b/app/models/activity_pub/object/organization.rb index a5327d10..31e5887d 100644 --- a/app/models/activity_pub/object/organization.rb +++ b/app/models/activity_pub/object/organization.rb @@ -3,4 +3,8 @@ # = Organization = # # Una organización -class ActivityPub::Object::Organization < ActivityPub::Object; end +class ActivityPub + module Object + class Organization < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/person.rb b/app/models/activity_pub/object/person.rb index 98a1568d..fd01e515 100644 --- a/app/models/activity_pub/object/person.rb +++ b/app/models/activity_pub/object/person.rb @@ -3,4 +3,8 @@ # = Person = # # Una persona, el perfil de une actore -class ActivityPub::Object::Person < ActivityPub::Object; end +class ActivityPub + module Object + class Person < ActivityPub::Object; end + end +end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 624ee571..45b8afd8 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -69,8 +69,6 @@ class SocialInbox # # @return [String] def generate_uri(&block) - @public_key_url ||= URI("https://#{hostname}").tap do |uri| - yield uri - end.to_s + @public_key_url ||= URI("https://#{hostname}").tap(&block).to_s end end From 7b8730c34c2ca41e5f3f25bd77c15cd3cf1e572a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 13:04:15 -0300 Subject: [PATCH 434/814] feat: las actividades se aprueban cuando las confirma la SI --- .../api/v1/webhooks/social_inbox_controller.rb | 6 +++++- app/models/activity_pub.rb | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 3341b33d..76c7ec40 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -35,8 +35,12 @@ module Api end # Cuando aprobamos una actividad, recibimos la confirmación y - # cambiamos el estado + # cambiamos el estado. def onapproved + ActivityPub.transaction do + activity_pub.approve! if activity_pub.waiting? + end + head :accepted end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 2a127433..71d67722 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -21,6 +21,8 @@ class ActivityPub < ApplicationRecord aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true + # Estamos esperando respuesta desde la Social Inbox + state :waiting # Le usuarie aprobó el objeto state :approved # Le usuarie rechazó el objeto @@ -44,7 +46,12 @@ class ActivityPub < ApplicationRecord # Si un objeto previamente aprobado fue actualizado, volvemos a # pausarlo. event :pause do - transitions from: :approved, to: :paused + transitions from: %i[waiting approved], to: :paused + end + + # La actividad se aprueba + event :approve do + transitions from: :waiting, to: :approved end end end From e733c45b63cfd901e82dd9565585b2cb2bcbea3b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 13:06:06 -0300 Subject: [PATCH 435/814] fix: las actividades se pueden rechazar --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 4 ++++ app/models/activity_pub.rb | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 76c7ec40..20028708 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -47,6 +47,10 @@ module Api # Cuando rechazamos una actividad, recibimos la confirmación y # cambiamos el estado def onrejected + ActivityPub.transaction do + activity_pub.reject! if activity_pub.waiting? + end + head :accepted end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 71d67722..b8e8eded 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -53,5 +53,10 @@ class ActivityPub < ApplicationRecord event :approve do transitions from: :waiting, to: :approved end + + # La actividad fue rechazada + event :reject do + transitions from: :waiting, to: :rejected + end end end From a9bdabf409076494b97d237631d47e1bbe64e592 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 13:07:27 -0300 Subject: [PATCH 436/814] =?UTF-8?q?fix:=20se=20puede=20volver=20a=20pausar?= =?UTF-8?q?=20despu=C3=A9s=20de=20rechazarla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index b8e8eded..1c225226 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -46,7 +46,7 @@ class ActivityPub < ApplicationRecord # Si un objeto previamente aprobado fue actualizado, volvemos a # pausarlo. event :pause do - transitions from: %i[waiting approved], to: :paused + transitions from: %i[waiting approved rejected], to: :paused end # La actividad se aprueba From b477487b659e01e522d621584cb9b94fba676eb7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 13:13:24 -0300 Subject: [PATCH 437/814] =?UTF-8?q?fixup!=20feat:=20obtener=20el=20conteni?= =?UTF-8?q?do=20del=20objeto=20m=C3=A1s=20adelante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 20028708..532cca5e 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -95,8 +95,9 @@ module Api if object_embedded? o.content = original_object else - ActivityPub::FetchJob.perform_later(site: site, object: object) + ActivityPub::FetchJob.perform_later(site: site, object: o) end + o.save! end end From 732012e14b8d54db01e274db2d9f53a223523898 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 13:13:34 -0300 Subject: [PATCH 438/814] docs: orden en que se crean los registros --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 532cca5e..51322990 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -24,6 +24,12 @@ module Api ActivityPub.transaction do # Crea todos los registros necesarios y actualiza el estado + # + # 1. Actor + # 2. Instance + # 3. Object + # 4. ActivityPub + # 5. Activity activity.update_activity_pub_state! end rescue ActiveRecord::RecordInvalid => e From 1fba54d80b3ae3e021c69e5a62f01174da63db33 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 13:50:29 -0300 Subject: [PATCH 439/814] fix: checkboxes --- app/controllers/application_controller.rb | 1 + app/views/components/_block_list.haml | 6 ++++++ app/views/components/_block_lists.haml | 8 ++------ app/views/components/_checkbox.haml | 5 +++-- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_instance.haml | 6 +++--- app/views/moderation_queue/_instances.haml | 2 +- db/seeds/blocklists.yml | 5 +++++ 9 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 app/views/components/_block_list.haml create mode 100644 db/seeds/blocklists.yml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f673ee83..eca479fe 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -32,6 +32,7 @@ class ApplicationController < ActionController::Base @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) + @blocklists= YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'blocklists.yml'))) @moderation_queue.each do |activity| activity['attributedTo'] = @remote_profile end diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml new file mode 100644 index 00000000..c2af3262 --- /dev/null +++ b/app/views/components/_block_list.haml @@ -0,0 +1,6 @@ +-# Componente Listas de bloqueo de Instancias +.card.mt-3.mb-3 + .card-body + .d-flex.flex-row + = render 'components/checkbox', id: blocklist["id"] do + %span.h4= blocklist["title"] diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 8cdcd43b..1e9cd76f 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,6 +1,2 @@ --# Componente Listas de bloqueo de Instancias -.card.mt-3.mb-3 - .card-body - .d-flex.flex-row - = render 'components/checkbox' - %h4.ml-5= t('.title') +- @blocklists.each do |blocklist| + = render 'components/block_list', blocklist: blocklist diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 3444720e..27f9a776 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,3 +1,4 @@ -# Componente Checkbox -.custom-control.custom-checkbox.p-0 - %input{ type: 'checkbox', id: local_assigns[:id], class: local_assigns[:class] } +.custom-control.custom-checkbox + %input.custom-control-input{ type: 'checkbox', id: id, name: id, class: local_assigns[:class] } + %label.custom-control-label{ for: id }= yield diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index ab4fc4c7..412f0aa7 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox' + = render 'components/checkbox', id: profile['id'] .col-11 %h4 %a{href: profile['id']}= profile['preferredUsername'] diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index fea4570f..99059133 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -2,7 +2,7 @@ .flex.mx-4.my-5 .row.no-gutters .col-1 - = render 'components/checkbox' + = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters .col-4 diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 74bda75b..cff8a957 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,13 +1,13 @@ - host = instance['domain'] - host ||= instance['uri'] -- host = "https://#{host}" +- hosthttps = "https://#{host}" .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox' + = render 'components/checkbox', id: host .col-11 %h4 - %a{ href: host }= instance['title'] + %a{ href: hosthttps }= instance['title'] %p= instance['description'].html_safe %p %span= t('.users') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index d19ef8ed..c51ba74f 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -11,5 +11,5 @@ %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') -= render 'components/block_lists' += render 'components/block_lists', blocklists: @blocklists = render 'moderation_queue/block_instances_textarea' diff --git a/db/seeds/blocklists.yml b/db/seeds/blocklists.yml new file mode 100644 index 00000000..d9f9dd6f --- /dev/null +++ b/db/seeds/blocklists.yml @@ -0,0 +1,5 @@ +--- +- id: gardenfence + title: Gardenfence +- id: lista + title: Lista From 34e63ff2dca083306ada0023098a7937b373f19f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 14:07:11 -0300 Subject: [PATCH 440/814] =?UTF-8?q?feat:=20actualizar=20el=20tipo=20tambi?= =?UTF-8?q?=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index ff14c795..e5950c86 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -17,7 +17,9 @@ class ActivityPub return unless response.ok? return unless response.miss? - object.update(content: FastJsonparser.parse(response.body)) + content = FastJsonparser.parse(response.body) + + object.update(content: content, type: ActivityPub::Object.type_from(content).name) end end end From 03c0b71b5f36f14af1f8a9dbab1f9a97fb706d2f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:42:56 -0300 Subject: [PATCH 441/814] fix: no es necesario vincular actores con objetos --- .../api/v1/webhooks/social_inbox_controller.rb | 3 +-- app/models/activity_pub/actor.rb | 1 - app/models/activity_pub/object.rb | 2 -- .../20240221184007_remove_actor_from_objects.rb | 12 ++++++++++++ 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20240221184007_remove_actor_from_objects.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 51322990..c15a757d 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -96,8 +96,7 @@ module Api # # @return [ActivityPub::Object] def object - @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(actor: actor, - uri: object_uri).tap do |o| + @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(uri: object_uri).tap do |o| if object_embedded? o.content = original_object else diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 7be69602..e79a596a 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -11,6 +11,5 @@ class ActivityPub belongs_to :instance has_many :activity_pubs, as: :object - has_many :objects end end diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 49a06772..ec759e3e 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -7,7 +7,5 @@ class ActivityPub belongs_to :actor has_many :activity_pubs, as: :object - - validates :actor_id, presence: true end end diff --git a/db/migrate/20240221184007_remove_actor_from_objects.rb b/db/migrate/20240221184007_remove_actor_from_objects.rb new file mode 100644 index 00000000..6ee5822c --- /dev/null +++ b/db/migrate/20240221184007_remove_actor_from_objects.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# No es necesario vincular actores con objetos, porque la forma en que +# lo estábamos haciendo no se refiere a le actore del objeto, sino de +# acciones distintas sobre el mismo objeto, generado por une actore. +# +# Y ese valor ya lo podemos obtener desde attributedTo +class RemoveActorFromObjects < ActiveRecord::Migration[6.1] + def change + remove_column :activity_pub_objects, :actor_id, :uuid, index: true + end +end From 0443cb0fc3cce6d7e6eff11b97b9f5b5914939c1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:43:10 -0300 Subject: [PATCH 442/814] fix: responder con forbidden cuando los registros no sean validos --- app/controllers/api/v1/webhooks/concerns/webhook_concern.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb b/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb index a546a55c..b94c91f6 100644 --- a/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb +++ b/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb @@ -11,6 +11,7 @@ module Api included do # Responde con forbidden si falla la validación del token rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + rescue_from ActiveRecord::RecordInvalid, with: :platforms_answer private From 5dbff20e2bf43df6833106c1f5f790a2399b38bc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:44:04 -0300 Subject: [PATCH 443/814] fixup! chore: rubocop --- app/models/activity_pub/activity/create.rb | 2 +- app/models/activity_pub/activity/delete.rb | 2 +- app/models/activity_pub/activity/flag.rb | 2 +- app/models/activity_pub/activity/follow.rb | 2 +- app/models/activity_pub/activity/generic.rb | 2 +- app/models/activity_pub/activity/undo.rb | 2 +- app/models/activity_pub/activity/update.rb | 2 +- app/models/activity_pub/object/application.rb | 2 +- app/models/activity_pub/object/article.rb | 2 +- app/models/activity_pub/object/generic.rb | 2 +- app/models/activity_pub/object/note.rb | 2 +- app/models/activity_pub/object/organization.rb | 2 +- app/models/activity_pub/object/person.rb | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/models/activity_pub/activity/create.rb b/app/models/activity_pub/activity/create.rb index 4acafaf2..9cd32559 100644 --- a/app/models/activity_pub/activity/create.rb +++ b/app/models/activity_pub/activity/create.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ActivityPub - module Activity + class Activity class Create < ActivityPub::Activity; end end end diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 2973f730..7080375e 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ActivityPub - module Activity + class Activity class Delete < ActivityPub::Activity # Si estamos eliminando el objeto, tenemos que vaciar su contenido y # cambiar el estado a borrado diff --git a/app/models/activity_pub/activity/flag.rb b/app/models/activity_pub/activity/flag.rb index 27bbe266..ffbc374b 100644 --- a/app/models/activity_pub/activity/flag.rb +++ b/app/models/activity_pub/activity/flag.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ActivityPub - module Activity + class Activity class Flag < ActivityPub::Activity; end end end diff --git a/app/models/activity_pub/activity/follow.rb b/app/models/activity_pub/activity/follow.rb index 9e32b67d..e383490a 100644 --- a/app/models/activity_pub/activity/follow.rb +++ b/app/models/activity_pub/activity/follow.rb @@ -5,7 +5,7 @@ # Una actividad de seguimiento se refiere siempre a une actore (el # sitio) y proviene de otre actore. class ActivityPub - module Activity + class Activity class Follow < ActivityPub::Activity; end end end diff --git a/app/models/activity_pub/activity/generic.rb b/app/models/activity_pub/activity/generic.rb index 89c26247..95fff3eb 100644 --- a/app/models/activity_pub/activity/generic.rb +++ b/app/models/activity_pub/activity/generic.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ActivityPub - module Activity + class Activity class Generic < ActivityPub::Activity; end end end diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb index 98233af9..41fb5e51 100644 --- a/app/models/activity_pub/activity/undo.rb +++ b/app/models/activity_pub/activity/undo.rb @@ -5,7 +5,7 @@ # Deshace una actividad, dependiendo de la actividad a la que se # refiere. class ActivityPub - module Activity + class Activity class Undo < ActivityPub::Activity end end diff --git a/app/models/activity_pub/activity/update.rb b/app/models/activity_pub/activity/update.rb index 50622b93..19c95b68 100644 --- a/app/models/activity_pub/activity/update.rb +++ b/app/models/activity_pub/activity/update.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ActivityPub - module Activity + class Activity class Update < ActivityPub::Activity # Si estamos actualizando el objeto, tenemos que devolverlo a estado # de moderación diff --git a/app/models/activity_pub/object/application.rb b/app/models/activity_pub/object/application.rb index e8d8fa0e..99ac935c 100644 --- a/app/models/activity_pub/object/application.rb +++ b/app/models/activity_pub/object/application.rb @@ -4,7 +4,7 @@ # # Una aplicación o instancia class ActivityPub - module Object + class Object class Application < ActivityPub::Object; end end end diff --git a/app/models/activity_pub/object/article.rb b/app/models/activity_pub/object/article.rb index 69fe371c..126ba3f1 100644 --- a/app/models/activity_pub/object/article.rb +++ b/app/models/activity_pub/object/article.rb @@ -4,7 +4,7 @@ # # Representa artículos class ActivityPub - module Object + class Object class Article < ActivityPub::Object; end end end diff --git a/app/models/activity_pub/object/generic.rb b/app/models/activity_pub/object/generic.rb index c16b25c6..3e5ff719 100644 --- a/app/models/activity_pub/object/generic.rb +++ b/app/models/activity_pub/object/generic.rb @@ -2,7 +2,7 @@ # = Generic = class ActivityPub - module Object + class Object class Generic < ActivityPub::Object; end end end diff --git a/app/models/activity_pub/object/note.rb b/app/models/activity_pub/object/note.rb index 06b969ab..ca113c15 100644 --- a/app/models/activity_pub/object/note.rb +++ b/app/models/activity_pub/object/note.rb @@ -4,7 +4,7 @@ # # Representa notas, el tipo más común de objeto del Fediverso. class ActivityPub - module Object + class Object class Note < ActivityPub::Object; end end end diff --git a/app/models/activity_pub/object/organization.rb b/app/models/activity_pub/object/organization.rb index 31e5887d..e3385232 100644 --- a/app/models/activity_pub/object/organization.rb +++ b/app/models/activity_pub/object/organization.rb @@ -4,7 +4,7 @@ # # Una organización class ActivityPub - module Object + class Object class Organization < ActivityPub::Object; end end end diff --git a/app/models/activity_pub/object/person.rb b/app/models/activity_pub/object/person.rb index fd01e515..a6a85d43 100644 --- a/app/models/activity_pub/object/person.rb +++ b/app/models/activity_pub/object/person.rb @@ -4,7 +4,7 @@ # # Una persona, el perfil de une actore class ActivityPub - module Object + class Object class Person < ActivityPub::Object; end end end From ddaee30da715981c9871728706450050ecbfd091 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:44:16 -0300 Subject: [PATCH 444/814] fix: primero guardar el objeto antes de obtener su contenido --- .../api/v1/webhooks/social_inbox_controller.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c15a757d..24865c92 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -97,13 +97,13 @@ module Api # @return [ActivityPub::Object] def object @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(uri: object_uri).tap do |o| - if object_embedded? - o.content = original_object - else - ActivityPub::FetchJob.perform_later(site: site, object: o) - end + o.content = original_object if object_embedded? o.save! + + # XXX: el objeto necesita ser guardado antes de poder + # procesarlo + ActivityPub::FetchJob.perform_later(site: site, object: o) unless object_embedded? end end From d98f893a7153d5fe546c6db5632356733e2ec4eb Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:44:29 -0300 Subject: [PATCH 445/814] fix: algunas actividades no tienen destinatarie --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 24865c92..fb7ede50 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -149,7 +149,6 @@ module Api raise '@context missing' unless activity[:@context].presence raise 'id missing' unless activity[:id].presence raise 'object missing' unless activity[:object].presence - raise 'not for us' unless [activity[:to]].flatten.include?(site.social_inbox.actor_id) rescue RuntimeError => e raise ActiveRecord::RecordNotFound, e.message end From 39bbc3a2bd26c7240a933e4769e5c642cea7fff7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:44:41 -0300 Subject: [PATCH 446/814] =?UTF-8?q?fix:=20deleted=20es=20un=20m=C3=A9todo?= =?UTF-8?q?=20reservado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 1c225226..42ed3f61 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -30,13 +30,13 @@ class ActivityPub < ApplicationRecord # Le usuarie reportó el objeto state :reported # Le actore eliminó el objeto - state :deleted + state :removed # Recibir una acción de eliminación, eliminar el contenido de la # base de datos. Esto elimina el contenido para todos los sitios # porque estamos respetando lo que pidió le actore. - event :delete do - transitions to: :deleted + event :remove do + transitions to: :removed after do object.update(object: {}) From f517889992e9f72fb517ab9c79afed20c80e2769 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 15:45:15 -0300 Subject: [PATCH 447/814] fixup! fix: no es necesario vincular actores con objetos --- db/structure.sql | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index 723c9e99..ee99e791 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -523,7 +523,6 @@ CREATE TABLE public.activity_pub_objects ( id uuid DEFAULT gen_random_uuid() NOT NULL, created_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL, - actor_id uuid NOT NULL, type character varying NOT NULL, uri character varying NOT NULL, content jsonb DEFAULT '{}'::jsonb @@ -2005,13 +2004,6 @@ CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USIN CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname); --- --- Name: index_activity_pub_objects_on_actor_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_activity_pub_objects_on_actor_id ON public.activity_pub_objects USING btree (actor_id); - - -- -- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: - -- @@ -2479,6 +2471,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240219175839'), ('20240219204011'), ('20240219204224'), -('20240220161414'); +('20240220161414'), +('20240221184007'); From f8f0eb9d3c341467ec25b9b48d242d29c36b3401 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 16:42:02 -0300 Subject: [PATCH 448/814] fix: no buscar csrf --- app/controllers/api/v1/webhooks/concerns/webhook_concern.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb b/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb index b94c91f6..aef2dd83 100644 --- a/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb +++ b/app/controllers/api/v1/webhooks/concerns/webhook_concern.rb @@ -9,6 +9,8 @@ module Api extend ActiveSupport::Concern included do + skip_before_action :verify_authenticity_token + # Responde con forbidden si falla la validación del token rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer rescue_from ActiveRecord::RecordInvalid, with: :platforms_answer From a4133c60018772af78b5bb5813050b4d1fbf5b34 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 16:42:14 -0300 Subject: [PATCH 449/814] fix: asegurarse que todos los registros existan --- .../api/v1/webhooks/social_inbox_controller.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index fb7ede50..e6b80c4b 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -24,12 +24,10 @@ module Api ActivityPub.transaction do # Crea todos los registros necesarios y actualiza el estado - # - # 1. Actor - # 2. Instance - # 3. Object - # 4. ActivityPub - # 5. Activity + actor.present? + instance.present? + object.present? + activity_pub.present? activity.update_activity_pub_state! end rescue ActiveRecord::RecordInvalid => e From 3292d7ebe3fc8f82fe817bc9ccd5d0be0074a171 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 16:42:28 -0300 Subject: [PATCH 450/814] fix: vaciar el contenido antes de cambiar de estado --- app/models/activity_pub.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 42ed3f61..9445717f 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -38,8 +38,8 @@ class ActivityPub < ApplicationRecord event :remove do transitions to: :removed - after do - object.update(object: {}) + before do + object.update(content: {}) end end From a13f42c22f39f00835a6a5862e750a00a61be62f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 16:43:31 -0300 Subject: [PATCH 451/814] fixup! fixup! fix: no es necesario vincular actores con objetos --- app/models/activity_pub/object.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index ec759e3e..898d5375 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -5,7 +5,6 @@ class ActivityPub class Object < ApplicationRecord include ActivityPub::Concerns::JsonLdConcern - belongs_to :actor has_many :activity_pubs, as: :object end end From b562b006bc716200898524a027ac67efb24d9080 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:03:59 -0300 Subject: [PATCH 452/814] =?UTF-8?q?fix:=20versi=C3=B3n=20requerida=20por?= =?UTF-8?q?=20aasm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 8e955e8f..676b3673 100644 --- a/Gemfile +++ b/Gemfile @@ -80,7 +80,7 @@ gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' gem 'device_detector' -gem 'after_commit_everywhere' +gem 'after_commit_everywhere', '~> 1.0' gem 'aasm' # database diff --git a/Gemfile.lock b/Gemfile.lock index 50745140..7aac4c12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -608,7 +608,7 @@ PLATFORMS DEPENDENCIES aasm - after_commit_everywhere + after_commit_everywhere (~> 1.0) bcrypt (~> 3.1.7) bcrypt_pbkdf blazer From e53f31f359617b90cd77921c4e67f2521daed337 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:04:39 -0300 Subject: [PATCH 453/814] =?UTF-8?q?fixup!=20fix:=20deleted=20es=20un=20m?= =?UTF-8?q?=C3=A9todo=20reservado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 9445717f..902924b6 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -16,7 +16,7 @@ class ActivityPub < ApplicationRecord validates :site_id, presence: true validates :object_id, presence: true - validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported deleted] } + validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported removed] } aasm do # Todavía no hay una decisión sobre el objeto From fc7c2e5b7455b8e91d526a366ac0f57bce8c6c2e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:05:17 -0300 Subject: [PATCH 454/814] fix: undo auto-cancela la actividad --- app/models/activity_pub.rb | 4 +++- app/models/activity_pub/activity/undo.rb | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 902924b6..7e5bcabe 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -38,8 +38,10 @@ class ActivityPub < ApplicationRecord event :remove do transitions to: :removed + # @todo Es posible que haya un ActivityPub::FetchJob pendiente + # cuando estamos haciendo esto, que rellene el objeto después. before do - object.update(content: {}) + object.update(content: {}) unless object.content.empty? end end diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb index 41fb5e51..4b6a5a4c 100644 --- a/app/models/activity_pub/activity/undo.rb +++ b/app/models/activity_pub/activity/undo.rb @@ -7,6 +7,18 @@ class ActivityPub class Activity class Undo < ActivityPub::Activity + # Una actividad de deshacer tiene anidada como objeto la actividad + # a deshacer. Para respetar la voluntad de le actore remote, + # tendríamos que eliminar cualquier actividad pendiente sobre el + # objeto. + # + # Sin embargo, estas acciones nunca deberían llegar a nuestra + # Inbox. + # + # @see {https://github.com/hyphacoop/social.distributed.press/issues/43} + def update_activity_pub_state! + activity_pub.remove! + end end end end From dca266714d520cfb0fbd36460c7a898573fac33a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:08:11 -0300 Subject: [PATCH 455/814] fix: no completar el contenido si el objeto tiene actividades canceladas --- app/jobs/activity_pub/fetch_job.rb | 2 ++ app/models/activity_pub.rb | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index e5950c86..ec8c29f7 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -11,6 +11,8 @@ class ActivityPub class FetchJob < ApplicationJob def perform(site:, object:) ActivityPub::Object.transaction do + return if object.activity_pubs.where(aasm_state: 'removed').count.positive? + response = site.social_inbox.dereferencer.get(uri: object.uri) # @todo Fallar cuando la respuesta no funcione? diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 7e5bcabe..df8e5c5c 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -38,8 +38,6 @@ class ActivityPub < ApplicationRecord event :remove do transitions to: :removed - # @todo Es posible que haya un ActivityPub::FetchJob pendiente - # cuando estamos haciendo esto, que rellene el objeto después. before do object.update(content: {}) unless object.content.empty? end From 2ae2b8e9e87b254cc041bda6c060a7b93d171592 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:09:15 -0300 Subject: [PATCH 456/814] =?UTF-8?q?fix:=20las=20actividades=20de=20borrado?= =?UTF-8?q?=20eliminan=20el=20contenido=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/activity/delete.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 7080375e..351dd3cb 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -4,9 +4,9 @@ class ActivityPub class Activity class Delete < ActivityPub::Activity # Si estamos eliminando el objeto, tenemos que vaciar su contenido y - # cambiar el estado a borrado + # cambiar el estado a borrado. def update_activity_pub_state! - activity_pub.deleted! + activity_pub.remove! end end end From 7a936c114314ae4fbcc5827cc1aa019dad02bd2e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:22:31 -0300 Subject: [PATCH 457/814] =?UTF-8?q?fix:=20no=20actualizar=20si=20ya=20esta?= =?UTF-8?q?ba=20cacheado=20y=20el=20contenido=20exist=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index ec8c29f7..b6c45026 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -17,7 +17,7 @@ class ActivityPub # @todo Fallar cuando la respuesta no funcione? return unless response.ok? - return unless response.miss? + return if response.miss? && object.content.present? content = FastJsonparser.parse(response.body) From a7bd712a7c5725125ccbadcf0c075e71bd4f36fe Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 17:33:58 -0300 Subject: [PATCH 458/814] =?UTF-8?q?fix:=20tama=C3=B1o=20botones=20de=20mod?= =?UTF-8?q?eraci=C3=B3n=20de=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_btn_base.haml | 2 +- app/views/components/_comments_btn_box.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index ccc7ce35..7fa507ca 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,3 +1,3 @@ -# Componente Botón general Moderación -%button.btn.mx-2{ href: href, class: local_assigns[:class] }= text +%button.btn{ href: href, class: local_assigns[:class] }= text diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 7932068f..8b8d7268 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,6 +1,6 @@ -# Componente Botonera de Comentarios -- btn_class = 'btn-secondary' +- btn_class = 'btn-secondary py-1 px-2' = render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' = render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' = render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' From e4e604f56d866b6d06e5479328330edf4e640894 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 17:34:46 -0300 Subject: [PATCH 459/814] =?UTF-8?q?fix:=20separadores=20en=20actividades?= =?UTF-8?q?=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 8 ++++---- app/views/moderation_queue/_comments.haml | 4 +++- app/views/moderation_queue/_instances.haml | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 99059133..7c77545a 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,13 +1,13 @@ -# Componente Comentario -.flex.mx-4.my-5 +.flex.mx-4.my-4 .row.no-gutters .col-1 = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters - .col-4 + .col-3 %p= comment['published'].to_datetime.strftime(t('date.format')) - .col-8 + .col-9 %dl %dt.d-inline.mr-2= t('.source_profile') %dd.d-inline @@ -17,7 +17,7 @@ .row.no-gutters .col.p-0 %p - %span.mr-3= t('.reply_to') + %span= t('.reply_to') %span %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row.no-gutters diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index d51909a3..b67fc71f 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -2,7 +2,9 @@ = render 'components/comments_filters' - moderation_queue.each do |comment| + %hr = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - = render 'components/comments_btn_box', comment: comment \ No newline at end of file + .d-flex.justify-content-between + = render 'components/comments_btn_box', comment: comment \ No newline at end of file diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index c51ba74f..1accf60d 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -2,13 +2,14 @@ = render 'components/instances_filters' - @instances.each do |instance| + %hr = render 'moderation_queue/instance', instance: instance -# Botones moderación .d-flex.pb-4 = render 'components/instances_btn_box' - %hr +%hr %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') = render 'components/block_lists', blocklists: @blocklists From b489b713ac64df577ced3b937172c076be44c0f5 Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 17:52:53 -0300 Subject: [PATCH 460/814] fix: faltaba poner la hora de los comentarios --- app/views/moderation_queue/_comment.haml | 8 +++++--- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 7c77545a..80446587 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -5,9 +5,11 @@ = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters - .col-3 - %p= comment['published'].to_datetime.strftime(t('date.format')) - .col-9 + .col-5.col-sm-3.col-lg-4 + %p + %span= comment['published'].to_datetime.strftime(t('date.format')) + %span= comment['published'].to_datetime.strftime(t('time.format')) + .col-7.col-sm-9.col-lg-8 %dl %dt.d-inline.mr-2= t('.source_profile') %dd.d-inline diff --git a/config/locales/en.yml b/config/locales/en.yml index d6a15d4b..0d10b3db 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -48,6 +48,7 @@ en: time: am: am pm: pm + format: '%-I:%M %p' components: instances_filters: text_show: Show diff --git a/config/locales/es.yml b/config/locales/es.yml index 65df27bf..e277f76b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -48,6 +48,7 @@ es: time: am: am pm: pm + format: '%-H:%M' components: instances_filters: text_show: Ver From e62d6c6c1d5e03d3b4b6c9c47feefc5d2b186833 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:50:06 -0300 Subject: [PATCH 461/814] fix: asignar un tipo por defecto para el objeto --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index e6b80c4b..c71c4922 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -94,7 +94,10 @@ module Api # # @return [ActivityPub::Object] def object - @object ||= ActivityPub::Object.type_from(original_object).find_or_initialize_by(uri: object_uri).tap do |o| + @object ||= ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| + # XXX: Si el objeto es una actividad, esto siempre va a ser + # Generic + o.type ||= 'ActivityPub::Object::Generic' o.content = original_object if object_embedded? o.save! From 6b12e5141cd1f4004b53573d39d934f2c205d24b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 21 Feb 2024 17:54:18 -0300 Subject: [PATCH 462/814] feat: al deshacer una actividad resolvemos la pendiente --- app/models/activity_pub/activity/undo.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb index 4b6a5a4c..18fbff5e 100644 --- a/app/models/activity_pub/activity/undo.rb +++ b/app/models/activity_pub/activity/undo.rb @@ -17,7 +17,10 @@ class ActivityPub # # @see {https://github.com/hyphacoop/social.distributed.press/issues/43} def update_activity_pub_state! - activity_pub.remove! + ActivityPub.transaction do + ActivityPub::Activity.find_by(uri: content['object'])&.activity_pub&.remove! + activity_pub.remove! + end end end end From 1b8685b7ca978f4a1f45d40161d6080678eaa51a Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 18:01:10 -0300 Subject: [PATCH 463/814] fix: yaml roto --- app/views/moderation_queue/_comments.haml | 2 +- config/locales/en.yml | 102 +++++++++++----------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index b67fc71f..0e6ce334 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -6,5 +6,5 @@ = render 'comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación - .d-flex.justify-content-between + .d-flex.justify-content-center = render 'components/comments_btn_box', comment: comment \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 0d10b3db..1b4f2d86 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -50,57 +50,57 @@ en: pm: pm format: '%-I:%M %p' components: - instances_filters: - text_show: Show - text_checked: With the checked - instances_checked_submenu: - submenu_case: Check case by case - submenu_allow: Allow everything - submenu_reject: Reject - instances_show_submenu: - submenu_allow: Allow - submenu_reject: Reject - comments_filters: - text_show: Sho - text_checked: With the checked - comments_checked_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_reject: Reject - comments_show_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_report: Report - submenu_reject: Reject - profiles_filters: - text_show: Show - text_checked: With the checked - profiles_checked_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_reject: Reject - submenu_block: Block - profiles_show_submenu: - submenu_accept: Accept - submenu_block: Block - submenu_reject: Reject - block_lists: - title: Block lists - comments_btn_box: - text_pause: Pause - text_reject: Reject - text_accept: Accept - text_reply: Reply - text_report: Report - instances_btn_box: - text_check: Check case by case - text_allow: Allow everything - text_deny: Block instance - profiles_btn_box: - text_approve: Always approve - text_check: Always check - text_deny: Block - text_report: Report + instances_filters: + text_show: Show + text_checked: With selected + instances_checked_submenu: + submenu_case: Check case by case + submenu_allow: Allow everything + submenu_reject: Reject + instances_show_submenu: + submenu_allow: Allow + submenu_reject: Reject + comments_filters: + text_show: Show + text_checked: With selected + comments_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + comments_show_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_report: Report + submenu_reject: Reject + profiles_filters: + text_show: Show + text_checked: With selected + profiles_checked_submenu: + submenu_pause: Pause + submenu_accept: Accept + submenu_reject: Reject + submenu_block: Block + profiles_show_submenu: + submenu_accept: Accept + submenu_block: Block + submenu_reject: Reject + block_lists: + title: Block lists + comments_btn_box: + text_pause: Pause + text_reject: Reject + text_accept: Accept + text_reply: Reply + text_report: Report + instances_btn_box: + text_check: Check case by case + text_allow: Allow everything + text_deny: Block instance + profiles_btn_box: + text_approve: Always approve + text_check: Always check + text_deny: Block + text_report: Report moderation_queue: index: title: Moderation From df88f80b300bd401547fb8f2a76203ff1736c20f Mon Sep 17 00:00:00 2001 From: maki Date: Wed, 21 Feb 2024 18:08:54 -0300 Subject: [PATCH 464/814] fix: comentario en un details si tiene summary --- app/views/moderation_queue/_comment.haml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 80446587..a066f845 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -24,4 +24,9 @@ %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] .row.no-gutters .col.p-0 - %p= comment['content'].html_safe + - if comment['summary'] + - summary = comment['summary'] + = render 'layouts/details', summary: summary do + %p= comment['content'].html_safe + - else + %p= comment['content'].html_safe From 023b23915078fc461be95d90eb2c389311fd1126 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 11:46:39 -0300 Subject: [PATCH 465/814] fix: no hay botones verdes --- app/views/devise/shared/_links.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/devise/shared/_links.haml b/app/views/devise/shared/_links.haml index b4b89175..5d5c0b67 100644 --- a/app/views/devise/shared/_links.haml +++ b/app/views/devise/shared/_links.haml @@ -4,12 +4,12 @@ - if controller_name != 'sessions' = link_to t('.sign_in'), new_session_path(resource_name, params: locale), - class: 'btn btn-lg btn-block btn-success' + class: 'btn btn-lg btn-block btn-secondary' %br/ - if devise_mapping.registerable? && controller_name != 'registrations' = link_to t('.sign_up'), new_registration_path(resource_name, params: locale), - class: 'btn btn-lg btn-block btn-success' + class: 'btn btn-lg btn-block btn-secondary' %br/ - if devise_mapping.recoverable? From 476ab951bbd4f8d0f560ffdcb3ba709e1b5ba258 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 13:31:31 -0300 Subject: [PATCH 466/814] fixup! feat: rutas --- app/controllers/api/v1/webhooks/pull_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/pull_controller.rb b/app/controllers/api/v1/webhooks/pull_controller.rb index 5f0b703b..93256fc7 100644 --- a/app/controllers/api/v1/webhooks/pull_controller.rb +++ b/app/controllers/api/v1/webhooks/pull_controller.rb @@ -5,7 +5,7 @@ module Api module Webhooks # Recibe webhooks y lanza un PullJob class PullController < BaseController - include WebhookConcern + include Api::V1::Webhooks::Concerns::WebhookConcern # Trae los cambios a partir de un post de Webhooks: # (Gitlab, Github, Gitea, etc) From 1404d2006d4566508c9eaa242de0940c4af61836 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 13:32:30 -0300 Subject: [PATCH 467/814] fixup! feat: asociar rol con deploy nos permite acceder al token --- db/migrate/20240216170202_add_rol_to_deploys.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240216170202_add_rol_to_deploys.rb b/db/migrate/20240216170202_add_rol_to_deploys.rb index 5f629432..93c4553d 100644 --- a/db/migrate/20240216170202_add_rol_to_deploys.rb +++ b/db/migrate/20240216170202_add_rol_to_deploys.rb @@ -6,7 +6,7 @@ class AddRolToDeploys < ActiveRecord::Migration[6.1] add_column :deploys, :rol_id, :integer, index: true Deploy.find_each do |deploy| - rol_id = deploy.site.roles.find_by(rol: 'usuarie', temporal: false).id + rol_id = deploy.site.roles.find_by(rol: 'usuarie', temporal: false)&.id deploy.update_column(:rol_id, rol_id) if rol_id end From e62e26c87c17152979c244b771ce7a02dda7fcb9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 22 Feb 2024 15:36:42 -0300 Subject: [PATCH 468/814] fix: agregado checkbox general a comentarios --- app/views/moderation_queue/_comments.haml | 8 ++++++-- app/views/posts/_moderation_queue.haml | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 0e6ce334..41193ce1 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/comments_filters' +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/comments_filters' - moderation_queue.each do |comment| %hr diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 2be35f7f..2ec6a07d 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/comments_filters' +.row.no-gutters.pt-2 + .col-1 + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/comments_filters' - moderation_queue.each do |comment| = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] From af1afe8f50c6e288474e4e1137179e3a682e5a8e Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 22 Feb 2024 15:50:57 -0300 Subject: [PATCH 469/814] fix: agregado html_safe a summary en remote_profile --- app/views/moderation_queue/_remote_profile.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index e8635cc6..43474b80 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -12,7 +12,7 @@ %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') %dt= t('.profile_summary') - %dd= remote_profile['summary'] + %dd= remote_profile['summary'].html_safe = render 'moderation_queue/comments', moderation_queue: @moderation_queue @@ -21,4 +21,4 @@ %dd= remote_profile['name'] -# Botones de Moderación -= render 'components/comments_btn_box' += render 'components/profiles_btn_box' From 969d641a9194c86dfb68b6ac76398ecc46d7703e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 16:04:10 -0300 Subject: [PATCH 470/814] fix: touch --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index dd250e3d..7b93184f 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -578,7 +578,7 @@ class Site < ApplicationRecord if !gems_installed? || gemfile_updated? || gemfile_lock_updated? deploy_local.bundle touch - ::File.touch(gemfile_path) + FileUtils.touch(gemfile_path) end end From a7662d005cbe6e8236bad9eec1274897baaf3d91 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 17:28:19 -0300 Subject: [PATCH 471/814] =?UTF-8?q?fix:=20copiar=20estilo=20de=20bot=C3=B3?= =?UTF-8?q?n=20desde=20el=20modo=20oscuro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 7f62e658..b4a41f99 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -52,6 +52,25 @@ $sizes: ( --background: #{$black}; --color: #{$cyan}; } + + .btn-secondary { + background-color: $white; + color: $black; + border: none; + + &:hover { + color: $black; + background-color: $cyan; + } + + &:active { + background-color: $cyan; + } + + &:focus { + box-shadow: 0 0 0 0.2rem $cyan; + } + } } // TODO: Encontrar la forma de generar esto desde los locales de Rails From c415c79c5c91eaca7ebf615a46fc33df88efa8df Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 17:46:58 -0300 Subject: [PATCH 472/814] =?UTF-8?q?fix:=20por=20alguna=20raz=C3=B3n=20usam?= =?UTF-8?q?os=20REDIS=5FSERVER?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/social_inbox.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 45b8afd8..b0fde523 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -38,7 +38,7 @@ class SocialInbox public_key_url: public_key_url, private_key_pem: site.private_key_pem, logger: Rails.logger, - cache_store: :redis + cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER']) ) end From b0e07d5d023baeddd7d63ef21cc690b9c140c31e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 17:56:12 -0300 Subject: [PATCH 473/814] fix: require --- app/models/social_inbox.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index b0fde523..036aa02b 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -3,6 +3,7 @@ require 'distributed_press/v1/social/client' require 'distributed_press/v1/social/hook' require 'distributed_press/v1/social/dereferencer' +require 'httparty/cache/store/redis' # Gestiona la Social Inbox de un sitio class SocialInbox From 1022d57fd3e2ee56de3c56353d26ef6a5627346e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 17:58:51 -0300 Subject: [PATCH 474/814] fix: los scopes en las rutas son raros --- app/models/deploy_social_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index fc0e01d5..29670d3b 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -73,7 +73,7 @@ class DeploySocialDistributedPress < Deploy webhook_class = DistributedPress::V1::Social::Schemas::Webhook hook_client.class::EVENTS.each do |event| - event_url = :"v1_site_webhooks_social_inbox_#{event}_url" + event_url = :"v1_site_webhooks_#{event}_url" webhook = webhook_class.new.call({ From f50e2d430d4ca57eb743ec5fe226a064e8d34495 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 18:01:09 -0300 Subject: [PATCH 475/814] fix: dump --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7aac4c12..8ece3064 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -272,7 +272,7 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - httparty-cache (0.0.4) + httparty-cache (0.0.5) httparty (~> 0.18) i18n (1.14.1) concurrent-ruby (~> 1.0) From c23d931dd43e1ca248a71df495b39c6830a8a718 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 18:04:56 -0300 Subject: [PATCH 476/814] =?UTF-8?q?fix:=20usar=20el=20m=C3=A9todo=20correc?= =?UTF-8?q?to?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_social_distributed_press.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 29670d3b..7f761e46 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -90,7 +90,7 @@ class DeploySocialDistributedPress < Deploy response = hook_client.put(event: event, hook: webhook) - raise ArgumentError, response.parsed_body unless response.ok? + raise ArgumentError, response.body unless response.ok? rescue ArgumentError => e ExceptionNotifier.notify_exception(e, data: { site_id: site.name, usuarie_id: rol.usuarie_id }) end From c02a9762068284586f5c636dc98694613774b21e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 18:08:48 -0300 Subject: [PATCH 477/814] feat: poder acceder a la inbox --- app/models/social_inbox.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 036aa02b..21b0ca45 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -2,6 +2,7 @@ require 'distributed_press/v1/social/client' require 'distributed_press/v1/social/hook' +require 'distributed_press/v1/social/inbox' require 'distributed_press/v1/social/dereferencer' require 'httparty/cache/store/redis' @@ -43,6 +44,11 @@ class SocialInbox ) end + # @return [DistributedPress::V1::Social::Inbox] + def inbox + @inbox ||= DistributedPress::V1::Social::Inbox.new(client: client, actor: actor) + end + # @return [DistributedPress::V1::Social::Dereferencer] def dereferencer @dereferencer ||= DistributedPress::V1::Social::Dereferencer.new(client: client) From 9b401f8c120f9cf074779c8c2bea724d21fec854 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 18:13:53 -0300 Subject: [PATCH 478/814] fix: el hostname puede estar en varios lados --- app/models/social_inbox.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 21b0ca45..2f5e7eca 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -67,9 +67,12 @@ class SocialInbox end end + # El hostname puede estar en varios lados... + # + # @return [String] def hostname @hostname ||= - site.config.dig('activity_pub', 'hostname') || site.hostname + site.config.dig('activity_pub', 'hostname') || site.config['hostname'] || site.hostname end # Genera una URI dentro de este sitio From 3a382390b1e82f78df79b6910cfd6d4ecdee8c1c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 18:42:20 -0300 Subject: [PATCH 479/814] fix: la social inbox no confirma acciones! --- .../v1/webhooks/social_inbox_controller.rb | 24 ++++++++++++++----- app/models/activity_pub.rb | 8 +++---- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c71c4922..1ffc1596 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -38,21 +38,33 @@ module Api head :accepted end - # Cuando aprobamos una actividad, recibimos la confirmación y - # cambiamos el estado. + # Cuando la Social Inbox acepta una actividad, la recibimos + # igual y la guardamos por si cambiamos de idea. + # + # @todo DRY def onapproved ActivityPub.transaction do - activity_pub.approve! if activity_pub.waiting? + actor.present? + instance.present? + object.present? + activity.present? + activity_pub.approve! end head :accepted end - # Cuando rechazamos una actividad, recibimos la confirmación y - # cambiamos el estado + # Cuando la Social Inbox rechaza una actividad, la recibimos + # igual y la guardamos por si cambiamos de idea. + # + # @todo DRY def onrejected ActivityPub.transaction do - activity_pub.reject! if activity_pub.waiting? + actor.present? + instance.present? + object.present? + activity.present? + activity_pub.reject! end head :accepted diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index df8e5c5c..07754b87 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -21,8 +21,6 @@ class ActivityPub < ApplicationRecord aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true - # Estamos esperando respuesta desde la Social Inbox - state :waiting # Le usuarie aprobó el objeto state :approved # Le usuarie rechazó el objeto @@ -46,17 +44,17 @@ class ActivityPub < ApplicationRecord # Si un objeto previamente aprobado fue actualizado, volvemos a # pausarlo. event :pause do - transitions from: %i[waiting approved rejected], to: :paused + transitions from: %i[approved rejected], to: :paused end # La actividad se aprueba event :approve do - transitions from: :waiting, to: :approved + transitions from: %i[paused rejected], to: :approved end # La actividad fue rechazada event :reject do - transitions from: :waiting, to: :rejected + transitions from: %i[paused approved], to: :rejected end end end From fd1d2382fa481ec45888bb036bc8aac27e3d50b4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Feb 2024 18:42:36 -0300 Subject: [PATCH 480/814] feat: luego de rechazar podemos reportar --- app/models/activity_pub.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 07754b87..217c15a1 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -56,5 +56,10 @@ class ActivityPub < ApplicationRecord event :reject do transitions from: %i[paused approved], to: :rejected end + + # Solo podemos reportarla luego de rechazarla + event :report do + transitions from: :rejected, to: :reported + end end end From 836e5d5935e675d46adf507353a4a6de4332f4bf Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:26:33 -0300 Subject: [PATCH 481/814] fix: las actividades pueden existir previamente --- .../api/v1/webhooks/social_inbox_controller.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 1ffc1596..8b8ba35f 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -132,12 +132,14 @@ module Api # # @return [ActivityPub::Activity] def activity - @activity ||= ActivityPub::Activity.type_from(original_activity).new(uri: original_activity[:id], - activity_pub: activity_pub).tap do |a| - a.content = original_activity.dup - a.content[:object] = object.uri - a.save! - end + @activity ||= + ActivityPub::Activity + .type_from(original_activity) + .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub).tap do |a| + a.content = original_activity.dup + a.content[:object] = object.uri + a.save! + end end # Actor, si no hay instancia, la crea en el momento From a51cb4dbddb0a984e2546edc807c4a7e897321e2 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:36:03 -0300 Subject: [PATCH 482/814] =?UTF-8?q?fix:=20copiar=20el=20contexto=20desde?= =?UTF-8?q?=20la=20acci=C3=B3n=20al=20objeto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 8b8ba35f..02c91813 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -171,7 +171,9 @@ module Api # @return [Hash,String] def original_object - @original_object ||= original_activity[:object].dup + @original_object ||= original_activity[:object].dup.tap do |o| + o[:@context] = original_activity[:@context].dup + end end end end From a4062c5f545a7f2bac4c5b909d83eaca037ea3ec Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:52:01 -0300 Subject: [PATCH 483/814] feat: eliminar un objeto elimina todas las actividades pendientes --- app/models/activity_pub/activity/delete.rb | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 351dd3cb..9e7daa16 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -3,10 +3,19 @@ class ActivityPub class Activity class Delete < ActivityPub::Activity - # Si estamos eliminando el objeto, tenemos que vaciar su contenido y - # cambiar el estado a borrado. + # Los Delete se refieren a objetos. Al eliminar un objeto, + # cancelamos todas las actividades que tienen relacionadas. + # + # XXX: La actividad tiene una firma, pero la implementación no + # está recomendada + # + # @see {https://docs.joinmastodon.org/spec/security/#ld} def update_activity_pub_state! - activity_pub.remove! + ActivityPub.transaction do + ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object']))&.activity_pubs&.find_each(&:remove!) + + activity_pub.remove! + end end end end From 2c8dbc885c38d25037df28b1a99a1ce0991ff5fd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:53:56 -0300 Subject: [PATCH 484/814] fix: evitar advertencias --- app/controllers/application_controller.rb | 2 +- app/models/concerns/tienda.rb | 2 +- app/models/site.rb | 2 +- app/models/site/api.rb | 2 +- app/models/site/social_distributed_press.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2746ab10..3201b909 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,7 +3,7 @@ # Forma de ingreso a Sutty class ApplicationController < ActionController::Base include ExceptionHandler - include Pundit + include Pundit::Authorization protect_from_forgery with: :null_session, prepend: true diff --git a/app/models/concerns/tienda.rb b/app/models/concerns/tienda.rb index cd09358e..86174c9a 100644 --- a/app/models/concerns/tienda.rb +++ b/app/models/concerns/tienda.rb @@ -5,7 +5,7 @@ module Tienda extend ActiveSupport::Concern included do - encrypts :tienda_api_key + has_encrypted :tienda_api_key def tienda? tienda_api_key.present? && tienda_url.present? diff --git a/app/models/site.rb b/app/models/site.rb index dd250e3d..a9cb3652 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -17,7 +17,7 @@ class Site < ApplicationRecord # tiene acceso pero los datos se guardan cifrados en el sitio. Esto # protege información privada en repositorios públicos, pero no la # protege de acceso al panel de Sutty! - encrypts :private_key + has_encrypted :private_key validates :name, uniqueness: true, hostname: { allow_root_label: true diff --git a/app/models/site/api.rb b/app/models/site/api.rb index 73f8e710..6c6f0ece 100644 --- a/app/models/site/api.rb +++ b/app/models/site/api.rb @@ -5,7 +5,7 @@ class Site extend ActiveSupport::Concern included do - encrypts :api_key + has_encrypted :api_key before_save :add_api_key_if_missing! # Genera mensajes secretos que podemos usar para la API de cada diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index c3abe06e..7ebdcb36 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -8,7 +8,7 @@ class Site extend ActiveSupport::Concern included do - encrypts :private_key_pem + has_encrypted :private_key_pem has_many :activity_pubs From e3aabf4b91e485ddfa90293fc71d1e41145fea7f Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:54:31 -0300 Subject: [PATCH 485/814] feat: poder obtener el id desde un objeto --- app/models/activity_pub.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 217c15a1..e99fa1f4 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -18,6 +18,16 @@ class ActivityPub < ApplicationRecord validates :object_id, presence: true validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported removed] } + # Encuentra la URI de un objeto + # + # @return [String, nil] + def self.uri_from_object(object) + case object + when String then object + when Hash then object['id'] + end + end + aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true From 77137f311cba52a54b0a028f18d7f009f011c9cb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 23 Feb 2024 12:56:39 -0300 Subject: [PATCH 486/814] docs: recordar que tenemos que validar mejor --- app/models/activity_pub/activity/delete.rb | 2 ++ app/models/activity_pub/activity/undo.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 9e7daa16..f6ff6536 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -9,6 +9,8 @@ class ActivityPub # XXX: La actividad tiene una firma, pero la implementación no # está recomendada # + # @todo Validar que le Actor corresponda con los objetos. Esto ya + # lo haría la Social Inbox por nosotres. # @see {https://docs.joinmastodon.org/spec/security/#ld} def update_activity_pub_state! ActivityPub.transaction do diff --git a/app/models/activity_pub/activity/undo.rb b/app/models/activity_pub/activity/undo.rb index 18fbff5e..ae78a0d3 100644 --- a/app/models/activity_pub/activity/undo.rb +++ b/app/models/activity_pub/activity/undo.rb @@ -15,6 +15,8 @@ class ActivityPub # Sin embargo, estas acciones nunca deberían llegar a nuestra # Inbox. # + # @todo Validar que le Actor corresponda con los objetos. Esto ya + # lo haría la Social Inbox por nosotres. # @see {https://github.com/hyphacoop/social.distributed.press/issues/43} def update_activity_pub_state! ActivityPub.transaction do From 2f19aae793b91447c3cc633456b19d8d0a35fa99 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 23 Feb 2024 13:52:31 -0300 Subject: [PATCH 487/814] feat: agregado enlace a listas de bloquedo y quitado estilo en css --- app/assets/stylesheets/application.scss | 5 ----- app/views/components/_block_list.haml | 6 ++++-- db/seeds/blocklists.yml | 2 ++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 240e61a5..a24af4c8 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -582,8 +582,3 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } } - - -hr { - border-bottom: 1px solid #dee2e6; -} \ No newline at end of file diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index c2af3262..36ca8144 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -2,5 +2,7 @@ .card.mt-3.mb-3 .card-body .d-flex.flex-row - = render 'components/checkbox', id: blocklist["id"] do - %span.h4= blocklist["title"] + = render 'components/checkbox', id: blocklist['id'] do + -#%span.h4= blocklist["title"] + %h4 + %a{ href: blocklist['link'] }= blocklist['title'] diff --git a/db/seeds/blocklists.yml b/db/seeds/blocklists.yml index d9f9dd6f..54dfe6c9 100644 --- a/db/seeds/blocklists.yml +++ b/db/seeds/blocklists.yml @@ -1,5 +1,7 @@ --- - id: gardenfence title: Gardenfence + link: 'https://gardenfence.github.io/' - id: lista title: Lista + link: '#' From e632bd249b16b6e888f65a9e90c517dbbe424a39 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 23 Feb 2024 14:47:24 -0300 Subject: [PATCH 488/814] fix: corregido compo comentario en cuenta de origen y fecha --- app/views/moderation_queue/_comment.haml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index a066f845..4836f03d 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -5,16 +5,10 @@ = render 'components/checkbox', id: comment['id'] .col-11 .row.no-gutters - .col-5.col-sm-3.col-lg-4 - %p - %span= comment['published'].to_datetime.strftime(t('date.format')) - %span= comment['published'].to_datetime.strftime(t('time.format')) - .col-7.col-sm-9.col-lg-8 - %dl - %dt.d-inline.mr-2= t('.source_profile') - %dd.d-inline - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - + .col.col-lg-10.d-inline-flex.justify-content-between + %h4 + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + = render 'layouts/time', time: comment['published'] - if comment['inReplyTo'] .row.no-gutters .col.p-0 @@ -30,3 +24,4 @@ %p= comment['content'].html_safe - else %p= comment['content'].html_safe + From ea6d794b572b48d3198275967927b74efbccb2be Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 23 Feb 2024 14:57:07 -0300 Subject: [PATCH 489/814] fix: corregido checkbox general en comentarios, cuentas e instancias --- app/views/moderation_queue/_accounts.haml | 8 ++++++-- app/views/moderation_queue/_comments.haml | 2 +- app/views/moderation_queue/_instances.haml | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 9a6738bd..5fa8638c 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/profiles_filters' +.row.no-gutters.pt-2 + .col-1.d-flex.align-items-center + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/profiles_filters' - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| %hr diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 41193ce1..6fa8c0f4 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,5 +1,5 @@ .row.no-gutters.pt-2 - .col-1 + .col-1.d-flex.align-items-center = render 'components/checkbox', id: moderation_queue.first['id'] .col-11 -# Filtros diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1accf60d..cf67a473 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,5 +1,9 @@ --# Filtros -= render 'components/instances_filters' +.row.no-gutters.pt-2 + .col-1.d-flex.align-items-center + = render 'components/checkbox', id: moderation_queue.first['id'] + .col-11 + -# Filtros + = render 'components/instances_filters' - @instances.each do |instance| %hr From f83642797922b32f316398e276533095180b2e35 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 11:09:57 -0300 Subject: [PATCH 490/814] =?UTF-8?q?feat:=20obtener=20informaci=C3=B3n=20so?= =?UTF-8?q?bre=20la=20instancia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/webhooks/social_inbox_controller.rb | 3 +++ app/jobs/activity_pub/instance_fetch_job.rb | 22 +++++++++++++++++++ app/models/social_inbox.rb | 8 +++---- 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 app/jobs/activity_pub/instance_fetch_job.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 02c91813..97ca58b5 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -150,6 +150,9 @@ module Api next if a.instance a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + + ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + a.save! end end diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb new file mode 100644 index 00000000..a5c07162 --- /dev/null +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class ActivityPub + # Obtiene o actualiza los datos de una instancia. + class InstanceFetchJob < ApplicationJob + def perform(site:, instance:) + %w[/api/v2/instance /api/v1/instance].each do |api| + uri = SocialInbox.generate_uri(instance.hostname) do |u| + u.path = api + end + + response = site.social_inbox.dereferencer.get(uri: uri) + + next unless response.ok? + + instance.update(content: response.parsed_response) + + break + end + end + end +end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 2f5e7eca..03612779 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -28,7 +28,7 @@ class SocialInbox end def actor_id - @actor_id ||= generate_uri do |uri| + @actor_id ||= SocialInbox.generate_uri(hostname) do |uri| uri.path = '/about.jsonld' end end @@ -61,7 +61,7 @@ class SocialInbox # @return [String] def public_key_url - @public_key_url ||= generate_uri do |uri| + @public_key_url ||= SocialInbox.generate_uri(hostname) do |uri| uri.path = '/about.jsonld' uri.fragment = 'main-key' end @@ -78,7 +78,7 @@ class SocialInbox # Genera una URI dentro de este sitio # # @return [String] - def generate_uri(&block) - @public_key_url ||= URI("https://#{hostname}").tap(&block).to_s + def self.generate_uri(hostname, &block) + URI("https://#{hostname}").tap(&block).to_s end end From 9e54d6311c0fbd9a7dfc34ab5b37460cf97b1021 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 12:46:55 -0300 Subject: [PATCH 491/814] =?UTF-8?q?feat:=20obtener=20informaci=C3=B3n=20de?= =?UTF-8?q?=20le=20actore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/webhooks/social_inbox_controller.rb | 2 ++ app/jobs/activity_pub/actor_fetch_job.rb | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 app/jobs/activity_pub/actor_fetch_job.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 97ca58b5..a5951716 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -154,6 +154,8 @@ module Api ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) a.save! + + ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) end end diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb new file mode 100644 index 00000000..1c6f1735 --- /dev/null +++ b/app/jobs/activity_pub/actor_fetch_job.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Obtiene o actualiza el contenido de un objeto, usando las credenciales +# del sitio. +# +# XXX: Esto usa las credenciales del sitio para volver el objeto +# disponible para todo el CMS. Asumimos que el objeto devuelto es el +# mismo para todo el mundo y las credenciales solo son para +# autenticación. +class ActivityPub + class ActorFetchJob < ApplicationJob + def perform(site:, actor:) + ActivityPub::Actor.transaction do + response = site.social_inbox.dereferencer.get(uri: actor.uri) + + # @todo Fallar cuando la respuesta no funcione? + return unless response.ok? + return if response.miss? && actor.content.present? + + actor.update(content: FastJsonparser.parse(response.body)) + end + end + end +end From a76c652f98e217a451a8b489586c3dc7500b8ef0 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 12:47:11 -0300 Subject: [PATCH 492/814] =?UTF-8?q?fix:=20permitir=20guardar=20le=20actore?= =?UTF-8?q?=20si=20la=20instancia=20ya=20exist=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/webhooks/social_inbox_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index a5951716..a1ff9677 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -147,11 +147,11 @@ module Api # @return [Actor] def actor @actor ||= ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| - next if a.instance + unless a.instance + a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) - a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) - - ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + end a.save! From 380d484c00aa2b53d171c0c85bc21160482679d0 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 24 Feb 2024 13:04:52 -0300 Subject: [PATCH 493/814] feat: poder encontrar instancias a partir de actividades --- app/controllers/moderation_queue_controller.rb | 6 ++++++ app/models/activity_pub/activity.rb | 1 + app/models/activity_pub/actor.rb | 1 + app/models/activity_pub/instance.rb | 4 ++++ app/models/activity_pub/object.rb | 7 +++++++ app/views/moderation_queue/_instance.haml | 18 +++++++----------- app/views/moderation_queue/_instances.haml | 2 +- .../20240223170317_add_actor_to_activities.rb | 18 ++++++++++++++++++ db/structure.sql | 6 ++++-- 9 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 db/migrate/20240223170317_add_actor_to_activities.rb diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index eec0c70f..5f94e1f7 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -5,6 +5,12 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index dummy_data + + # @todo cambiar el estado por query + @activity_pubs = site.activity_pubs.where(aasm_state: 'paused') + @activities = ActivityPub::Activity.where(activity_pub_id: @activity_pubs.pluck(:id)) + @actors = ActivityPub::Actor.where(id: @activities.unscoped.distinct.pluck(:actor_id)) + @instances = ActivityPub::Instance.where(id: @actors.distinct.pluck(:instance_id)) end # Perfil remoto de usuarie diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index 5ee3d2d1..a220b831 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -16,6 +16,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern belongs_to :activity_pub + belongs_to :actor has_one :object, through: :activity_pub validates :activity_pub_id, presence: true diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index e79a596a..7a858a7e 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -11,5 +11,6 @@ class ActivityPub belongs_to :instance has_many :activity_pubs, as: :object + has_many :activities end end diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index b13b8676..17bf183d 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -19,5 +19,9 @@ class ActivityPub state :allowed state :blocked end + + def uri + @uri ||= "https://#{hostname}/" + end end end diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 898d5375..c196160f 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -6,5 +6,12 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern has_many :activity_pubs, as: :object + + # Encontrar le Actor por su relación con el objeto + # + # @return [ActivityPub::Actor,nil] + def actor + ActivityPub::Actor.find_by(uri: content['actor']) + end end end diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index cff8a957..958a0199 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,16 +1,12 @@ -- host = instance['domain'] -- host ||= instance['uri'] -- hosthttps = "https://#{host}" - .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: host + = render 'components/checkbox', id: instance.hostname .col-11 - %h4 - %a{ href: hosthttps }= instance['title'] - %p= instance['description'].html_safe - %p + %h4 + %a{ href: instance.uri }= instance.content['title'] + %p= instance.content['description'].html_safe + %p %span= t('.users') %span - = instance.dig('usage', 'users', 'active_month') - = instance.dig('stats', 'user_count') + = instance.content.dig('usage', 'users', 'active_month') + = instance.content.dig('stats', 'user_count') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1accf60d..e836d7e0 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -7,7 +7,7 @@ -# Botones moderación .d-flex.pb-4 - = render 'components/instances_btn_box' + = render 'components/instances_btn_box', instance: instance %hr %h3.mt-5= t('moderation_queue.instances.title') diff --git a/db/migrate/20240223170317_add_actor_to_activities.rb b/db/migrate/20240223170317_add_actor_to_activities.rb new file mode 100644 index 00000000..a546cd94 --- /dev/null +++ b/db/migrate/20240223170317_add_actor_to_activities.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Relaciona Actor con Activity +class AddActorToActivities < ActiveRecord::Migration[6.1] + def up + add_column :activity_pub_activities, :actor_id, :uuid, index: true + + ActivityPub::Activity.find_each do |activity| + actor = ActivityPub::Actor.find_by(uri: activity.content['actor']) + + activity.update(actor: actor) if actor.present? + end + end + + def down + remove_column :activity_pub_activities, :actor_id, :uuid, index: true + end +end diff --git a/db/structure.sql b/db/structure.sql index ee99e791..97e9ba36 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -484,7 +484,8 @@ CREATE TABLE public.activity_pub_activities ( activity_pub_id uuid NOT NULL, type character varying NOT NULL, uri character varying NOT NULL, - content jsonb DEFAULT '{}'::jsonb + content jsonb DEFAULT '{}'::jsonb, + actor_id uuid ); @@ -2472,6 +2473,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240219204011'), ('20240219204224'), ('20240220161414'), -('20240221184007'); +('20240221184007'), +('20240223170317'); From 64cef8a13e5532ad670378dd8dffd04ef9135dbf Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 10:39:00 -0300 Subject: [PATCH 494/814] feat: relacionar actividades con instancias de origen --- app/controllers/moderation_queue_controller.rb | 6 ++---- app/models/activity_pub.rb | 1 + ...226133022_add_instance_id_to_activity_pubs.rb | 16 ++++++++++++++++ db/structure.sql | 6 ++++-- 4 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 5f94e1f7..8920c717 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -7,10 +7,8 @@ class ModerationQueueController < ApplicationController dummy_data # @todo cambiar el estado por query - @activity_pubs = site.activity_pubs.where(aasm_state: 'paused') - @activities = ActivityPub::Activity.where(activity_pub_id: @activity_pubs.pluck(:id)) - @actors = ActivityPub::Actor.where(id: @activities.unscoped.distinct.pluck(:actor_id)) - @instances = ActivityPub::Instance.where(id: @actors.distinct.pluck(:instance_id)) + @activity_pubs = site.activity_pubs + @instances = ActivityPub::Instance.where(id: @activity_pubs.distinct.pluck(:instance_id)) end # Perfil remoto de usuarie diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index e99fa1f4..1afeee96 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -10,6 +10,7 @@ class ActivityPub < ApplicationRecord include AASM + belongs_to :instance belongs_to :site belongs_to :object, polymorphic: true has_many :activities diff --git a/db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb b/db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb new file mode 100644 index 00000000..710aacef --- /dev/null +++ b/db/migrate/20240226133022_add_instance_id_to_activity_pubs.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Relaciona instancias con sus actividades +class AddInstanceIdToActivityPubs < ActiveRecord::Migration[6.1] + def up + add_column :activity_pubs, :instance_id, :uuid, index: true + + ActivityPub.all.find_each do |activity_pub| + activity_pub.update(instance: activity_pub&.object&.actor&.instance) + end + end + + def down + remove_column :activity_pubs, :instance_id, :uuid, index: true + end +end diff --git a/db/structure.sql b/db/structure.sql index 97e9ba36..4fb11e5a 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -541,7 +541,8 @@ CREATE TABLE public.activity_pubs ( site_id bigint NOT NULL, object_id uuid NOT NULL, object_type character varying NOT NULL, - aasm_state character varying NOT NULL + aasm_state character varying NOT NULL, + instance_id uuid ); @@ -2474,6 +2475,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240219204224'), ('20240220161414'), ('20240221184007'), -('20240223170317'); +('20240223170317'), +('20240226133022'); From dc11e6efc76a72a6d934f8eee13718b206531206 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 12:27:56 -0300 Subject: [PATCH 495/814] =?UTF-8?q?feat:=20cada=20sitio=20tiene=20un=20est?= =?UTF-8?q?ado=20de=20moderaci=C3=B3n=20para=20la=20instancia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/webhooks/social_inbox_controller.rb | 5 +- .../instance_moderations_controller.rb | 35 +++++++++ .../moderation_queue_controller.rb | 2 +- app/models/activity_pub/instance.rb | 1 + app/models/instance_moderation.rb | 27 +++++++ app/models/site/social_distributed_press.rb | 1 + app/policies/instance_moderation_policy.rb | 16 +++++ app/views/components/_btn_base.haml | 6 +- app/views/components/_instances_btn_box.haml | 6 +- app/views/moderation_queue/_instances.haml | 6 +- app/views/moderation_queue/index.haml | 2 +- config/routes.rb | 6 ++ ...240226134335_create_instance_moderation.rb | 26 +++++++ db/structure.sql | 72 ++++++++++++++++++- 14 files changed, 200 insertions(+), 11 deletions(-) create mode 100644 app/controllers/instance_moderations_controller.rb create mode 100644 app/models/instance_moderation.rb create mode 100644 app/policies/instance_moderation_policy.rb create mode 100644 db/migrate/20240226134335_create_instance_moderation.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index a1ff9677..12545915 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -142,7 +142,8 @@ module Api end end - # Actor, si no hay instancia, la crea en el momento + # Actor, si no hay instancia, la crea en el momento, junto con + # su estado de moderación. # # @return [Actor] def actor @@ -150,6 +151,8 @@ module Api unless a.instance a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + site.instance_moderations.find_or_create_by(instance: a.instance) + ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) end diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb new file mode 100644 index 00000000..55f3c51b --- /dev/null +++ b/app/controllers/instance_moderations_controller.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# Actualiza la relación entre un sitio y una instancia +class InstanceModerationsController < ApplicationController + before_action :authorize_policy + + def pause + instance_moderation.pause! + + redirect_to site_moderation_queue_path + end + + def allow + instance_moderation.allow! + + redirect_to site_moderation_queue_path + end + + def block + instance_moderation.block! + + redirect_to site_moderation_queue_path + end + + private + + # @return [InstanceModeration] + def instance_moderation + @instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id]) + end + + def authorize_policy + authorize instance_moderation + end +end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 8920c717..d2123234 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -8,7 +8,7 @@ class ModerationQueueController < ApplicationController # @todo cambiar el estado por query @activity_pubs = site.activity_pubs - @instances = ActivityPub::Instance.where(id: @activity_pubs.distinct.pluck(:instance_id)) + @instance_moderations = site.instance_moderations end # Perfil remoto de usuarie diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 17bf183d..627ccb10 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -13,6 +13,7 @@ class ActivityPub has_many :activity_pubs has_many :actors + has_many :instance_moderations aasm do state :paused, initial: true diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb new file mode 100644 index 00000000..3c092958 --- /dev/null +++ b/app/models/instance_moderation.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# Mantiene el registro de relaciones entre sitios e instancias +class InstanceModeration < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :instance, class_name: 'ActivityPub::Instance' + + aasm do + state :paused, initial: true + state :allowed + state :blocked + + event :pause do + transitions from: %i[allowed blocked], to: :paused + end + + event :allow do + transitions from: %i[paused blocked], to: :allowed + end + + event :block do + transitions from: %i[paused allowed], to: :blocked + end + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 7ebdcb36..73b284bf 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -11,6 +11,7 @@ class Site has_encrypted :private_key_pem has_many :activity_pubs + has_many :instance_moderations before_save :generate_private_key_pem!, unless: :private_key_pem? diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb new file mode 100644 index 00000000..6b3157e8 --- /dev/null +++ b/app/policies/instance_moderation_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Solo les usuaries pueden moderar instancias +InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do + def pause? + instance_moderation.site.usuarie? usuarie + end + + def allow? + pause? + end + + def block? + pause? + end +end diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 7fa507ca..677b88f1 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,3 +1,7 @@ -# Componente Botón general Moderación -%button.btn{ href: href, class: local_assigns[:class] }= text +- local_assigns[:method] ||= 'patch' +- local_assigns[:class] = "btn #{local_assigns[:class]}" + +-# @todo path es obligatorio += button_to text, local_assigns[:path], **local_assigns diff --git a/app/views/components/_instances_btn_box.haml b/app/views/components/_instances_btn_box.haml index 854262c0..74cad4a4 100644 --- a/app/views/components/_instances_btn_box.haml +++ b/app/views/components/_instances_btn_box.haml @@ -1,6 +1,6 @@ -# Componente botonera de moderación de Instancias - btn_class = 'btn btn-secondary' -= render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_allow'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' \ No newline at end of file += render 'components/btn_base', path: site_instance_moderation_pause_path(instance_moderation_id: instance_moderation), text: t('.text_check'), class: btn_class, disabled: !instance_moderation.may_pause? += render 'components/btn_base', path: site_instance_moderation_allow_path(instance_moderation_id: instance_moderation), text: t('.text_allow'), class: btn_class, disabled: !instance_moderation.may_allow? += render 'components/btn_base', path: site_instance_moderation_block_path(instance_moderation_id: instance_moderation), text: t('.text_deny'), class: btn_class, disabled: !instance_moderation.may_block? diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index e836d7e0..318cddef 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,13 +1,13 @@ -# Filtros = render 'components/instances_filters' -- @instances.each do |instance| +- instance_moderations.each do |instance_moderation| %hr - = render 'moderation_queue/instance', instance: instance + = render 'moderation_queue/instance', instance: instance_moderation.instance -# Botones moderación .d-flex.pb-4 - = render 'components/instances_btn_box', instance: instance + = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation %hr %h3.mt-5= t('moderation_queue.instances.title') diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index ab98ee30..0c937758 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -5,7 +5,7 @@ .col - summary = t('.instances') = render 'layouts/details', summary: summary do - = render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue + = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do diff --git a/config/routes.rb b/config/routes.rb index ddc29994..b6250902 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -62,6 +62,12 @@ Rails.application.routes.draw do get 'remote_profile', to: 'moderation_queue#remote_profile' get 'instances', to: 'moderation_queue#instances' + resources :instance_moderations, only: [] do + patch :pause, to: 'instance_moderations#pause' + patch :allow, to: 'instance_moderations#allow' + patch :block, to: 'instance_moderations#block' + end + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do diff --git a/db/migrate/20240226134335_create_instance_moderation.rb b/db/migrate/20240226134335_create_instance_moderation.rb new file mode 100644 index 00000000..8b08e14e --- /dev/null +++ b/db/migrate/20240226134335_create_instance_moderation.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Como la instancia es única para todo el panel, necesitamos llevar +# registro de su relación con cada sitio por separado. +class CreateInstanceModeration < ActiveRecord::Migration[6.1] + def up + create_table :instance_moderations do |t| + t.timestamps + + t.belongs_to :site + t.uuid :instance_id, index: true + + t.string :aasm_state, null: false, default: 'paused' + + t.index %i[site_id instance_id], unique: true + end + + ActivityPub.all.find_each do |activity_pub| + InstanceModeration.find_or_create_by(site: activity_pub.site, instance: activity_pub.instance) + end + end + + def down + drop_table :instance_moderations + end +end diff --git a/db/structure.sql b/db/structure.sql index 4fb11e5a..c3896060 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -950,6 +950,39 @@ CREATE TABLE public.indexed_posts ( ); +-- +-- Name: instance_moderations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.instance_moderations ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + instance_id uuid, + aasm_state character varying DEFAULT 'paused'::character varying NOT NULL +); + + +-- +-- Name: instance_moderations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.instance_moderations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: instance_moderations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.instance_moderations_id_seq OWNED BY public.instance_moderations.id; + + -- -- Name: licencias; Type: TABLE; Schema: public; Owner: - -- @@ -1514,6 +1547,13 @@ ALTER TABLE ONLY public.designs ALTER COLUMN id SET DEFAULT nextval('public.desi ALTER TABLE ONLY public.distributed_press_publishers ALTER COLUMN id SET DEFAULT nextval('public.distributed_press_publishers_id_seq'::regclass); +-- +-- Name: instance_moderations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.instance_moderations ALTER COLUMN id SET DEFAULT nextval('public.instance_moderations_id_seq'::regclass); + + -- -- Name: licencias id; Type: DEFAULT; Schema: public; Owner: - -- @@ -1774,6 +1814,14 @@ ALTER TABLE ONLY public.indexed_posts ADD CONSTRAINT indexed_posts_pkey PRIMARY KEY (id); +-- +-- Name: instance_moderations instance_moderations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.instance_moderations + ADD CONSTRAINT instance_moderations_pkey PRIMARY KEY (id); + + -- -- Name: licencias licencias_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2139,6 +2187,27 @@ CREATE INDEX index_indexed_posts_on_locale ON public.indexed_posts USING btree ( CREATE INDEX index_indexed_posts_on_site_id ON public.indexed_posts USING btree (site_id); +-- +-- Name: index_instance_moderations_on_instance_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_instance_moderations_on_instance_id ON public.instance_moderations USING btree (instance_id); + + +-- +-- Name: index_instance_moderations_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_instance_moderations_on_site_id ON public.instance_moderations USING btree (site_id); + + +-- +-- Name: index_instance_moderations_on_site_id_and_instance_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_instance_moderations_on_site_id_and_instance_id ON public.instance_moderations USING btree (site_id, instance_id); + + -- -- Name: index_licencias_on_name; Type: INDEX; Schema: public; Owner: - -- @@ -2476,6 +2545,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240220161414'), ('20240221184007'), ('20240223170317'), -('20240226133022'); +('20240226133022'), +('20240226134335'); From ffdcb5fae8b37187963182323076ddf048e149c9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:12:56 -0300 Subject: [PATCH 496/814] =?UTF-8?q?feat:=20poder=20cambiar=20el=20estado?= =?UTF-8?q?=20de=20moderaci=C3=B3n=20a=20instancias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/instance.rb | 6 ++++++ app/models/instance_moderation.rb | 30 ++++++++++++++++++++++++++--- app/models/social_inbox.rb | 12 ++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 627ccb10..42cd2695 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -15,12 +15,18 @@ class ActivityPub has_many :actors has_many :instance_moderations + # XXX: Mantenemos esto por si queremos bloquear una instancia a + # nivel general aasm do state :paused, initial: true state :allowed state :blocked end + def list_name + "@*@#{hostname}" + end + def uri @uri ||= "https://#{hostname}/" end diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 3c092958..17b38fb7 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -13,15 +13,39 @@ class InstanceModeration < ApplicationRecord state :blocked event :pause do - transitions from: %i[allowed blocked], to: :paused + transitions from: %i[allowed blocked], to: :paused, guard: :pause_remotely! end event :allow do - transitions from: %i[paused blocked], to: :allowed + transitions from: %i[paused blocked], to: :allowed, guard: :allow_remotely! end event :block do - transitions from: %i[paused allowed], to: :blocked + transitions from: %i[paused allowed], to: :blocked, guard: :block_remotely! end end + + # Elimina la instancia de todas las listas + # + # @return [Boolean] + def pause_remotely! + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? + end + + # Deja de permitir la instancia + # + # @return [Boolean] + def block_remotely! + site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && + site.social_inbox.blocklist.post(list: [instance.list_name]).ok? + end + + # Permite la instancia + # + # @return [Boolean] + def allow_remotely! + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + site.social_inbox.allowlist.post(list: [instance.list_name]).ok? + end end diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 03612779..6677a320 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true require 'distributed_press/v1/social/client' +require 'distributed_press/v1/social/allowlist' +require 'distributed_press/v1/social/blocklist' require 'distributed_press/v1/social/hook' require 'distributed_press/v1/social/inbox' require 'distributed_press/v1/social/dereferencer' @@ -59,6 +61,16 @@ class SocialInbox @hook ||= DistributedPress::V1::Social::Hook.new(client: client, actor: actor) end + # @return [DistributedPress::V1::Social::Allowlist] + def allowlist + @allowlist ||= DistributedPress::V1::Social::Allowlist.new(client: client, actor: actor) + end + + # @return [DistributedPress::V1::Social::Blocklist] + def blocklist + @blocklist ||= DistributedPress::V1::Social::Blocklist.new(client: client, actor: actor) + end + # @return [String] def public_key_url @public_key_url ||= SocialInbox.generate_uri(hostname) do |uri| From a1b5e385b0ff97a079d60fb689fa05757002269e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:50:03 -0300 Subject: [PATCH 497/814] fix: los guards se ejecutan todo el tiempo --- app/models/instance_moderation.rb | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 17b38fb7..735ec387 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -13,15 +13,27 @@ class InstanceModeration < ApplicationRecord state :blocked event :pause do - transitions from: %i[allowed blocked], to: :paused, guard: :pause_remotely! + transitions from: %i[allowed blocked], to: :paused + + before do + pause_remotely! + end end event :allow do - transitions from: %i[paused blocked], to: :allowed, guard: :allow_remotely! + transitions from: %i[paused blocked], to: :allowed + + before do + allow_remotely! + end end event :block do - transitions from: %i[paused allowed], to: :blocked, guard: :block_remotely! + transitions from: %i[paused allowed], to: :blocked + + before do + block_remotely! + end end end @@ -29,7 +41,8 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def pause_remotely! - site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? end @@ -37,7 +50,8 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def block_remotely! - site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && + raise AASM::InvalidTransition unless + site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && site.social_inbox.blocklist.post(list: [instance.list_name]).ok? end @@ -45,7 +59,8 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def allow_remotely! - site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && site.social_inbox.allowlist.post(list: [instance.list_name]).ok? end end From cc7175ab997f2febd906022b9af6a69df7d7e057 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:51:33 -0300 Subject: [PATCH 498/814] feat: poder filtrar por estado de la instancia --- app/controllers/moderation_queue_controller.rb | 2 +- app/views/components/_instances_filters.haml | 2 +- app/views/components/_instances_show_submenu.haml | 5 +++-- app/views/moderation_queue/_instances.haml | 3 +++ config/locales/en.yml | 5 +++++ config/locales/es.yml | 6 ++++-- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index d2123234..8c030460 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -8,7 +8,7 @@ class ModerationQueueController < ApplicationController # @todo cambiar el estado por query @activity_pubs = site.activity_pubs - @instance_moderations = site.instance_moderations + @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) end # Perfil remoto de usuarie diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 213bb7c0..eac20d38 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -3,4 +3,4 @@ = render 'components/instances_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/comments_show_submenu' + = render 'components/instances_show_submenu' diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index 1074cc3f..56206735 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,2 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file += render 'components/dropdown_item', text: t('.submenu_paused'), path: site_moderation_queue_path(state: 'paused') += render 'components/dropdown_item', text: t('.submenu_allowed'), path: site_moderation_queue_path(state: 'allowed') += render 'components/dropdown_item', text: t('.submenu_blocked'), path: site_moderation_queue_path(state: 'blocked') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 2303a061..4c55c439 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,6 +5,9 @@ -# Filtros = render 'components/instances_filters' +- if instance_moderations.count.zero? + %h3= t('moderation_queue.nothing') + - instance_moderations.each do |instance_moderation| %hr = render 'moderation_queue/instance', instance: instance_moderation.instance diff --git a/config/locales/en.yml b/config/locales/en.yml index 1b4f2d86..188b85c4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -60,6 +60,10 @@ en: instances_show_submenu: submenu_allow: Allow submenu_reject: Reject + instances_show_submenu: + submenu_paused: Moderated + submenu_allowed: Allowed + submenu_blocked: Blocked comments_filters: text_show: Show text_checked: With selected @@ -102,6 +106,7 @@ en: text_deny: Block text_report: Report moderation_queue: + nothing: "There's nothing for this filter" index: title: Moderation instances: Instances diff --git a/config/locales/es.yml b/config/locales/es.yml index e277f76b..d3651cb7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -58,8 +58,9 @@ es: submenu_allow: Permitir todo submenu_reject: Rechazado instances_show_submenu: - submenu_allow: Permitido - submenu_reject: Rechazado + submenu_paused: Pausadas + submenu_allowed: Permitidas + submenu_blocked: Bloqueadas comments_filters: text_show: Ver text_checked: Con los marcados @@ -102,6 +103,7 @@ es: text_deny: Bloquear text_report: Reportar moderation_queue: + nothing: 'No hay nada para este filtro' index: title: Actividades de moderación instances: Instancias From e78f71f25a5d6c1190b5efc4a8ede116e4b12800 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 16:52:02 -0300 Subject: [PATCH 499/814] fix: acciones --- app/views/components/_instances_checked_submenu.haml | 4 ++-- app/views/moderation_queue/_instances.haml | 5 +++-- config/locales/en.yml | 8 +++----- config/locales/es.yml | 5 +++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index f0b76185..9da642a7 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,3 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_case'), path: '/' += render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' = render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file += render 'components/dropdown_item', text: t('.submenu_block'), path: '/' diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 4c55c439..20501370 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,6 +1,7 @@ -.row.no-gutters.pt-2 +.row.no-gutters.pt-2 .col-1.d-flex.align-items-center - = render 'components/checkbox', id: moderation_queue.first['id'] + = render 'components/checkbox', id: 'all' do + %span.sr-only= t('moderation_queue.everything') .col-11 -# Filtros = render 'components/instances_filters' diff --git a/config/locales/en.yml b/config/locales/en.yml index 188b85c4..9e40c433 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -54,12 +54,9 @@ en: text_show: Show text_checked: With selected instances_checked_submenu: - submenu_case: Check case by case - submenu_allow: Allow everything - submenu_reject: Reject - instances_show_submenu: + submenu_pause: Moderate submenu_allow: Allow - submenu_reject: Reject + submenu_block: Block instances_show_submenu: submenu_paused: Moderated submenu_allowed: Allowed @@ -106,6 +103,7 @@ en: text_deny: Block text_report: Report moderation_queue: + everything: 'Select all' nothing: "There's nothing for this filter" index: title: Moderation diff --git a/config/locales/es.yml b/config/locales/es.yml index d3651cb7..af75105b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -54,9 +54,9 @@ es: text_show: Ver text_checked: Con los marcados instances_checked_submenu: - submenu_case: Moderar caso por caso + submenu_pause: Moderar caso por caso submenu_allow: Permitir todo - submenu_reject: Rechazado + submenu_block: Rechazar todo instances_show_submenu: submenu_paused: Pausadas submenu_allowed: Permitidas @@ -103,6 +103,7 @@ es: text_deny: Bloquear text_report: Reportar moderation_queue: + everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' index: title: Actividades de moderación From 761d68604b9bbb1ce2a597d0717bd4121762f4e2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 17:03:18 -0300 Subject: [PATCH 500/814] feat: poder seleccionar todas las instancias --- .../controllers/select_all_controller.js | 11 +++++++ app/views/components/_checkbox.haml | 2 +- app/views/components/_select_all.haml | 4 +++ app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 33 ++++++++++--------- 5 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 app/javascript/controllers/select_all_controller.js create mode 100644 app/views/components/_select_all.haml diff --git a/app/javascript/controllers/select_all_controller.js b/app/javascript/controllers/select_all_controller.js new file mode 100644 index 00000000..7aca0f59 --- /dev/null +++ b/app/javascript/controllers/select_all_controller.js @@ -0,0 +1,11 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = ["toggle", "input"]; + + toggle(event = undefined) { + this.inputTargets.forEach(input => { + input.checked = this.toggleTarget.checked; + }); + } +} diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 27f9a776..1932df90 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,4 +1,4 @@ -# Componente Checkbox .custom-control.custom-checkbox - %input.custom-control-input{ type: 'checkbox', id: id, name: id, class: local_assigns[:class] } + %input.custom-control-input{ type: 'checkbox', id: id, name: id, **local_assigns } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_select_all.haml b/app/views/components/_select_all.haml new file mode 100644 index 00000000..2603dfd3 --- /dev/null +++ b/app/views/components/_select_all.haml @@ -0,0 +1,4 @@ +-# + @param id [String] += render 'components/checkbox', id: id, data: { action: 'select-all#toggle', target: 'select-all.toggle' } do + %span.sr-only= t('.label') diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 958a0199..327ea892 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname + = render 'components/checkbox', id: instance.hostname, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= instance.content['title'] diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 20501370..1540ae53 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,24 +1,25 @@ -.row.no-gutters.pt-2 +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/checkbox', id: 'all' do - %span.sr-only= t('moderation_queue.everything') + = render 'components/select_all', id: 'instances' .col-11 -# Filtros = render 'components/instances_filters' -- if instance_moderations.count.zero? - %h3= t('moderation_queue.nothing') + .col-12 + - if instance_moderations.count.zero? + %h3= t('moderation_queue.nothing') -- instance_moderations.each do |instance_moderation| - %hr - = render 'moderation_queue/instance', instance: instance_moderation.instance + - instance_moderations.each do |instance_moderation| + %hr + = render 'moderation_queue/instance', instance: instance_moderation.instance - -# Botones moderación - .d-flex.pb-4 - = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation + -# Botones moderación + .d-flex.pb-4 + = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation -%hr -%h3.mt-5= t('moderation_queue.instances.title') -%lead= t('moderation_queue.instances.description') -= render 'components/block_lists', blocklists: @blocklists -= render 'moderation_queue/block_instances_textarea' + %hr + .col-12 + %h3.mt-5= t('moderation_queue.instances.title') + %lead= t('moderation_queue.instances.description') + = render 'components/block_lists', blocklists: @blocklists + = render 'moderation_queue/block_instances_textarea' From 9b2efaafac38cf7a52dacb63a15f5265d38c1990 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 17:37:34 -0300 Subject: [PATCH 501/814] =?UTF-8?q?feat:=20hacer=20una=20acci=C3=B3n=20con?= =?UTF-8?q?=20las=20seleccionadas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../instance_moderations_controller.rb | 23 ++++++++++- app/policies/instance_moderation_policy.rb | 6 +++ app/views/components/_checkbox.haml | 3 +- app/views/components/_dropdown_button.haml | 4 ++ .../_instances_checked_submenu.haml | 6 +-- app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 38 ++++++++++--------- config/routes.rb | 2 + 8 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 app/views/components/_dropdown_button.haml diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 55f3c51b..67a6be1d 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -2,7 +2,7 @@ # Actualiza la relación entre un sitio y una instancia class InstanceModerationsController < ApplicationController - before_action :authorize_policy + before_action :authorize_policy, except: %i[action_on_several] def pause instance_moderation.pause! @@ -22,6 +22,27 @@ class InstanceModerationsController < ApplicationController redirect_to site_moderation_queue_path end + def action_on_several + instance_moderations = site.instance_moderations.where(id: params[:instance_moderation]) + + authorize instance_moderations + + action = params[:instance_moderation_action].to_sym + method = :"#{action}!" + + InstanceModeration.transaction do + instance_moderations.find_each do |instance_moderation| + events = instance_moderation.aasm.events.map(&:name) + + next unless events.include? action + + instance_moderation.public_send(method) + end + end + + redirect_to site_moderation_queue_path + end + private # @return [InstanceModeration] diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb index 6b3157e8..c07455b3 100644 --- a/app/policies/instance_moderation_policy.rb +++ b/app/policies/instance_moderation_policy.rb @@ -13,4 +13,10 @@ InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do def block? pause? end + + # En este paso tenemos varias instancias por moderar pero todas son + # del mismo sitio. + def action_on_several? + instance_moderation.first.site.usuarie? usuarie + end end diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 1932df90..596ff074 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,4 +1,5 @@ -# Componente Checkbox +- local_assigns[:name] ||= id .custom-control.custom-checkbox - %input.custom-control-input{ type: 'checkbox', id: id, name: id, **local_assigns } + %input.custom-control-input{ type: 'checkbox', id: id, **local_assigns } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_dropdown_button.haml b/app/views/components/_dropdown_button.haml new file mode 100644 index 00000000..8b0c4684 --- /dev/null +++ b/app/views/components/_dropdown_button.haml @@ -0,0 +1,4 @@ +-# + @param name [String] + @param value [String] +%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value }= text diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index 9da642a7..c3573ead 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,3 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_allow'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_block'), path: '/' += render 'components/dropdown_button', text: t('.submenu_pause'), name: 'instance_moderation_action', value: 'pause' += render 'components/dropdown_button', text: t('.submenu_allow'), name: 'instance_moderation_action', value: 'allow' += render 'components/dropdown_button', text: t('.submenu_block'), name: 'instance_moderation_action', value: 'block' diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 327ea892..e7f74b7e 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname, data: { target: 'select-all.input' } + = render 'components/checkbox', id: instance.hostname, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= instance.content['title'] diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 1540ae53..129e1d41 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,24 +1,26 @@ -.row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'instances' - .col-11 - -# Filtros - = render 'components/instances_filters' +%section + %form{ action: site_instance_moderations_action_on_several_path, method: :post } + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'instances' + .col-11 + -# Filtros + = render 'components/instances_filters' - .col-12 - - if instance_moderations.count.zero? - %h3= t('moderation_queue.nothing') + .col-12 + - if instance_moderations.count.zero? + %h3= t('moderation_queue.nothing') + + - instance_moderations.each do |instance_moderation| + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance + + -# Botones moderación + .d-flex.pb-4 + = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation - - instance_moderations.each do |instance_moderation| %hr - = render 'moderation_queue/instance', instance: instance_moderation.instance - - -# Botones moderación - .d-flex.pb-4 - = render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation - - %hr - .col-12 + %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') = render 'components/block_lists', blocklists: @blocklists diff --git a/config/routes.rb b/config/routes.rb index b6250902..d9e2aca7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,6 +68,8 @@ Rails.application.routes.draw do patch :block, to: 'instance_moderations#block' end + patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From ca4b3360cde74d1f325861e98d5d056980b11800 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 26 Feb 2024 17:38:00 -0300 Subject: [PATCH 502/814] fixup! feat: poder seleccionar todas las instancias --- app/processors/instance_moderation_processor.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 app/processors/instance_moderation_processor.rb diff --git a/app/processors/instance_moderation_processor.rb b/app/processors/instance_moderation_processor.rb new file mode 100644 index 00000000..414901d6 --- /dev/null +++ b/app/processors/instance_moderation_processor.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Gestiona los filtros de InstanceModeration +class InstanceModerationProcessor < Rubanok::Processor + map :state, activate_always: true do |state: 'paused'| + raw.where(aasm_state: state) + end +end From 85cfed59fc8fa58fcfc3ba68c73bc03c727215b8 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:14:44 -0300 Subject: [PATCH 503/814] =?UTF-8?q?fix:=20corregido=20posici=C3=B3n=20de?= =?UTF-8?q?=20sumary=20en=20details=20y=20boton=20de=20bloqueo=20de=20inst?= =?UTF-8?q?ancias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/layouts/_details.haml | 3 ++- app/views/moderation_queue/_block_instances_textarea.haml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 306986bf..dd6ac5cf 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,5 +2,6 @@ %details.details.py-2 %summary - %h3.py-2= summary + .col-11 + %h3.py-2= summary = yield diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 9b388a0d..a90704cc 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,5 @@ .form-group = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') = text_area_tag "custom_blocklist", nil, class: 'form-control' - %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') - + %p + %a.mt-3{ role: 'button', href: '', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') From 7837e2e85f1a15b546ba6121b2db57e41d460f1a Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:18:18 -0300 Subject: [PATCH 504/814] fix: corregido espacio en componente block_list --- app/views/components/_block_list.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 36ca8144..0d07a340 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -4,5 +4,5 @@ .d-flex.flex-row = render 'components/checkbox', id: blocklist['id'] do -#%span.h4= blocklist["title"] - %h4 + %h4.m-0 %a{ href: blocklist['link'] }= blocklist['title'] From 570459fef3c6f424f46483c718320f529e728da5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:25:09 -0300 Subject: [PATCH 505/814] =?UTF-8?q?fix:=20corregido=20posici=C3=B3n=20de?= =?UTF-8?q?=20botones=20de=20moderaci=C3=B3n=20en=20details=20de=20Instanc?= =?UTF-8?q?ias=20y=20Cuentas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_account.haml | 4 ++++ app/views/moderation_queue/_accounts.haml | 3 --- app/views/moderation_queue/_instance.haml | 4 ++++ app/views/moderation_queue/_instances.haml | 4 ---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 412f0aa7..2c929402 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -5,3 +5,7 @@ %h4 %a{href: profile['id']}= profile['preferredUsername'] =profile['summary'].html_safe + + -# Botones de Moderación + .d-flex.pb-4 + = render 'components/profiles_btn_box' \ No newline at end of file diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 5fa8638c..2d8e1420 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -9,7 +9,4 @@ %hr = render 'account', profile: remote_profile --# Botones de Moderación -.d-flex.pb-4 - = render 'components/profiles_btn_box' diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index cff8a957..889b6095 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -14,3 +14,7 @@ %span = instance.dig('usage', 'users', 'active_month') = instance.dig('stats', 'user_count') + + -# Botones moderación + .d-flex.pb-4 + = render 'components/instances_btn_box' diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index cf67a473..72be522f 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,10 +9,6 @@ %hr = render 'moderation_queue/instance', instance: instance - -# Botones moderación - .d-flex.pb-4 - = render 'components/instances_btn_box' - %hr %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') From f53ab113396b3e06544b39adf19b9012a865502a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 12:29:42 -0300 Subject: [PATCH 506/814] fixup! feat: poder seleccionar todas las instancias --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index 676b3673..d720a2d6 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 'rubanok' gem 'after_commit_everywhere', '~> 1.0' gem 'aasm' diff --git a/Gemfile.lock b/Gemfile.lock index 8ece3064..72a30af1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -488,6 +488,7 @@ GEM rexml (~> 3.2, >= 3.2.4) stream (~> 0.5.3) rouge (3.30.0) + rubanok (0.5.0) rubocop (1.42.0) json (~> 2.3) parallel (~> 1.10) @@ -679,6 +680,7 @@ DEPENDENCIES redis-rails rgl rollups! + rubanok rubocop-rails ruby-brs rubyzip From df6c04888244afd876a786834892b671baa1bb54 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 12:32:09 -0300 Subject: [PATCH 507/814] feat: fediblock --- app/models/activity_pub/fediblock.rb | 77 +++++++++++++++++++ app/models/activity_pub/instance.rb | 6 ++ .../20240227134845_create_fediblocks.rb | 26 +++++++ db/seeds.rb | 6 ++ db/seeds/activity_pub/fediblocks.yml | 16 ++++ db/structure.sql | 27 ++++++- 6 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 app/models/activity_pub/fediblock.rb create mode 100644 db/migrate/20240227134845_create_fediblocks.rb create mode 100644 db/seeds/activity_pub/fediblocks.yml diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb new file mode 100644 index 00000000..8d024f56 --- /dev/null +++ b/app/models/activity_pub/fediblock.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'httparty' + +# Listas de bloqueo y sus URLs de descarga +class ActivityPub + class Fediblock < ApplicationRecord + class Client + include ::HTTParty + + # @param url [String] + # @return [HTTParty::Response] + def get(url) + self.class.get(url, parser: csv_parser) + end + + # Procesa el CSV + # + # @return [Proc] + def csv_parser + @csv_parser ||= + begin + require 'csv' + + proc do |body, _| + CSV.parse(body, headers: true) + end + end + end + end + + class FediblockDownloadError < ::StandardError; end + + validates_presence_of :title, :url, :download_url, :format + validates_inclusion_of :format, in: %w[mastodon fediblock] + + HOSTNAME_HEADERS = { + 'mastodon' => '#domain', + 'fediblock' => 'domain' + } + + def client + @client ||= Client.new + end + + # Descarga la lista y crea las instancias con el estado necesario + def process! + response = client.get(download_url) + + raise FediblockDownloadError unless response.ok? + + Fediblock.transaction do + csv = response.parsed_response + process_csv! csv + + update(instances: csv.map { |r| r[hostname_header] }) + end + end + + private + + def hostname_header + HOSTNAME_HEADERS[format] + end + + # Crea o encuentra instancias que ya existían y las bloquea + # + # @param csv [CSV::Table] + def process_csv!(csv) + csv.each do |row| + ActivityPub::Instance.find_or_create_by(hostname: row[hostname_header]).tap do |i| + i.block! if i.may_block? + end + end + end + end +end diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 42cd2695..749d98ac 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -21,6 +21,12 @@ class ActivityPub state :paused, initial: true state :allowed state :blocked + + # Al pasar una instancia a bloqueo, quiere decir que todos los + # sitios adoptan esta lista + event :block do + transitions from: %i[paused allowed], to: :blocked + end end def list_name diff --git a/db/migrate/20240227134845_create_fediblocks.rb b/db/migrate/20240227134845_create_fediblocks.rb new file mode 100644 index 00000000..03f65f7c --- /dev/null +++ b/db/migrate/20240227134845_create_fediblocks.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Las fediblocks son listas descargables de instancias bloqueadas. El +# formato hace una recomendación sobre suspensión o desfederación, pero +# nosotres bloqueamos todo. +class CreateFediblocks < ActiveRecord::Migration[6.1] + def up + create_table :activity_pub_fediblocks, id: :uuid do |t| + t.timestamps + + t.string :title, null: false + t.string :url, null: false + t.string :download_url, null: false + t.string :format, null: false + t.jsonb :instances, default: [] + end + + YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| + ActivityPub::Fediblock.create(**fediblock).process! + end + end + + def down + drop_table :activity_pub_fediblocks + end +end diff --git a/db/seeds.rb b/db/seeds.rb index b9ef96a1..8e8c291f 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -27,3 +27,9 @@ if PrivacyPolicy.count.zero? PrivacyPolicy.new(**pp).save! end end + +YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| + ActivityPub::Fediblock.find_or_create_by(id: fediblock['id']).tap do |f| + f.update(**fediblock) + end +end diff --git a/db/seeds/activity_pub/fediblocks.yml b/db/seeds/activity_pub/fediblocks.yml new file mode 100644 index 00000000..c977f9bf --- /dev/null +++ b/db/seeds/activity_pub/fediblocks.yml @@ -0,0 +1,16 @@ +--- +- title: "Gardenfence" + url: "https://gardenfence.github.io/" + download_url: "https://github.com/gardenfence/blocklist/raw/main/gardenfence-fediblocksync.csv" + format: "fediblock" + id: "9046789a-5de8-4b16-beed-796060f8f3cc" +- title: "Oliphant Tier 0" + url: "https://writer.oliphant.social/oliphant/the-oliphant-social-blocklist" + download_url: "https://codeberg.org/oliphant/blocklists/raw/branch/main/blocklists/mastodon/tier0.csv" + format: "mastodon" + id: "fc1efcb8-7e68-4a76-ae9e-0c447752b12b" +- title: "The Bad Space (90%)" + url: "https://tweaking.thebad.space/exports" + download_url: "https://tweaking.thebad.space/exports/mastodon/90" + format: "fediblock" + id: "5dd6705a-c28f-4912-9456-07b0d4983108" diff --git a/db/structure.sql b/db/structure.sql index c3896060..241039d1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -502,6 +502,22 @@ CREATE TABLE public.activity_pub_actors ( ); +-- +-- Name: activity_pub_fediblocks; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_fediblocks ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + title character varying NOT NULL, + url character varying NOT NULL, + download_url character varying NOT NULL, + format character varying NOT NULL, + instances jsonb DEFAULT '[]'::jsonb +); + + -- -- Name: activity_pub_instances; Type: TABLE; Schema: public; Owner: - -- @@ -1694,6 +1710,14 @@ ALTER TABLE ONLY public.activity_pub_actors ADD CONSTRAINT activity_pub_actors_pkey PRIMARY KEY (id); +-- +-- Name: activity_pub_fediblocks activity_pub_fediblocks_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_fediblocks + ADD CONSTRAINT activity_pub_fediblocks_pkey PRIMARY KEY (id); + + -- -- Name: activity_pub_instances activity_pub_instances_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2546,6 +2570,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240221184007'), ('20240223170317'), ('20240226133022'), -('20240226134335'); +('20240226134335'), +('20240227134845'); From e728c09cc244b7a7a528d57b543fead8b74da312 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 12:35:25 -0300 Subject: [PATCH 508/814] =?UTF-8?q?fix:=20corregida=20traducci=C3=B3n=20de?= =?UTF-8?q?=20usuarios=20de=20instancia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_instance.haml | 6 +++--- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 889b6095..3bfbde44 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -9,9 +9,9 @@ %h4 %a{ href: hosthttps }= instance['title'] %p= instance['description'].html_safe - %p - %span= t('.users') - %span + %dl + %dt= t('.users') + %dd = instance.dig('usage', 'users', 'active_month') = instance.dig('stats', 'user_count') diff --git a/config/locales/en.yml b/config/locales/en.yml index 1b4f2d86..51b1df4d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -122,6 +122,7 @@ en: description: Description custom_block: Custom block lists submit: Save block lists + instance: users: "Users:" dark: Dark dir: ltr diff --git a/config/locales/es.yml b/config/locales/es.yml index e277f76b..f4751c7a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -122,6 +122,7 @@ es: description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo submit: Guardar lista de bloqueo + instance: users: "Usuaries:" dark: Oscuro es: Castellano From ae0ca386c3102171e44fb9b0173350208ba7740e Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 13:07:51 -0300 Subject: [PATCH 509/814] fix: correciones varias en componente remote_profile --- app/views/moderation_queue/_remote_profile.haml | 10 +++++++--- config/locales/en.yml | 1 + config/locales/es.yml | 3 ++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 43474b80..263f9c6b 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -5,12 +5,16 @@ %dt= t('.profile_name') %dd= remote_profile['name'] + %dt= t('.preferred_name') + %dd= remote_profile['preferredUsername'] + %dt= t('.profile_id') - %dd= remote_profile['id'] + %dd + %a{ href: 'https://mastodon.mauve.moe/users/mauve' }= remote_profile['id'] %dt= t('.profile_published') - %dd= remote_profile['published'].to_datetime.strftime('%m/%d/%Y') - + %dd + = render 'layouts/time', time: remote_profile['published'] %dt= t('.profile_summary') %dd= remote_profile['summary'].html_safe diff --git a/config/locales/en.yml b/config/locales/en.yml index 51b1df4d..9aa2c801 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -114,6 +114,7 @@ en: user: Username profile: Profile profile_name: Profile name + preferred_name: Name in Fediverse profile_id: ID profile_published: Published profile_summary: Summary diff --git a/config/locales/es.yml b/config/locales/es.yml index f4751c7a..e39b13c2 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -114,9 +114,10 @@ es: user: Nombre de usuario profile: Cuenta de Origen profile_name: Nombre de la Cuenta + preferred_name: Nombre en el Fediverso profile_id: ID profile_published: Publicada - profile_summary: Resumen + profile_summary: Presentación instances: title: Mis listas de bloqueo description: Descripción de listas de bloqueo From 5a30da4232282d8fdb7483109b9c420d9dfbc674 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 13:14:25 -0300 Subject: [PATCH 510/814] =?UTF-8?q?fix:=20corregido=20parrafo=20en=20Prese?= =?UTF-8?q?ntaci=C3=B3n=20de=20componente=20Remote=5Fprofile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_remote_profile.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 263f9c6b..92cf8e96 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -16,7 +16,8 @@ %dd = render 'layouts/time', time: remote_profile['published'] %dt= t('.profile_summary') - %dd= remote_profile['summary'].html_safe + %dd + %p= remote_profile['summary'].html_safe = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 8654228edcd3d7b24562f0f62565662b99100373 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 13:25:40 -0300 Subject: [PATCH 511/814] =?UTF-8?q?feat:=20actualizar=20los=20fediblocks?= =?UTF-8?q?=20todos=20los=20d=C3=ADas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Procfile | 1 + app/jobs/activity_pub/fediblock_fetch_job.rb | 14 ++++++++++++++ lib/tasks/activity_pub.rake | 8 ++++++++ monit.conf | 5 +++++ 4 files changed, 28 insertions(+) create mode 100644 app/jobs/activity_pub/fediblock_fetch_job.rb create mode 100644 lib/tasks/activity_pub.rake diff --git a/Procfile b/Procfile index eab8a502..a74f613b 100644 --- a/Procfile +++ b/Procfile @@ -10,3 +10,4 @@ cleanup: bundle exec rake cleanup:everything emergency_cleanup: bundle exec rake cleanup:everything BEFORE=7 stats: bundle exec rake stats:process_all que: daemonize -c /srv/ -p /srv/tmp/que.pid -u rails /usr/local/bin/syslogize bundle exec que +fediblock: bundle exec rails activity_pub:fediblocks diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb new file mode 100644 index 00000000..d6cb4b83 --- /dev/null +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class ActivityPub + # Se encarga de mantener las listas de bloqueo actualizadas + class FediblockFetchJob < ApplicationJob + def perform + ActivityPub::Fediblock.find_each do |fediblock| + fediblock.process! + rescue ActivityPub::Fediblock::FediblockDownloadError => e + ExceptionNotifier.notify_exception(e, data: { fediblock: fediblock.title }) + end + end + end +end diff --git a/lib/tasks/activity_pub.rake b/lib/tasks/activity_pub.rake new file mode 100644 index 00000000..08c0f980 --- /dev/null +++ b/lib/tasks/activity_pub.rake @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +namespace :activity_pub do + desc 'Update Fediblocks' + task fediblocks: :environment do |_, args| + ActivityPub::FediblockFetchJob.perform_later + end +end diff --git a/monit.conf b/monit.conf index accd0e28..2b7e50a8 100644 --- a/monit.conf +++ b/monit.conf @@ -9,6 +9,11 @@ check program distributed_press_tokens_renew every "0 3 * * *" if status != 0 then alert +check program fediblocks + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv fediblocks" as uid "rails" gid "www-data" + every "0 7 * * *" + if status != 0 then alert + check program access_logs with path "/srv/http/bin/access_logs" as uid "app" and gid "www-data" every "0 0 * * *" From ebdd95151e61bc90d646a7564c289ed67d326981 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 13:43:46 -0300 Subject: [PATCH 512/814] feat: relacionar sitios con fediblocks --- app/models/fediblock_state.rb | 72 +++++++++++++++++++ app/models/site/social_distributed_press.rb | 1 + .../20240227142019_create_fediblock_states.rb | 29 ++++++++ db/structure.sql | 46 +++++++++++- 4 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 app/models/fediblock_state.rb create mode 100644 db/migrate/20240227142019_create_fediblock_states.rb diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb new file mode 100644 index 00000000..8045e23e --- /dev/null +++ b/app/models/fediblock_state.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# Relación entre Fediblocks y Sites +class FediblockState < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :fediblock, class_name: 'ActivityPub::Fediblock' + + # El efecto secundario de esta máquina de estados es modificar el + # estado de moderación de cada instancia en el sitio. Nos salteamos + # los hooks de los eventos individuales. + aasm do + # Aunque queramos las listas habilitadas por defecto, tenemos que + # habilitarlas luego de crearlas para poder generar la lista de + # bloqueo en la Social Inbox. + state :disabled, initial: true + state :enabled + + event :enable do + transitions from: :disabled, to: :enabled + + before do + enable_remotely! + end + end + + # Al deshabilitar, las listas pasan a modo pausa. + # + # @todo No cambiar el estado si se habían habilitado manualmente, + # pero esto implica que tenemos que encontrar las que sí y quitarlas + # de list_names + event :disable do + transitions from: :enabled, to: :disabled + + before do + disable_remotely! + end + end + end + + private + + # Obtiene todos los IDs de instancias para poder obtener el estado de + # moderación en el sitio. + # + # @return [Array] + def instance_ids + ActivityPub::Instance.where(hostname: fediblock.instances).pluck(:id) + end + + # @return [Array] + def list_names + @list_names ||= fediblock.instances.map do |instance| + "@*@#{instance}" + end + end + + # Al deshabilitar, las instancias pasan a ser analizadas caso por caso + def disable_remotely! + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.delete(list: list_names).ok? && + site.social_inbox.allowlist.delete(list: list_names).ok? + end + + # Al habilitar, se bloquean todas las instancias de la lista + def enable_remotely! + raise AASM::InvalidTransition unless + site.social_inbox.blocklist.post(list: list_names).ok? && + site.social_inbox.allowlist.delete(list: list_names).ok? + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 73b284bf..e0d2d4f4 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -12,6 +12,7 @@ class Site has_many :activity_pubs has_many :instance_moderations + has_many :fediblock_states before_save :generate_private_key_pem!, unless: :private_key_pem? diff --git a/db/migrate/20240227142019_create_fediblock_states.rb b/db/migrate/20240227142019_create_fediblock_states.rb new file mode 100644 index 00000000..c99cf63d --- /dev/null +++ b/db/migrate/20240227142019_create_fediblock_states.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# La relación entre sitios y fediblocks +class CreateFediblockStates < ActiveRecord::Migration[6.1] + def up + create_table :fediblock_states, id: :uuid do |t| + t.timestamps + + t.belongs_to :site + t.uuid :fediblock_id, index: true + t.string :aasm_state + + t.index %i[site_id fediblock_id], unique: true + end + + # Todas las listas están activas por defecto + DeploySocialDistributedPress.find_each do |deploy| + ActivityPub::Fediblock.find_each do |fediblock| + FediblockState.create(site: deploy.site, fediblock: fediblock, aasm_state: 'disabled').tap do |f| + f.enable! + end + end + end + end + + def down + drop_table :fediblock_states + end +end diff --git a/db/structure.sql b/db/structure.sql index 241039d1..ac897695 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -944,6 +944,20 @@ CREATE SEQUENCE public.distributed_press_publishers_id_seq ALTER SEQUENCE public.distributed_press_publishers_id_seq OWNED BY public.distributed_press_publishers.id; +-- +-- Name: fediblock_states; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.fediblock_states ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + fediblock_id uuid, + aasm_state character varying +); + + -- -- Name: indexed_posts; Type: TABLE; Schema: public; Owner: - -- @@ -1830,6 +1844,14 @@ ALTER TABLE ONLY public.distributed_press_publishers ADD CONSTRAINT distributed_press_publishers_pkey PRIMARY KEY (id); +-- +-- Name: fediblock_states fediblock_states_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.fediblock_states + ADD CONSTRAINT fediblock_states_pkey PRIMARY KEY (id); + + -- -- Name: indexed_posts indexed_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2176,6 +2198,27 @@ CREATE UNIQUE INDEX index_designs_on_gem ON public.designs USING btree (gem); CREATE UNIQUE INDEX index_designs_on_name ON public.designs USING btree (name); +-- +-- Name: index_fediblock_states_on_fediblock_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_fediblock_states_on_fediblock_id ON public.fediblock_states USING btree (fediblock_id); + + +-- +-- Name: index_fediblock_states_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_fediblock_states_on_site_id ON public.fediblock_states USING btree (site_id); + + +-- +-- Name: index_fediblock_states_on_site_id_and_fediblock_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_fediblock_states_on_site_id_and_fediblock_id ON public.fediblock_states USING btree (site_id, fediblock_id); + + -- -- Name: index_indexed_posts_on_front_matter; Type: INDEX; Schema: public; Owner: - -- @@ -2571,6 +2614,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240223170317'), ('20240226133022'), ('20240226134335'), -('20240227134845'); +('20240227134845'), +('20240227142019'); From c0b64fc3da31846c2e1e85c900d3b1d5e0323988 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 14:08:48 -0300 Subject: [PATCH 513/814] fix: corregido enlace a listas de bloqueo en compo block_list --- app/views/components/_block_list.haml | 4 ++-- app/views/moderation_queue/_block_instances_textarea.haml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 0d07a340..5bc0e130 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -3,6 +3,6 @@ .card-body .d-flex.flex-row = render 'components/checkbox', id: blocklist['id'] do - -#%span.h4= blocklist["title"] - %h4.m-0 + %span.h4= blocklist["title"] + %p %a{ href: blocklist['link'] }= blocklist['title'] diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index a90704cc..9b388a0d 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,5 @@ .form-group = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') = text_area_tag "custom_blocklist", nil, class: 'form-control' - %p - %a.mt-3{ role: 'button', href: '', class: 'btn btn-secondary' }= t('moderation_queue.instances.submit') + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') + From ec328d31b9e988c85d0b2c58c04f76e8dccee0a5 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 14:23:57 -0300 Subject: [PATCH 514/814] feat: cargar las fediblocks en la pantalla --- app/views/components/_block_list.haml | 6 +++--- app/views/components/_block_lists.haml | 4 ++-- app/views/moderation_queue/_instances.haml | 2 +- app/views/moderation_queue/index.haml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 5bc0e130..c70b40f8 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -2,7 +2,7 @@ .card.mt-3.mb-3 .card-body .d-flex.flex-row - = render 'components/checkbox', id: blocklist['id'] do - %span.h4= blocklist["title"] + = render 'components/checkbox', id: state.id, checked: state.enabled? do + %span.h4= blocklist.title %p - %a{ href: blocklist['link'] }= blocklist['title'] + %a{ href: blocklist.url }= t('.more') diff --git a/app/views/components/_block_lists.haml b/app/views/components/_block_lists.haml index 1e9cd76f..b6dc0afa 100644 --- a/app/views/components/_block_lists.haml +++ b/app/views/components/_block_lists.haml @@ -1,2 +1,2 @@ -- @blocklists.each do |blocklist| - = render 'components/block_list', blocklist: blocklist +- blocklists.each do |blocklist| + = render 'components/block_list', blocklist: blocklist.fediblock, state: blocklist diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 6303d07c..a08c8b10 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -19,5 +19,5 @@ %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') - = render 'components/block_lists', blocklists: @blocklists + = render 'components/block_lists', blocklists: fediblock_states = render 'moderation_queue/block_instances_textarea' diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0c937758..0fb1c968 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -5,7 +5,7 @@ .col - summary = t('.instances') = render 'layouts/details', summary: summary do - = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations + = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations, fediblock_states: @site.fediblock_states %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do From cda5fc1215c1613465047fe73fb3866244fff1d3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 14:37:07 -0300 Subject: [PATCH 515/814] fix: corregido enlace en block_list y texto en es.yml --- app/views/components/_block_list.haml | 3 ++- config/locales/es.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 5bc0e130..0c7a7b04 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -4,5 +4,6 @@ .d-flex.flex-row = render 'components/checkbox', id: blocklist['id'] do %span.h4= blocklist["title"] - %p + + %p.mb-0 %a{ href: blocklist['link'] }= blocklist['title'] diff --git a/config/locales/es.yml b/config/locales/es.yml index e39b13c2..7a2bfd85 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -122,7 +122,7 @@ es: title: Mis listas de bloqueo description: Descripción de listas de bloqueo custom_block: Lista personalizada de bloqueo - submit: Guardar lista de bloqueo + submit: Guardar listas de bloqueo instance: users: "Usuaries:" dark: Oscuro From 0dba9e550040f1cfb53778ee9f4f1de5c7aed406 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 15:05:16 -0300 Subject: [PATCH 516/814] =?UTF-8?q?fix:=20corregida=20alineaci=C3=B3n=20de?= =?UTF-8?q?=20checkbox=20general=20en=20details=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_comment.haml | 44 +++++++++++------------ app/views/moderation_queue/_comments.haml | 2 +- app/views/posts/_moderation_queue.haml | 1 + 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 4836f03d..afd2a335 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,27 +1,27 @@ -# Componente Comentario -.flex.mx-4.my-4 - .row.no-gutters - .col-1 - = render 'components/checkbox', id: comment['id'] - .col-11 - .row.no-gutters - .col.col-lg-10.d-inline-flex.justify-content-between - %h4 - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] - = render 'layouts/time', time: comment['published'] - - if comment['inReplyTo'] - .row.no-gutters - .col.p-0 - %p - %span= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + +.row.no-gutters + .col-1 + = render 'components/checkbox', id: comment['id'] + .col-11 + .row.no-gutters + .col.col-lg-10.d-inline-flex.justify-content-between + %h4 + %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + = render 'layouts/time', time: comment['published'] + - if comment['inReplyTo'] .row.no-gutters .col.p-0 - - if comment['summary'] - - summary = comment['summary'] - = render 'layouts/details', summary: summary do - %p= comment['content'].html_safe - - else + %p + %span= t('.reply_to') + %span + %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] + .row.no-gutters + .col.p-0 + - if comment['summary'] + - summary = comment['summary'] + = render 'layouts/details', summary: summary do %p= comment['content'].html_safe + - else + %p= comment['content'].html_safe diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 6fa8c0f4..eadfd78b 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,7 +1,7 @@ .row.no-gutters.pt-2 .col-1.d-flex.align-items-center = render 'components/checkbox', id: moderation_queue.first['id'] - .col-11 + .col-md-9 -# Filtros = render 'components/comments_filters' diff --git a/app/views/posts/_moderation_queue.haml b/app/views/posts/_moderation_queue.haml index 2ec6a07d..a72e8abd 100644 --- a/app/views/posts/_moderation_queue.haml +++ b/app/views/posts/_moderation_queue.haml @@ -6,6 +6,7 @@ = render 'components/comments_filters' - moderation_queue.each do |comment| + %hr = render 'moderation_queue/comment', comment: comment, profile: comment['attributedTo'] -# Botones moderación From bbbbad18a073e5931adad4b256599840297977d1 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 15:21:31 -0300 Subject: [PATCH 517/814] fix: corregido margen en summary de compo details --- app/views/layouts/_details.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index dd6ac5cf..99ba4894 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,6 +2,7 @@ %details.details.py-2 %summary - .col-11 - %h3.py-2= summary + .row + .col-11.pr-2 + %h3.py-2= summary = yield From e239bd8b85fd6dad2e7fe4fcec72c46beb323b7a Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 15:25:25 -0300 Subject: [PATCH 518/814] fix: corregido usuarios en compo instance --- app/views/moderation_queue/_instance.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 3bfbde44..ec887d2d 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -9,8 +9,8 @@ %h4 %a{ href: hosthttps }= instance['title'] %p= instance['description'].html_safe - %dl - %dt= t('.users') + %dl.d-inline-flex + %dt.pr-2= t('.users') %dd = instance.dig('usage', 'users', 'active_month') = instance.dig('stats', 'user_count') From d4fa056db4d652070a829b16b79cea92f3e5c426 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 27 Feb 2024 16:08:11 -0300 Subject: [PATCH 519/814] fix: corregido summary en compo details --- app/views/layouts/_details.haml | 4 +--- app/views/moderation_queue/_remote_profile.haml | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 99ba4894..a40d0403 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -2,7 +2,5 @@ %details.details.py-2 %summary - .row - .col-11.pr-2 - %h3.py-2= summary + %h3.py-2.pr-2= summary = yield diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml index 92cf8e96..263f9c6b 100644 --- a/app/views/moderation_queue/_remote_profile.haml +++ b/app/views/moderation_queue/_remote_profile.haml @@ -16,8 +16,7 @@ %dd = render 'layouts/time', time: remote_profile['published'] %dt= t('.profile_summary') - %dd - %p= remote_profile['summary'].html_safe + %dd= remote_profile['summary'].html_safe = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 4bc11c700755d211967ef1b71e5e6828fc0f9e94 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:39:02 -0300 Subject: [PATCH 520/814] feat: gestionar listas de bloqueo desde el panel --- .../fediblock_states_controller.rb | 40 +++++++++++++++++++ .../activity_pub/instance_moderation_job.rb | 29 ++++++++++++++ app/models/site/social_distributed_press.rb | 1 + app/views/components/_block_list.haml | 14 ++++--- .../_block_instances_textarea.haml | 6 +-- app/views/moderation_queue/_instances.haml | 9 ++++- config/locales/en.yml | 2 + config/locales/es.yml | 2 + config/routes.rb | 1 + 9 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 app/controllers/fediblock_states_controller.rb create mode 100644 app/jobs/activity_pub/instance_moderation_job.rb diff --git a/app/controllers/fediblock_states_controller.rb b/app/controllers/fediblock_states_controller.rb new file mode 100644 index 00000000..c116b75a --- /dev/null +++ b/app/controllers/fediblock_states_controller.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# Estado de las listas de bloqueo en cada sitio +class FediblockStatesController < ApplicationController + # Realiza cambios en las listas de bloqueo + def action_on_several + if fediblock_states_ids.present? + # Encontrar todas y deshabilitar las que no se enviaron + site.fediblock_states.all.find_each do |fediblock_state| + if fediblock_states_ids.include? fediblock_state.id + fediblock_state.enable! if fediblock_state.may_enable? + elsif fediblock_state.may_disable? + fediblock_state.disable! + end + end + end + + # Bloquear otras instancias + if custom_blocklist.present? + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: custom_blocklist) + end + + redirect_to site_moderation_queue_path + end + + private + + def fediblock_states_ids + params[:fediblock_states_ids] || [] + end + + # La lista de hostnames + def custom_blocklist + @custom_blocklist ||= fediblocks_states_params[:custom_blocklist].split("\n").map(&:strip).select(&:present?) + end + + def fediblocks_states_params + @fediblocks_states_params ||= params.permit(:custom_blocklist, fediblock_states_ids: []) + end +end diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb new file mode 100644 index 00000000..a9b0bea0 --- /dev/null +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class ActivityPub + # Bloquea varias instancias de una sola vez + class InstanceModerationJob < ApplicationJob + # @param :site [Site] + # @param :hostnames [Array] + def perform(site:, hostnames:) + # Crear las instancias que no existan todavía + hostnames.each do |hostname| + ActivityPub::Instance.find_or_create_by(hostname: hostname) + end + + instances = ActivityPub::Instance.where(hostname: hostnames) + + Site.transaction do + # Crea todas las moderaciones de instancia con un estado por + # defecto si no existen + instances.find_each do |instance| + # Esto bloquea cada una individualmente en la Social Inbox, + # idealmente son pocas instancias las que aparecen. + site.instance_moderations.find_or_create_by(instance: instance).tap do |instance_moderation| + instance_moderation.block! if instance_moderation.may_block? + end + end + end + end + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index e0d2d4f4..fdb37bca 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -13,6 +13,7 @@ class Site has_many :activity_pubs has_many :instance_moderations has_many :fediblock_states + has_many :instances, through: :instance_moderations before_save :generate_private_key_pem!, unless: :private_key_pem? diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index f972642a..79481363 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -1,8 +1,12 @@ -# Componente Listas de bloqueo de Instancias +- know_more = t('.know_more') .card.mt-3.mb-3 .card-body - .d-flex.flex-row - = render 'components/checkbox', id: state.id, checked: state.enabled? do - %span.h4= blocklist.title - %p.mb-0 - %a{ href: blocklist.url }= t('.more') + = render 'components/checkbox', id: state.id, name: 'fediblock_states_ids[]', value: state.id, checked: state.enabled? do + %span.h4.mb-0= blocklist.title + + %dl.mb-0 + %dt.d-inline= t('.instances_blocked') + %dd.d-inline.font-weight-normal= blocklist.instances.count + %p.mb-0.font-weight-normal + %a{ href: blocklist.url }= know_more diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 9b388a0d..9729d4de 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,5 +1,3 @@ .form-group - = label_tag "custom_blocklist", t('moderation_queue.instances.custom_block') - = text_area_tag "custom_blocklist", nil, class: 'form-control' - %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') - + = label_tag 'custom_blocklist', t('moderation_queue.instances.custom_block') + = text_area_tag 'custom_blocklist', nil, class: 'form-control' diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a08c8b10..d2ebb5a7 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -19,5 +19,10 @@ %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') - = render 'components/block_lists', blocklists: fediblock_states - = render 'moderation_queue/block_instances_textarea' + + = form_tag site_fediblock_states_action_on_several_path, method: :patch do + = render 'components/block_lists', blocklists: fediblock_states + = render 'moderation_queue/block_instances_textarea' + + .form-group + %button.btn.btn-secondary.mt-3{ type: 'submit' }= t('moderation_queue.instances.submit') diff --git a/config/locales/en.yml b/config/locales/en.yml index 9581285f..717c9ece 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -50,6 +50,8 @@ en: pm: pm format: '%-I:%M %p' components: + block_list: + know_more: Know more instances_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index 9b1f1937..87111523 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -50,6 +50,8 @@ es: pm: pm format: '%-H:%M' components: + block_list: + know_more: Saber más (en inglés) instances_filters: text_show: Ver text_checked: Con los marcados diff --git a/config/routes.rb b/config/routes.rb index d9e2aca7..d70f8339 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -69,6 +69,7 @@ Rails.application.routes.draw do end patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' + patch :fediblock_states_action_on_several, to: 'fediblock_states#action_on_several' # Gestionar artículos según idioma nested do From d5f48c60073e8245e1f1cf1cbd8c558da60cdcfc Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:40:08 -0300 Subject: [PATCH 521/814] feat: al actualizar las blocklists, bloquear las instancias en los sitios que las tengan habilitadas --- app/jobs/activity_pub/fediblock_fetch_job.rb | 11 ++++++++- .../activity_pub/fediblock_updated_job.rb | 24 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 app/jobs/activity_pub/fediblock_updated_job.rb diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb index d6cb4b83..6730cbf0 100644 --- a/app/jobs/activity_pub/fediblock_fetch_job.rb +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -1,11 +1,20 @@ # frozen_string_literal: true class ActivityPub - # Se encarga de mantener las listas de bloqueo actualizadas + # Se encarga de mantener las listas de bloqueo actualizadas. Luego de + # actualizar el listado de instancias, bloquea las instancias en cada + # sitio que tenga el fediblock habilitado. class FediblockFetchJob < ApplicationJob def perform ActivityPub::Fediblock.find_each do |fediblock| fediblock.process! + + instances_added = fediblock.instances - fediblock.instances_was + + # No hacer nada si no cambió con respecto a la versión anterior + next if instances_added.empty? + + ActivityPub::FediblockUpdatedJob.perform_later(fediblock: fediblock, hostnames: instances_added) rescue ActivityPub::Fediblock::FediblockDownloadError => e ExceptionNotifier.notify_exception(e, data: { fediblock: fediblock.title }) end diff --git a/app/jobs/activity_pub/fediblock_updated_job.rb b/app/jobs/activity_pub/fediblock_updated_job.rb new file mode 100644 index 00000000..007fa25e --- /dev/null +++ b/app/jobs/activity_pub/fediblock_updated_job.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Se encarga de mantener sincronizadas las listas de instancias +# de los fediblocks con los sitios que las tengan activadas. +class ActivityPub + class FediblockUpdatedJob < ApplicationJob + # @param :fediblock [ActivityPub::Fediblock] + # @param :instances [Array] + def perform(fediblock:, hostnames:) + instances = ActivityPub::Instance.where(hostname: instances) + + # Todos los sitios con la Social Inbox habilitada + Site.where(id: DeploySocialDistributedPress.pluck(:site_id)).find_each do |site| + # Crea el estado si no existía + fediblock_state = site.fediblock_states.find_or_create_by(fediblock: fediblock) + + # No hace nada con los deshabilitados + next unless fediblock_state.enabled? + + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: instances) + end + end + end +end From 34ead9ea4a40957e4f6251c691dcc5d53e258488 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:53:48 -0300 Subject: [PATCH 522/814] feat: establecer prioridades para las tareas --- app/jobs/activity_pub/actor_fetch_job.rb | 2 ++ app/jobs/activity_pub/fediblock_fetch_job.rb | 2 ++ app/jobs/activity_pub/fediblock_updated_job.rb | 2 ++ app/jobs/activity_pub/fetch_job.rb | 2 ++ app/jobs/activity_pub/instance_fetch_job.rb | 2 ++ app/jobs/activity_pub/instance_moderation_job.rb | 2 ++ 6 files changed, 12 insertions(+) diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb index 1c6f1735..71107151 100644 --- a/app/jobs/activity_pub/actor_fetch_job.rb +++ b/app/jobs/activity_pub/actor_fetch_job.rb @@ -9,6 +9,8 @@ # autenticación. class ActivityPub class ActorFetchJob < ApplicationJob + self.priority = 50 + def perform(site:, actor:) ActivityPub::Actor.transaction do response = site.social_inbox.dereferencer.get(uri: actor.uri) diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb index 6730cbf0..aa748bc6 100644 --- a/app/jobs/activity_pub/fediblock_fetch_job.rb +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -5,6 +5,8 @@ class ActivityPub # actualizar el listado de instancias, bloquea las instancias en cada # sitio que tenga el fediblock habilitado. class FediblockFetchJob < ApplicationJob + self.priority = 50 + def perform ActivityPub::Fediblock.find_each do |fediblock| fediblock.process! diff --git a/app/jobs/activity_pub/fediblock_updated_job.rb b/app/jobs/activity_pub/fediblock_updated_job.rb index 007fa25e..b4a56609 100644 --- a/app/jobs/activity_pub/fediblock_updated_job.rb +++ b/app/jobs/activity_pub/fediblock_updated_job.rb @@ -4,6 +4,8 @@ # de los fediblocks con los sitios que las tengan activadas. class ActivityPub class FediblockUpdatedJob < ApplicationJob + self.priority = 50 + # @param :fediblock [ActivityPub::Fediblock] # @param :instances [Array] def perform(fediblock:, hostnames:) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index b6c45026..e3fef993 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -9,6 +9,8 @@ # autenticación. class ActivityPub class FetchJob < ApplicationJob + self.priority = 50 + def perform(site:, object:) ActivityPub::Object.transaction do return if object.activity_pubs.where(aasm_state: 'removed').count.positive? diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index a5c07162..0ceb1a8a 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -3,6 +3,8 @@ class ActivityPub # Obtiene o actualiza los datos de una instancia. class InstanceFetchJob < ApplicationJob + self.priority = 100 + def perform(site:, instance:) %w[/api/v2/instance /api/v1/instance].each do |api| uri = SocialInbox.generate_uri(instance.hostname) do |u| diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index a9b0bea0..b205e68f 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -3,6 +3,8 @@ class ActivityPub # Bloquea varias instancias de una sola vez class InstanceModerationJob < ApplicationJob + self.priority = 50 + # @param :site [Site] # @param :hostnames [Array] def perform(site:, hostnames:) From 342521c897d77243e63fcbb565651eba7ae0f80d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 27 Feb 2024 16:54:09 -0300 Subject: [PATCH 523/814] fix: guardar los datos de la instancia --- app/jobs/activity_pub/instance_fetch_job.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index 0ceb1a8a..ce202092 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true class ActivityPub - # Obtiene o actualiza los datos de una instancia. + # Obtiene o actualiza los datos de una instancia. Usamos un cliente + # de ActivityPub porque la instancia podría estar en federación + # limitada. class InstanceFetchJob < ApplicationJob self.priority = 100 @@ -14,8 +16,10 @@ class ActivityPub response = site.social_inbox.dereferencer.get(uri: uri) next unless response.ok? + # @todo Validate schema + next unless response.parsed_response.is_a?(DistributedPress::V1::Social::ReferencedObject) - instance.update(content: response.parsed_response) + instance.update(content: response.parsed_response.object) break end From aae04f3739c1cd07a4518922d8ff2cbac66180ac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 11:54:41 -0300 Subject: [PATCH 524/814] feat: al activar el fediverso, activar las listas de bloqueo --- app/models/deploy_social_distributed_press.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 7f761e46..9f968f36 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -8,6 +8,7 @@ class DeploySocialDistributedPress < Deploy DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync].freeze after_save :create_hooks! + after_create :enable_fediblocks! # Envía las notificaciones def deploy(output: false) @@ -95,4 +96,16 @@ class DeploySocialDistributedPress < Deploy ExceptionNotifier.notify_exception(e, data: { site_id: site.name, usuarie_id: rol.usuarie_id }) end end + + # Habilita todos los fediblocks disponibles. + # + # @todo Hacer que algunos sean opcionales + # @todo Mover a un Job + def enable_fediblocks! + ActivityPub::Fediblock.find_each do |fediblock| + site.fediblock_states.find_or_create_by(fediblock: fediblock).tap do |state| + state.enable! if state.may_enable? + end + end + end end From dc82b8cef2ee014898128a8916b75c5358d9646d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 12:05:09 -0300 Subject: [PATCH 525/814] feat: asignar rol a deploys al crear o modificar el sitio --- app/services/site_service.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 5c37cfe3..a3649bc5 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -26,6 +26,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # que no haya estados intermedios. site.locales = [usuarie.lang] + I18n.available_locales + add_role_to_deploys! + site.save && site.config.write && commit_config(action: :create) && @@ -43,7 +45,10 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Actualiza el sitio y guarda los cambios en la configuración def update I18n.with_locale(usuarie&.lang&.to_sym || I18n.default_locale) do - site.update(params) && + site.assign_attributes(params) + add_role_to_deploys! + + site.save && site.config.write && commit_config(action: :update) && site.reset.nil? && @@ -224,6 +229,17 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do private + # Asignar un rol a cada deploy si no lo tenía ya + def add_role_to_deploys! + site.deploys.each do |deploy| + deploy.rol ||= current_role + end + end + + def current_role + @current_role ||= usuarie.rol_for_site(site) + end + def with_all_locales(&block) site.locales.map do |locale| next unless I18n.available_locales.include? locale From d5cf0fffe09183cf9aea111bfaff60d6e7d6bfcb Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 12:09:16 -0300 Subject: [PATCH 526/814] feat: no mostrar comentarios a invitades --- app/views/posts/edit.haml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/posts/edit.haml b/app/views/posts/edit.haml index 2e46590e..e7e0260d 100644 --- a/app/views/posts/edit.haml +++ b/app/views/posts/edit.haml @@ -1,8 +1,9 @@ .row.justify-content-center .col-md-8 - - summary = t('posts.edit.post') - = render 'layouts/details', summary: summary do + - if policy(@site).edit? + = render 'layouts/details', summary: t('posts.edit.post') do + = render 'posts/form', site: @site, post: @post + = render 'layouts/details', summary: t('posts.edit.moderation_queue') do + = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue + - else = render 'posts/form', site: @site, post: @post - - summary = t('posts.edit.moderation_queue') - = render 'layouts/details', summary: summary do - = render 'posts/moderation_queue', site: @site, post: @post, moderation_queue: @moderation_queue From f1de4c80735b106fe4b7951ece4367bb20522bac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 12:32:59 -0300 Subject: [PATCH 527/814] fix: ignorar instancias que ya no existen --- app/jobs/activity_pub/instance_fetch_job.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index ce202092..9c562f7d 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -21,6 +21,16 @@ class ActivityPub instance.update(content: response.parsed_response.object) + break + rescue BRS::BaseError, + Errno::ECONNREFUSED, + HTTParty::Error, + JSON::JSONError, + Net::OpenTimeout, + OpenSSL::OpenSSLError, + SocketError, + Errno::ENETUNREACH => e + ExceptionNotifier.notify_exception(e, data: { instance: uri }) break end end From ee10e170ec6b8c6f939173ee647f874d4770bc3b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:01:36 -0300 Subject: [PATCH 528/814] =?UTF-8?q?fix:=20el=20rol=20todav=C3=ADa=20no=20e?= =?UTF-8?q?st=C3=A1=20guardado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/site_service.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index a3649bc5..6b57fc8b 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -13,7 +13,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do def create self.site = Site.new params - add_role temporal: false, rol: 'usuarie' + role = add_role temporal: false, rol: 'usuarie' site.deploys.build type: 'DeployLocal' # Los sitios de testing no se sincronizan sync_nodes unless site.name.end_with? '.testing' @@ -26,7 +26,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # que no haya estados intermedios. site.locales = [usuarie.lang] + I18n.available_locales - add_role_to_deploys! + add_role_to_deploys! role site.save && site.config.write && @@ -230,9 +230,9 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do private # Asignar un rol a cada deploy si no lo tenía ya - def add_role_to_deploys! + def add_role_to_deploys!(role = current_role) site.deploys.each do |deploy| - deploy.rol ||= current_role + deploy.rol ||= role end end From 670d6063e56922b3a8f8debdbd45fd823c34e38a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:04:52 -0300 Subject: [PATCH 529/814] fix: generar un rol dentro del sitio --- app/services/site_service.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 6b57fc8b..dabce349 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -13,7 +13,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do def create self.site = Site.new params - role = add_role temporal: false, rol: 'usuarie' + role = site.roles.build(usuarie: usuarie, temporal: false, rol: 'usuarie') site.deploys.build type: 'DeployLocal' # Los sitios de testing no se sincronizan sync_nodes unless site.name.end_with? '.testing' @@ -106,11 +106,6 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do GitPushJob.perform_later(site) end - def add_role(temporal: true, rol: 'invitade') - site.roles << Rol.new(site: site, usuarie: usuarie, - temporal: temporal, rol: rol) - end - # Crea la licencia del sitio para cada locale disponible en el sitio # # @return [Boolean] From 7521f598a64df25daac30501029d21171d48f7b1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:45:58 -0300 Subject: [PATCH 530/814] fix: poder deseleccionar todos los fediblocks --- app/controllers/fediblock_states_controller.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/controllers/fediblock_states_controller.rb b/app/controllers/fediblock_states_controller.rb index c116b75a..6d9737c3 100644 --- a/app/controllers/fediblock_states_controller.rb +++ b/app/controllers/fediblock_states_controller.rb @@ -4,14 +4,12 @@ class FediblockStatesController < ApplicationController # Realiza cambios en las listas de bloqueo def action_on_several - if fediblock_states_ids.present? - # Encontrar todas y deshabilitar las que no se enviaron - site.fediblock_states.all.find_each do |fediblock_state| - if fediblock_states_ids.include? fediblock_state.id - fediblock_state.enable! if fediblock_state.may_enable? - elsif fediblock_state.may_disable? - fediblock_state.disable! - end + # Encontrar todas y deshabilitar las que no se enviaron + site.fediblock_states.all.find_each do |fediblock_state| + if fediblock_states_ids.include? fediblock_state.id + fediblock_state.enable! if fediblock_state.may_enable? + elsif fediblock_state.may_disable? + fediblock_state.disable! end end From 15800e1096f01707def8a9c845407b38a9e8d545 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 15:47:40 -0300 Subject: [PATCH 531/814] BREAKING CHANGE: renombrar instancias por hostnames --- app/jobs/activity_pub/fediblock_fetch_job.rb | 6 +++--- app/jobs/activity_pub/fediblock_updated_job.rb | 9 ++++++--- app/models/activity_pub/fediblock.rb | 7 ++++++- app/views/components/_block_list.haml | 2 +- ...0228171335_rename_fediblock_instances_to_hostnames.rb | 9 +++++++++ db/structure.sql | 5 +++-- 6 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb diff --git a/app/jobs/activity_pub/fediblock_fetch_job.rb b/app/jobs/activity_pub/fediblock_fetch_job.rb index aa748bc6..3d12f4cd 100644 --- a/app/jobs/activity_pub/fediblock_fetch_job.rb +++ b/app/jobs/activity_pub/fediblock_fetch_job.rb @@ -11,12 +11,12 @@ class ActivityPub ActivityPub::Fediblock.find_each do |fediblock| fediblock.process! - instances_added = fediblock.instances - fediblock.instances_was + hostnames_added = fediblock.hostnames - fediblock.hostnames_was # No hacer nada si no cambió con respecto a la versión anterior - next if instances_added.empty? + next if hostnames_added.empty? - ActivityPub::FediblockUpdatedJob.perform_later(fediblock: fediblock, hostnames: instances_added) + ActivityPub::FediblockUpdatedJob.perform_later(fediblock: fediblock, hostnames: hostnames_added) rescue ActivityPub::Fediblock::FediblockDownloadError => e ExceptionNotifier.notify_exception(e, data: { fediblock: fediblock.title }) end diff --git a/app/jobs/activity_pub/fediblock_updated_job.rb b/app/jobs/activity_pub/fediblock_updated_job.rb index b4a56609..1bb47517 100644 --- a/app/jobs/activity_pub/fediblock_updated_job.rb +++ b/app/jobs/activity_pub/fediblock_updated_job.rb @@ -2,14 +2,17 @@ # Se encarga de mantener sincronizadas las listas de instancias # de los fediblocks con los sitios que las tengan activadas. +# +# También va a asociar las listas con todos los sitios que tengan la +# Social Inbox habilitada. class ActivityPub class FediblockUpdatedJob < ApplicationJob self.priority = 50 # @param :fediblock [ActivityPub::Fediblock] - # @param :instances [Array] + # @param :hostnames [Array] def perform(fediblock:, hostnames:) - instances = ActivityPub::Instance.where(hostname: instances) + instances = ActivityPub::Instance.where(hostname: hostnames) # Todos los sitios con la Social Inbox habilitada Site.where(id: DeploySocialDistributedPress.pluck(:site_id)).find_each do |site| @@ -19,7 +22,7 @@ class ActivityPub # No hace nada con los deshabilitados next unless fediblock_state.enabled? - ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: instances) + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: hostnames) end end end diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb index 8d024f56..4abcb80f 100644 --- a/app/models/activity_pub/fediblock.rb +++ b/app/models/activity_pub/fediblock.rb @@ -43,6 +43,11 @@ class ActivityPub @client ||= Client.new end + # Todas las instancias de este fediblock + def instances + ActivityPub::Instance.where(hostname: hostnames) + end + # Descarga la lista y crea las instancias con el estado necesario def process! response = client.get(download_url) @@ -53,7 +58,7 @@ class ActivityPub csv = response.parsed_response process_csv! csv - update(instances: csv.map { |r| r[hostname_header] }) + update(hostnames: csv.map { |r| r[hostname_header] }) end end diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 79481363..75825bb0 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -7,6 +7,6 @@ %dl.mb-0 %dt.d-inline= t('.instances_blocked') - %dd.d-inline.font-weight-normal= blocklist.instances.count + %dd.d-inline.font-weight-normal= blocklist.hostnames.count %p.mb-0.font-weight-normal %a{ href: blocklist.url }= know_more diff --git a/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb b/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb new file mode 100644 index 00000000..bad343f2 --- /dev/null +++ b/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Cambia el nombre de la columna para que podamos obtener todas las +# instancias de un fediblock +class RenameFediblockInstancesToHostnames < ActiveRecord::Migration[6.1] + def change + rename_column :activity_pub_fediblocks, :instances, :hostnames + end +end diff --git a/db/structure.sql b/db/structure.sql index ac897695..740f5d87 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -514,7 +514,7 @@ CREATE TABLE public.activity_pub_fediblocks ( url character varying NOT NULL, download_url character varying NOT NULL, format character varying NOT NULL, - instances jsonb DEFAULT '[]'::jsonb + hostnames jsonb DEFAULT '[]'::jsonb ); @@ -2615,6 +2615,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240226133022'), ('20240226134335'), ('20240227134845'), -('20240227142019'); +('20240227142019'), +('20240228171335'); From 1ee41f2d5e9de7dc78f79c7afcb574ff2fa79648 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:04:37 -0300 Subject: [PATCH 532/814] feat: al activar o desactivar un fediblock, vincular con todas las instancias --- app/models/fediblock_state.rb | 28 +++++++++++++++++++++------- app/models/instance_moderation.rb | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 8045e23e..13e31cb2 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -1,6 +1,12 @@ # frozen_string_literal: true -# Relación entre Fediblocks y Sites +# Relación entre Fediblocks y Sites. +# +# Cuando se habilita un Fediblock, tenemos que asociar todas sus +# instancias con el sitio y bloquearlas. Cuando se deshabilita, la +# relación ya está creada y se va actualizando. +# +# @see ActivityPub::FediblockUpdatedJob class FediblockState < ApplicationRecord include AASM @@ -22,6 +28,15 @@ class FediblockState < ApplicationRecord before do enable_remotely! + + # Al actualizar el estado en masa garantizamos que las + # instancias que ya existen queden sincronizadas con el bloqueo + # en masa que acabamos de hacer. + instance_moderations.block_all! + + # Luego esta tarea crea las que falten e ignora las que ya se + # bloquearon. + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames) end end @@ -35,18 +50,17 @@ class FediblockState < ApplicationRecord before do disable_remotely! + + instance_moderations.pause_all! end end end private - # Obtiene todos los IDs de instancias para poder obtener el estado de - # moderación en el sitio. - # - # @return [Array] - def instance_ids - ActivityPub::Instance.where(hostname: fediblock.instances).pluck(:id) + # Todas las instancias de moderación de este sitio + def instance_moderations + site.instance_moderations.where(instance_id: fediblock.instances.pluck(:id)) end # @return [Array] diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 735ec387..d9f74527 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -7,6 +7,21 @@ class InstanceModeration < ApplicationRecord belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' + # Traer todas las instancias bloqueables, según la máquina de estados, + # todas las que no estén bloqueadas ya. + scope :may_block, -> { where.not(aasm_state: 'blocked') } + scope :may_pause, -> { where.not(aasm_state: 'paused') } + + # Bloquear instancias en masa + def self.block_all! + self.may_block.update_all(aasm_state: 'blocked', updated_at: Time.now) + end + + # Pausar instancias en masa + def self.pause_all! + self.may_pause.update_all(aasm_state: 'paused', updated_at: Time.now) + end + aasm do state :paused, initial: true state :allowed From 43d190ba7426ee8cf85e88a6a88b8fd2cebc94b4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:13:51 -0300 Subject: [PATCH 533/814] feat: mostrar la cantidad de instancias --- app/models/instance_moderation.rb | 3 +++ app/views/components/_instances_filters.haml | 2 +- app/views/components/_instances_show_submenu.haml | 6 +++--- app/views/moderation_queue/_instances.haml | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index d9f74527..10b5e8e0 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -11,6 +11,9 @@ class InstanceModeration < ApplicationRecord # todas las que no estén bloqueadas ya. scope :may_block, -> { where.not(aasm_state: 'blocked') } scope :may_pause, -> { where.not(aasm_state: 'paused') } + scope :paused, -> { where(aasm_state: 'paused') } + scope :blocked, -> { where(aasm_state: 'blocked') } + scope :allowed, -> { where(aasm_state: 'allowed') } # Bloquear instancias en masa def self.block_all! diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index eac20d38..fe40ced3 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -3,4 +3,4 @@ = render 'components/instances_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/instances_show_submenu' + = render 'components/instances_show_submenu', site: site diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index 56206735..811d65c7 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,3 +1,3 @@ -= render 'components/dropdown_item', text: t('.submenu_paused'), path: site_moderation_queue_path(state: 'paused') -= render 'components/dropdown_item', text: t('.submenu_allowed'), path: site_moderation_queue_path(state: 'allowed') -= render 'components/dropdown_item', text: t('.submenu_blocked'), path: site_moderation_queue_path(state: 'blocked') += render 'components/dropdown_item', text: t('.submenu_paused', count: site.instance_moderations.paused.count), path: site_moderation_queue_path(state: 'paused') += render 'components/dropdown_item', text: t('.submenu_allowed', count: site.instance_moderations.allowed.count), path: site_moderation_queue_path(state: 'allowed') += render 'components/dropdown_item', text: t('.submenu_blocked', count: site.instance_moderations.blocked.count), path: site_moderation_queue_path(state: 'blocked') diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index d2ebb5a7..65f4350a 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -5,7 +5,7 @@ = render 'components/select_all', id: 'instances' .col-11 -# Filtros - = render 'components/instances_filters' + = render 'components/instances_filters', site: site .col-12 - if instance_moderations.count.zero? From 259d1c1e90d86d12c86aedf5aefdeb3bdad1cbbc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:23:18 -0300 Subject: [PATCH 534/814] =?UTF-8?q?feat:=20optimizar=20acceso=20a=20inform?= =?UTF-8?q?aci=C3=B3n=20y=20ordenar=20por=20hostname?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/processors/instance_moderation_processor.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/processors/instance_moderation_processor.rb b/app/processors/instance_moderation_processor.rb index 414901d6..908beaf7 100644 --- a/app/processors/instance_moderation_processor.rb +++ b/app/processors/instance_moderation_processor.rb @@ -2,6 +2,10 @@ # Gestiona los filtros de InstanceModeration class InstanceModerationProcessor < Rubanok::Processor + prepare do + raw.includes(:instance).order('activity_pub_instances.hostname') + end + map :state, activate_always: true do |state: 'paused'| raw.where(aasm_state: state) end From f9d02cc63eeb38d2b4e8c27e69521a463720eec4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:32:03 -0300 Subject: [PATCH 535/814] =?UTF-8?q?feat:=20recordar=20el=20filtro=20que=20?= =?UTF-8?q?est=C3=A1bamos=20usando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../instance_moderations_controller.rb | 21 +++++++++---------- .../moderation_queue_controller.rb | 2 ++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 67a6be1d..d25e1450 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -3,23 +3,18 @@ # Actualiza la relación entre un sitio y una instancia class InstanceModerationsController < ApplicationController before_action :authorize_policy, except: %i[action_on_several] + around_action :redirect_to_moderation_queue! def pause - instance_moderation.pause! - - redirect_to site_moderation_queue_path + instance_moderation.pause! if instance_moderation.may_pause? end def allow - instance_moderation.allow! - - redirect_to site_moderation_queue_path + instance_moderation.allow! if instance_moderation.may_allow? end def block - instance_moderation.block! - - redirect_to site_moderation_queue_path + instance_moderation.block! if instance_moderation.may_block? end def action_on_several @@ -39,12 +34,16 @@ class InstanceModerationsController < ApplicationController instance_moderation.public_send(method) end end - - redirect_to site_moderation_queue_path end private + def redirect_to_moderation_queue!(&action) + redirect_back fallback_location: site_moderation_queue_path, state: session[:moderation_queue_filtered_by_state] + + yield + end + # @return [InstanceModeration] def instance_moderation @instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id]) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 8c030460..fd7d2acb 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,6 +6,8 @@ class ModerationQueueController < ApplicationController def index dummy_data + session[:moderation_queue_filtered_by_state] = params[:state] + # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) From 448564aa46739bdb72e4d226775993ee6ea55271 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:36:50 -0300 Subject: [PATCH 536/814] =?UTF-8?q?fix:=20hacer=20la=20tarea=20sincr=C3=B3?= =?UTF-8?q?nicamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/fediblock_state.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 13e31cb2..a160c43a 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -36,7 +36,7 @@ class FediblockState < ApplicationRecord # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. - ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames) + ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) end end From 17705f66ad2f0c1a66469393f009e2081ebd50c6 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:42:18 -0300 Subject: [PATCH 537/814] feat: tarjeta cacheada de instancia --- app/views/moderation_queue/_instance.haml | 16 +++++++++------- app/views/moderation_queue/_instances.haml | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index ec76c6e6..73655e1b 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,15 +1,17 @@ +- usuaries = instance.content.dig('usage', 'users', 'active_month') +- usuaries ||= instance.content.dig('stats', 'user_count') + .row.no-gutters.pt-2 .col-1 = render 'components/checkbox', id: instance.hostname, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 - %a{ href: instance.uri }= instance.content['title'] - %p= instance.content['description'].html_safe - %dl - %dt.d-inline= t('.users') - %dd.d-inline - = instance.content.dig('usage', 'users', 'active_month') - = instance.content.dig('stats', 'user_count') + %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname + %p= sanitize instance.content['description'] + - if usuaries.present? + %dl + %dt.d-inline= t('.users') + %dd.d-inline= sanitize usuaries.to_s -# Botones moderación .d-flex.pb-4 diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 65f4350a..a45da354 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -12,8 +12,9 @@ %h3= t('moderation_queue.nothing') - instance_moderations.each do |instance_moderation| - %hr - = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance + - cache [instance_moderation.aasm_state, instance_moderation.instance] do + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance %hr %div From dd20c6ce84881d96704f24a516e9fc2561e535c7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 16:42:39 -0300 Subject: [PATCH 538/814] fixup! feat: mostrar la cantidad de instancias --- config/locales/en.yml | 6 +++--- config/locales/es.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 717c9ece..c6a7d936 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -60,9 +60,9 @@ en: submenu_allow: Allow submenu_block: Block instances_show_submenu: - submenu_paused: Moderated - submenu_allowed: Allowed - submenu_blocked: Blocked + submenu_paused: "Moderated (%{count})" + submenu_allowed: "Allowed (%{count})" + submenu_blocked: "Blocked (%{count})" comments_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index 87111523..b3105220 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -60,9 +60,9 @@ es: submenu_allow: Permitir todo submenu_block: Rechazar todo instances_show_submenu: - submenu_paused: Pausadas - submenu_allowed: Permitidas - submenu_blocked: Bloqueadas + submenu_paused: "Pausadas (%{count})" + submenu_allowed: "Permitidas (%{count})" + submenu_blocked: "Bloqueadas (%{count})" comments_filters: text_show: Ver text_checked: Con los marcados From ef9169c89135259c98d5117b9af4f20179f2b110 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:12:33 -0300 Subject: [PATCH 539/814] =?UTF-8?q?fix:=20traducci=C3=B3n=20faltante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_block_list.haml | 3 ++- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/components/_block_list.haml b/app/views/components/_block_list.haml index 75825bb0..27e44cac 100644 --- a/app/views/components/_block_list.haml +++ b/app/views/components/_block_list.haml @@ -1,12 +1,13 @@ -# Componente Listas de bloqueo de Instancias - know_more = t('.know_more') +- instances_blocked = t('.instances_blocked') .card.mt-3.mb-3 .card-body = render 'components/checkbox', id: state.id, name: 'fediblock_states_ids[]', value: state.id, checked: state.enabled? do %span.h4.mb-0= blocklist.title %dl.mb-0 - %dt.d-inline= t('.instances_blocked') + %dt.d-inline= instances_blocked %dd.d-inline.font-weight-normal= blocklist.hostnames.count %p.mb-0.font-weight-normal %a{ href: blocklist.url }= know_more diff --git a/config/locales/en.yml b/config/locales/en.yml index c6a7d936..aaa5a451 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -52,6 +52,7 @@ en: components: block_list: know_more: Know more + instances_blocked: Instances blocked instances_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index b3105220..8fe01b83 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -52,6 +52,7 @@ es: components: block_list: know_more: Saber más (en inglés) + instances_blocked: Instancias bloqueadas instances_filters: text_show: Ver text_checked: Con los marcados From eafe8bcdd577d817a791552ffb774241bfd34422 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:26:22 -0300 Subject: [PATCH 540/814] feat: poder seleccionar todas las cuentas --- app/views/moderation_queue/_account.haml | 4 ++-- app/views/moderation_queue/_accounts.haml | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 2c929402..27ea30d1 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: profile['id'] + = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } .col-11 %h4 %a{href: profile['id']}= profile['preferredUsername'] @@ -8,4 +8,4 @@ -# Botones de Moderación .d-flex.pb-4 - = render 'components/profiles_btn_box' \ No newline at end of file + = render 'components/profiles_btn_box' diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 2d8e1420..c88a2de6 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,12 +1,10 @@ -.row.no-gutters.pt-2 +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/checkbox', id: moderation_queue.first['id'] + = render 'components/select_all', id: 'actors' .col-11 -# Filtros = render 'components/profiles_filters' - -- @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| - %hr - = render 'account', profile: remote_profile - - + .col-12 + - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| + %hr + = render 'account', profile: remote_profile From f524724c0ffe37830ef305f3ca6fa66f38b2bfbf Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:34:34 -0300 Subject: [PATCH 541/814] feat: moderar actores --- app/models/activity_pub/actor.rb | 1 + app/models/actor_moderation.rb | 32 +++++++++++++++ app/models/site/social_distributed_press.rb | 1 + ...20240228202830_create_actor_moderations.rb | 14 +++++++ db/structure.sql | 39 ++++++++++++++++++- 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 app/models/actor_moderation.rb create mode 100644 db/migrate/20240228202830_create_actor_moderations.rb diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 7a858a7e..92750946 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -10,6 +10,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern belongs_to :instance + has_many :actor_moderation has_many :activity_pubs, as: :object has_many :activities end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb new file mode 100644 index 00000000..69fbf3bd --- /dev/null +++ b/app/models/actor_moderation.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# Mantiene la relación entre Site y Actor +class ActorModeration < ApplicationRecord + include AASM + + belongs_to :site + belongs_to :actor, class_name: 'ActivityPub::Actor' + + aasm do + state :paused, initial: true + state :allowed + state :blocked + state :reported + + event :pause do + transitions from: %i[allowed blocked reported], to: :paused + end + + event :allowed do + transitions from: %i[paused blocked reported], to: :allowed + end + + event :blocked do + transitions from: %i[paused allowed], to: :blocked + end + + event :reported do + transitions from: %i[blocked], to: :reported + end + end +end diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index fdb37bca..e916bf3e 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -12,6 +12,7 @@ class Site has_many :activity_pubs has_many :instance_moderations + has_many :actor_moderations has_many :fediblock_states has_many :instances, through: :instance_moderations diff --git a/db/migrate/20240228202830_create_actor_moderations.rb b/db/migrate/20240228202830_create_actor_moderations.rb new file mode 100644 index 00000000..01460eae --- /dev/null +++ b/db/migrate/20240228202830_create_actor_moderations.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Relación entre Actor y Site +class CreateActorModerations < ActiveRecord::Migration[6.1] + def change + create_table :actor_moderations, id: :uuid do |t| + t.timestamps + + t.belongs_to :site + t.uuid :actor_id, index: true + t.string :aasm_state, null: false + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 740f5d87..e4d39ad0 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -562,6 +562,20 @@ CREATE TABLE public.activity_pubs ( ); +-- +-- Name: actor_moderations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.actor_moderations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + actor_id uuid, + aasm_state character varying NOT NULL +); + + -- -- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: - -- @@ -1756,6 +1770,14 @@ ALTER TABLE ONLY public.activity_pubs ADD CONSTRAINT activity_pubs_pkey PRIMARY KEY (id); +-- +-- Name: actor_moderations actor_moderations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.actor_moderations + ADD CONSTRAINT actor_moderations_pkey PRIMARY KEY (id); + + -- -- Name: blazer_audits blazer_audits_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2107,6 +2129,20 @@ CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_ins CREATE UNIQUE INDEX index_activity_pubs_on_site_id_and_object_id_and_object_type ON public.activity_pubs USING btree (site_id, object_id, object_type); +-- +-- Name: index_actor_moderations_on_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_actor_moderations_on_actor_id ON public.actor_moderations USING btree (actor_id); + + +-- +-- Name: index_actor_moderations_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_actor_moderations_on_site_id ON public.actor_moderations USING btree (site_id); + + -- -- Name: index_blazer_audits_on_query_id; Type: INDEX; Schema: public; Owner: - -- @@ -2616,6 +2652,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240226134335'), ('20240227134845'), ('20240227142019'), -('20240228171335'); +('20240228171335'), +('20240228202830'); From aeb8f884935964ec00e2d213042bea33b13fddb2 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:44:21 -0300 Subject: [PATCH 542/814] =?UTF-8?q?feat:=20crear=20el=20estado=20de=20mode?= =?UTF-8?q?raci=C3=B3n=20si=20no=20existe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 12545915..f52525f1 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -158,6 +158,8 @@ module Api a.save! + site.actor_moderations.find_or_create_by(actor: a) + ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) end end From 6eaf00c7ad1597a2bac9b22e1719f10ad8e70b7b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:52:24 -0300 Subject: [PATCH 543/814] fix: recibir actividades correctamente --- .../api/v1/webhooks/social_inbox_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index f52525f1..34ef1d6c 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -5,6 +5,9 @@ module Api module Webhooks # Recibe webhooks de la Social Inbox # + # @todo Mover todo a un Job que obtenga el objeto remoto antes de + # instanciar el objeto localmente en lugar de arreglarlo después y + # poder responder lo más rápido posible el webhook. # @see {https://www.w3.org/TR/activitypub/} class SocialInboxController < BaseController include Api::V1::Webhooks::Concerns::WebhookConcern @@ -28,6 +31,7 @@ module Api instance.present? object.present? activity_pub.present? + activity.update_activity_pub_state! end rescue ActiveRecord::RecordInvalid => e @@ -125,7 +129,7 @@ module Api # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, object: object) + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object: object) end # Crea la actividad y la vincula con el estado @@ -135,7 +139,7 @@ module Api @activity ||= ActivityPub::Activity .type_from(original_activity) - .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub).tap do |a| + .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup a.content[:object] = object.uri a.save! From 6d9a64f7283a488b59fd32d325acac1ec6a34af9 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 17:58:00 -0300 Subject: [PATCH 544/814] feat: moderar en la social inbox --- app/models/activity_pub/actor.rb | 11 ++++++++++ app/models/actor_moderation.rb | 37 ++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 92750946..a5171815 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -13,5 +13,16 @@ class ActivityPub has_many :actor_moderation has_many :activity_pubs, as: :object has_many :activities + + # Obtiene el nombre de la Actor como mención, solo si obtuvimos el + # contenido de antemano. + # + # @return [String, nil] + def mention + return if content['preferredUsername'].blank? + return if instance.blank? + + @mention ||= "@#{content['preferredUsername']}@#{instance.hostname}" + end end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 69fbf3bd..efbde33b 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -15,18 +15,51 @@ class ActorModeration < ApplicationRecord event :pause do transitions from: %i[allowed blocked reported], to: :paused + + before do + pause_remotely! + end end - event :allowed do + event :allow do transitions from: %i[paused blocked reported], to: :allowed + + before do + allow_remotely! + end end - event :blocked do + event :block do transitions from: %i[paused allowed], to: :blocked + + before do + block_remotely! + end end event :reported do transitions from: %i[blocked], to: :reported end end + + def pause_remotely! + raise AASM::InvalidTransition unless + actor.mention && + site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && + site.social_inbox.blocklist.delete(list: [actor.mention]).ok? + end + + def allow_remotely! + raise AASM::InvalidTransition unless + actor.mention && + site.social_inbox.allowlist.post(list: [actor.mention]).ok? && + site.social_inbox.blocklist.delete(list: [actor.mention]).ok? + end + + def block_remotely! + raise AASM::InvalidTransition unless + actor.mention && + site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && + site.social_inbox.blocklist.post(list: [actor.mention]).ok? + end end From e07da7858e02309f0571428dfd754de0bc38687b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:27:15 -0300 Subject: [PATCH 545/814] =?UTF-8?q?feat:=20cambiar=20a=20orden=20descendie?= =?UTF-8?q?nte=20por=20fecha=20de=20modificaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/processors/actor_moderation_processor.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 app/processors/actor_moderation_processor.rb diff --git a/app/processors/actor_moderation_processor.rb b/app/processors/actor_moderation_processor.rb new file mode 100644 index 00000000..efd12666 --- /dev/null +++ b/app/processors/actor_moderation_processor.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Gestiona los filtros de ActorModeration +class ActorModerationProcessor < Rubanok::Processor + # En orden descendiente para encontrar le últime Actor + prepare do + raw.order(updated_at: :desc) + end + + map :actor_state, activate_always: true do |state: 'paused'| + raw.where(aasm_state: state) + end +end From 0e2f6276eb501b0787442f096fe916dca0bfd4ba Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:31:28 -0300 Subject: [PATCH 546/814] feat: siempre actualizar la fecha de le actore al guardar una actividad --- app/models/activity_pub/activity.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index a220b831..1147c5b8 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -16,7 +16,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern belongs_to :activity_pub - belongs_to :actor + belongs_to :actor, touch: true has_one :object, through: :activity_pub validates :activity_pub_id, presence: true From 25c9963284887f581758d2f524e9b81ab9ed4991 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:35:34 -0300 Subject: [PATCH 547/814] =?UTF-8?q?feat:=20mostrar=20las=20cuentas=20en=20?= =?UTF-8?q?la=20cola=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 1 + app/processors/actor_moderation_processor.rb | 4 ++-- app/views/moderation_queue/_accounts.haml | 4 ++-- app/views/moderation_queue/index.haml | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index fd7d2acb..a9611a1b 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -11,6 +11,7 @@ class ModerationQueueController < ApplicationController # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) + @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) end # Perfil remoto de usuarie diff --git a/app/processors/actor_moderation_processor.rb b/app/processors/actor_moderation_processor.rb index efd12666..a3035654 100644 --- a/app/processors/actor_moderation_processor.rb +++ b/app/processors/actor_moderation_processor.rb @@ -7,7 +7,7 @@ class ActorModerationProcessor < Rubanok::Processor raw.order(updated_at: :desc) end - map :actor_state, activate_always: true do |state: 'paused'| - raw.where(aasm_state: state) + map :actor_state, activate_always: true do |actor_state: 'paused'| + raw.where(aasm_state: actor_state) end end diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index c88a2de6..5630a6d7 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -5,6 +5,6 @@ -# Filtros = render 'components/profiles_filters' .col-12 - - @moderation_queue.map{ |c| c['attributedTo'] }.uniq.each do |remote_profile| + - actor_moderations.find_each do |actor_moderation| %hr - = render 'account', profile: remote_profile + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 0fb1c968..df2c219d 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -9,7 +9,7 @@ %hr - summary = t('.accounts') = render 'layouts/details', summary: summary do - = render 'moderation_queue/accounts', site: @site, post: @post, moderation_queue: @moderation_queue + = render 'moderation_queue/accounts', site: @site, post: @post, actor_moderations: @actor_moderations %hr - summary = t('.comments') = render 'layouts/details', summary: summary do From 2edafc8901a92e81534f3d50ff9c5fea797488ed Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:42:48 -0300 Subject: [PATCH 548/814] feat: ver la cuenta de cuentas por moderar --- app/views/components/_profiles_filters.haml | 4 ++-- app/views/components/_profiles_show_submenu.haml | 7 ++++--- app/views/moderation_queue/_accounts.haml | 2 +- config/locales/en.yml | 9 +++++---- config/locales/es.yml | 9 +++++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index 0088afef..c6397e69 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu' + = render 'components/profiles_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/profiles_show_submenu' \ No newline at end of file + = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 2ba949b1..703e4a15 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,3 +1,4 @@ -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_block'), path: '/' \ No newline at end of file +- ActorModeration.aasm.states.map(&:name).each do |actor_state| + = render 'components/dropdown_item', + text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), + path: site_moderation_queue_path(params.permit(:state, :actor_state).merge(actor_state: actor_state)) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 5630a6d7..44c2893e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -3,7 +3,7 @@ = render 'components/select_all', id: 'actors' .col-11 -# Filtros - = render 'components/profiles_filters' + = render 'components/profiles_filters', actor_moderations: actor_moderations .col-12 - actor_moderations.find_each do |actor_moderation| %hr diff --git a/config/locales/en.yml b/config/locales/en.yml index aaa5a451..c4bff0a9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -85,10 +85,11 @@ en: submenu_reject: Reject submenu_block: Block profiles_show_submenu: - submenu_accept: Accept - submenu_block: Block - submenu_reject: Reject - block_lists: + submenu_paused: "Paused (%{count})" + submenu_allowed: "Allowed (%{count})" + submenu_blocked: "Blocked (%{count})" + submenu_reported: "Reported (%{count})" + block_lists: title: Block lists comments_btn_box: text_pause: Pause diff --git a/config/locales/es.yml b/config/locales/es.yml index 8fe01b83..9409eddd 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -85,10 +85,11 @@ es: submenu_reject: Rechazado submenu_block: Bloqueado profiles_show_submenu: - submenu_accept: Aceptado - submenu_block: Bloqueado - submenu_reject: Rechazado - block_lists: + submenu_paused: "Pausadas (%{count})" + submenu_allowed: "Permitidas (%{count})" + submenu_blocked: "Bloqueadas (%{count})" + submenu_reported: "Reportadas (%{count})" + block_lists: title: Listas de bloqueo comments_btn_box: text_pause: Pausa From 0539eb8f2245d4c8573aa744352f1ea72b9f74ae Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 18:51:41 -0300 Subject: [PATCH 549/814] =?UTF-8?q?feat:=20avisar=20cuando=20no=20se=20enc?= =?UTF-8?q?ontr=C3=B3=20nada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_accounts.haml | 2 ++ app/views/moderation_queue/_instances.haml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 44c2893e..c7dba0a1 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -5,6 +5,8 @@ -# Filtros = render 'components/profiles_filters', actor_moderations: actor_moderations .col-12 + - if actor_moderations.count.zero? + %h4= t('moderation_queue.nothing') - actor_moderations.find_each do |actor_moderation| %hr = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a45da354..77b6adea 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -9,7 +9,7 @@ .col-12 - if instance_moderations.count.zero? - %h3= t('moderation_queue.nothing') + %h4= t('moderation_queue.nothing') - instance_moderations.each do |instance_moderation| - cache [instance_moderation.aasm_state, instance_moderation.instance] do From 5370a542ff52be582e927262ed57c8ffce8da42a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 28 Feb 2024 19:10:37 -0300 Subject: [PATCH 550/814] feat: cambiar el estado de les actores desde el panel --- .../actor_moderations_controller.rb | 20 +++++++++++++++++++ .../moderation_queue_controller.rb | 2 +- app/models/actor_moderation.rb | 6 +++++- app/policies/actor_moderation_policy.rb | 16 +++++++++++++++ app/views/components/_profiles_btn_box.haml | 10 ++++++---- app/views/moderation_queue/_account.haml | 7 ++++--- config/locales/en.yml | 6 +++--- config/locales/es.yml | 6 +++--- 8 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 app/controllers/actor_moderations_controller.rb create mode 100644 app/policies/actor_moderation_policy.rb diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb new file mode 100644 index 00000000..543ca74d --- /dev/null +++ b/app/controllers/actor_moderations_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# Gestiona la cola de moderación de actores +class ActorModerationsController < ApplicationController + ActorModeration.aasm.events.map(&:name).each do |actor_event| + define_method(actor_event) do + authorize actor_moderation + + actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") + + redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + end + end + + private + + def actor_moderation + @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id]) + end +end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index a9611a1b..df36dfbe 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,7 +6,7 @@ class ModerationQueueController < ApplicationController def index dummy_data - session[:moderation_queue_filtered_by_state] = params[:state] + session[:moderation_queue_filters] = params.permit(:state, :actor_state) # @todo cambiar el estado por query @activity_pubs = site.activity_pubs diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index efbde33b..f186dd69 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -7,6 +7,10 @@ class ActorModeration < ApplicationRecord belongs_to :site belongs_to :actor, class_name: 'ActivityPub::Actor' + def self.events + aasm.events.map(&:name) + end + aasm do state :paused, initial: true state :allowed @@ -37,7 +41,7 @@ class ActorModeration < ApplicationRecord end end - event :reported do + event :report do transitions from: %i[blocked], to: :reported end end diff --git a/app/policies/actor_moderation_policy.rb b/app/policies/actor_moderation_policy.rb new file mode 100644 index 00000000..07a9a752 --- /dev/null +++ b/app/policies/actor_moderation_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Solo les usuaries pueden moderar actores +ActorModerationPolicy = Struct.new(:usuarie, :actor_moderation) do + ActorModeration.events.each do |actor_event| + define_method(:"#{actor_event}?") do + actor_moderation.site.usuarie? usuarie + end + end + + # En este paso tenemos varias cuentas por moderar pero todas son + # del mismo sitio. + def action_on_several? + actor_moderation.first.site.usuarie? usuarie + end +end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 06faa8a1..bc1fd7e4 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,7 +1,9 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) - btn_class = 'btn-secondary' -= render 'components/btn_base', text: t('.text_approve'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_check'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file +- ActorModeration.events.each do |actor_event| + = render 'components/btn_base', + text: t(".text_#{actor_event}"), + path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), + class: btn_class, + disabled: !actor_moderation.public_send(:"may_#{actor_event}?") diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 27ea30d1..24fbb270 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -3,9 +3,10 @@ = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } .col-11 %h4 - %a{href: profile['id']}= profile['preferredUsername'] - =profile['summary'].html_safe + %a{href: profile['id']}= sanitize profile['name'] + .mb-3 + = sanitize profile['summary'].html_safe -# Botones de Moderación .d-flex.pb-4 - = render 'components/profiles_btn_box' + = render 'components/profiles_btn_box', actor_moderation: actor_moderation diff --git a/config/locales/en.yml b/config/locales/en.yml index c4bff0a9..3c8e8851 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -102,9 +102,9 @@ en: text_allow: Allow everything text_deny: Block instance profiles_btn_box: - text_approve: Always approve - text_check: Always check - text_deny: Block + text_pause: Always check + text_allow: Always approve + text_block: Block text_report: Report moderation_queue: everything: 'Select all' diff --git a/config/locales/es.yml b/config/locales/es.yml index 9409eddd..d2c30ef6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -102,9 +102,9 @@ es: text_allow: Permitir todo text_deny: Bloquear instancia profiles_btn_box: - text_approve: Aprobar siempre - text_check: Revisar siempre - text_deny: Bloquear + text_pause: Revisar siempre + text_allow: Aprobar siempre + text_block: Bloquear text_report: Reportar moderation_queue: everything: 'Seleccionar todo' From cf46988d9db2aa34bb26ae5dbd521923da28ed23 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 15:53:32 -0300 Subject: [PATCH 551/814] fixup! feat: cambiar el estado de les actores desde el panel --- app/views/actor_moderations/show.haml | 4 ++++ config/routes.rb | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 app/views/actor_moderations/show.haml diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml new file mode 100644 index 00000000..ba0fc257 --- /dev/null +++ b/app/views/actor_moderations/show.haml @@ -0,0 +1,4 @@ +.row.justify-content-center + .col-md-8 + %h1= t('.profile') + = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/config/routes.rb b/config/routes.rb index d70f8339..f6b412e2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -71,6 +71,12 @@ Rails.application.routes.draw do patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' patch :fediblock_states_action_on_several, to: 'fediblock_states#action_on_several' + resources :actor_moderations, only: [] do + ActorModeration.events.each do |actor_event| + patch actor_event, to: "actor_moderations##{actor_event}" + end + end + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From 3ba23a8b8c49ae25accd7bbcfaef99f6779d8a05 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 15:54:53 -0300 Subject: [PATCH 552/814] feat: poder ir al perfil desde la lista --- .../actor_moderations_controller.rb | 7 ++++- .../moderation_queue_controller.rb | 5 ---- app/views/actor_moderations/show.haml | 8 +++-- app/views/components/_actor.haml | 21 ++++++++++++++ app/views/components/_profiles_btn_box.haml | 15 +++++----- app/views/moderation_queue/_account.haml | 2 +- .../moderation_queue/_remote_profile.haml | 29 ------------------- .../moderation_queue/remote_profile.haml | 4 --- config/locales/en.yml | 17 ++++++----- config/locales/es.yml | 17 ++++++----- config/routes.rb | 3 +- 11 files changed, 61 insertions(+), 67 deletions(-) create mode 100644 app/views/components/_actor.haml delete mode 100644 app/views/moderation_queue/_remote_profile.haml delete mode 100644 app/views/moderation_queue/remote_profile.haml diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 543ca74d..f4637d70 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -12,9 +12,14 @@ class ActorModerationsController < ApplicationController end end + # Ver el perfil remoto + def show + @remote_profile = actor_moderation.actor.content + end + private def actor_moderation - @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id]) + @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index df36dfbe..95639b35 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -14,11 +14,6 @@ class ModerationQueueController < ApplicationController @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) end - # Perfil remoto de usuarie - def remote_profile - dummy_data - end - # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml index ba0fc257..7b62f672 100644 --- a/app/views/actor_moderations/show.haml +++ b/app/views/actor_moderations/show.haml @@ -1,4 +1,8 @@ .row.justify-content-center - .col-md-8 + .col-12.col-md-8 %h1= t('.profile') - = render 'moderation_queue/remote_profile', remote_profile: @remote_profile + = render 'components/actor', remote_profile: @remote_profile + .col-12.col-md-8 + = render 'components/profiles_btn_box', actor_moderation: @actor_moderation + -# + = render 'moderation_queue/comments', moderation_queue: @moderation_queue diff --git a/app/views/components/_actor.haml b/app/views/components/_actor.haml new file mode 100644 index 00000000..f5d6efae --- /dev/null +++ b/app/views/components/_actor.haml @@ -0,0 +1,21 @@ +-# Componente Remote_Profile + +.py-2 + %dl + %dt= t('.profile_name') + %dd= sanitize remote_profile['name'] + + %dt= t('.preferred_name') + %dd= sanitize remote_profile['preferredUsername'] + + %dt= t('.profile_id') + %dd + = link_to sanitize(remote_profile['id']) + + - if remote_profile['published'].present? + %dt= t('.profile_published') + %dd + = render 'layouts/time', time: sanitize(remote_profile['published']) + %dt= t('.profile_summary') + %dd + = sanitize remote_profile['summary'] diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index bc1fd7e4..bd994f84 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,9 +1,10 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) -- btn_class = 'btn-secondary' -- ActorModeration.events.each do |actor_event| - = render 'components/btn_base', - text: t(".text_#{actor_event}"), - path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), - class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?") +.d-flex.flex-row + - btn_class = 'btn-secondary' + - ActorModeration.events.each do |actor_event| + = render 'components/btn_base', + text: t(".text_#{actor_event}"), + path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), + class: btn_class, + disabled: !actor_moderation.public_send(:"may_#{actor_event}?") diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 24fbb270..cdcc0ad4 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -3,7 +3,7 @@ = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } .col-11 %h4 - %a{href: profile['id']}= sanitize profile['name'] + = link_to sanitize(profile['name']), site_actor_moderation_path(id: actor_moderation) .mb-3 = sanitize profile['summary'].html_safe diff --git a/app/views/moderation_queue/_remote_profile.haml b/app/views/moderation_queue/_remote_profile.haml deleted file mode 100644 index 92cf8e96..00000000 --- a/app/views/moderation_queue/_remote_profile.haml +++ /dev/null @@ -1,29 +0,0 @@ --# Componente Remote_Profile - -.flex.py-2.mx-2 - %dl - %dt= t('.profile_name') - %dd= remote_profile['name'] - - %dt= t('.preferred_name') - %dd= remote_profile['preferredUsername'] - - %dt= t('.profile_id') - %dd - %a{ href: 'https://mastodon.mauve.moe/users/mauve' }= remote_profile['id'] - - %dt= t('.profile_published') - %dd - = render 'layouts/time', time: remote_profile['published'] - %dt= t('.profile_summary') - %dd - %p= remote_profile['summary'].html_safe - - = render 'moderation_queue/comments', moderation_queue: @moderation_queue - -%dl.mt-5 - %dt= t('.profile_name') - %dd= remote_profile['name'] - --# Botones de Moderación -= render 'components/profiles_btn_box' diff --git a/app/views/moderation_queue/remote_profile.haml b/app/views/moderation_queue/remote_profile.haml deleted file mode 100644 index ba0fc257..00000000 --- a/app/views/moderation_queue/remote_profile.haml +++ /dev/null @@ -1,4 +0,0 @@ -.row.justify-content-center - .col-md-8 - %h1= t('.profile') - = render 'moderation_queue/remote_profile', remote_profile: @remote_profile diff --git a/config/locales/en.yml b/config/locales/en.yml index 3c8e8851..62e9a1a7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,6 +106,15 @@ en: text_allow: Always approve text_block: Block text_report: Report + actor_moderations: + show: + user: Username + profile: Profile + profile_name: Profile name + preferred_name: Name in Fediverse + profile_id: ID + profile_published: Published + profile_summary: Summary moderation_queue: everything: 'Select all' nothing: "There's nothing for this filter" @@ -117,14 +126,6 @@ en: comment: source_profile: Source Profile reply_to: Reply to - remote_profile: - user: Username - profile: Profile - profile_name: Profile name - preferred_name: Name in Fediverse - profile_id: ID - profile_published: Published - profile_summary: Summary instances: title: My block lists description: Description diff --git a/config/locales/es.yml b/config/locales/es.yml index d2c30ef6..3dc68d98 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,6 +106,15 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar + actor_moderations: + show: + user: Nombre de usuarie + profile: Cuenta de Origen + profile_name: Nombre de la cuenta + preferred_name: Nombre en el Fediverso + profile_id: ID + profile_published: Publicada + profile_summary: Presentación moderation_queue: everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' @@ -117,14 +126,6 @@ es: comment: source_profile: Cuenta de Origen reply_to: En respuesta a - remote_profile: - user: Nombre de usuario - profile: Cuenta de Origen - profile_name: Nombre de la Cuenta - preferred_name: Nombre en el Fediverso - profile_id: ID - profile_published: Publicada - profile_summary: Presentación instances: title: Mis listas de bloqueo description: Descripción de listas de bloqueo diff --git a/config/routes.rb b/config/routes.rb index f6b412e2..ceffcd26 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -59,7 +59,6 @@ Rails.application.routes.draw do post 'collaborate', to: 'collaborations#accept_collaboration' get 'moderation_queue', to: 'moderation_queue#index' - get 'remote_profile', to: 'moderation_queue#remote_profile' get 'instances', to: 'moderation_queue#instances' resources :instance_moderations, only: [] do @@ -71,7 +70,7 @@ Rails.application.routes.draw do patch :instance_moderations_action_on_several, to: 'instance_moderations#action_on_several' patch :fediblock_states_action_on_several, to: 'fediblock_states#action_on_several' - resources :actor_moderations, only: [] do + resources :actor_moderations, only: %i[show] do ActorModeration.events.each do |actor_event| patch actor_event, to: "actor_moderations##{actor_event}" end From cbba822f31b12d5607210aa2dec749915d8184c7 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 16:27:48 -0300 Subject: [PATCH 553/814] feat: recordar el estado del details --- .../controllers/details_controller.js | 17 +++++++++++++++++ app/views/layouts/_details.haml | 9 +++++++-- app/views/moderation_queue/index.haml | 9 +++------ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 app/javascript/controllers/details_controller.js diff --git a/app/javascript/controllers/details_controller.js b/app/javascript/controllers/details_controller.js new file mode 100644 index 00000000..57935e1e --- /dev/null +++ b/app/javascript/controllers/details_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = []; + + connect() { + const state = window.sessionStorage.getItem(this.element.id); + + if (state === "open") { + this.element.setAttribute("open", true); + } + } + + store(event = undefined) { + window.sessionStorage.setItem(this.element.id, event.newState); + } +} diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 99ba4894..ce38bddd 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -1,6 +1,11 @@ --# Detail Cola de Moderación +-# + Detail Cola de Moderación -%details.details.py-2 + @param :id [String] El ID opcional sirve para mantener el historial de + cuál estaba abierto y recuperarlo al cargar la página + @param :summary [String] El resumen + +%details.details.py-2{ id: local_assigns[:id], data: { controller: 'details', action: 'toggle->details#store' } } %summary .row .col-11.pr-2 diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index df2c219d..799fc641 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -3,14 +3,11 @@ %h1= t('.title') .row .col - - summary = t('.instances') - = render 'layouts/details', summary: summary do + = render 'layouts/details', id: 'summary', summary: t('.instances') do = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations, fediblock_states: @site.fediblock_states %hr - - summary = t('.accounts') - = render 'layouts/details', summary: summary do + = render 'layouts/details', id: 'accounts', summary: t('.accounts') do = render 'moderation_queue/accounts', site: @site, post: @post, actor_moderations: @actor_moderations %hr - - summary = t('.comments') - = render 'layouts/details', summary: summary do + = render 'layouts/details', id: 'comments', summary: t('.comments') do = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue From 6c61aec60e177d522e0dacd7d50152c6ec72b5d0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Feb 2024 16:45:06 -0300 Subject: [PATCH 554/814] feat: al modificar un fediblock, cambiar el estado a todes les actores --- app/models/actor_moderation.rb | 12 ++++++++++++ app/models/fediblock_state.rb | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index f186dd69..1d9bae5d 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -7,6 +7,18 @@ class ActorModeration < ApplicationRecord belongs_to :site belongs_to :actor, class_name: 'ActivityPub::Actor' + # Bloquea todes les Actores bloqueables + def self.block_all! + self.update_all(aasm_state: 'blocked', updated_at: Time.now) + end + + def self.pause_all! + self.update_all(aasm_state: 'paused', updated_at: Time.now) + end + + # Todos los eventos de la máquina de estados + # + # @return [Array] def self.events aasm.events.map(&:name) end diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index a160c43a..180a45b5 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -37,6 +37,11 @@ class FediblockState < ApplicationRecord # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) + + # Bloquear a todes les Actores de las instancias bloqueadas para + # indicarle a le usuarie que les tiene que desbloquear + # manualmente. + ActorModeration.where(actor_id: actor_ids).paused.block_all! end end @@ -52,15 +57,27 @@ class FediblockState < ApplicationRecord disable_remotely! instance_moderations.pause_all! + + # Volver a pausar todes les actores de esta instancia que fueron + # bloqueades. + ActorModeration.where(actor_id: actor_ids).blocked.pause_all! end end end private + def actor_ids + ActivityPub::Actor.where(instance_id: instance_ids).pluck(:id) + end + + def instance_ids + fediblock.instances.pluck(:id) + end + # Todas las instancias de moderación de este sitio def instance_moderations - site.instance_moderations.where(instance_id: fediblock.instances.pluck(:id)) + site.instance_moderations.where(instance_id: instance_ids) end # @return [Array] From 6c3b2ab022b50bb15753d5acdd584f76239142d3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 1 Mar 2024 12:19:51 -0300 Subject: [PATCH 555/814] fix: movido metodo lfs_cleanup en cleanup_service.rb a site::repository --- app/models/site/repository.rb | 5 +++++ app/services/cleanup_service.rb | 10 ++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index acbf6553..58baa5dd 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -235,5 +235,10 @@ class Site r&.success? end + + def lfs_cleanup + site.repository.git_sh("git", "lfs", "prune") + site.repository.git_sh("git", "lfs", "dedup") + end end end diff --git a/app/services/cleanup_service.rb b/app/services/cleanup_service.rb index 28f6f860..e53fbcb4 100644 --- a/app/services/cleanup_service.rb +++ b/app/services/cleanup_service.rb @@ -31,7 +31,7 @@ class CleanupService site.deploys.find_each(&:cleanup!) site.repository.gc - lfs_cleanup + site.repository.lfs_cleanup site.touch end end @@ -46,14 +46,8 @@ class CleanupService Rails.logger.info "Limpiando repositorio git de #{site.name}" site.repository.gc - lfs_cleanup + site.repository.lfs_cleanup site.touch end end - - private - def lfs_cleanup - site.repository.git_sh("git", "lfs", "prune") - site.repository.git_sh("git", "lfs", "dedup") - end end From 291c477aec286e4cbefca321604c91cdf428c65a Mon Sep 17 00:00:00 2001 From: jazzari Date: Fri, 1 Mar 2024 13:11:04 -0300 Subject: [PATCH 556/814] fix: corregido metodo lfs_cleanup --- app/models/site/repository.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 58baa5dd..687ced12 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -237,8 +237,8 @@ class Site end def lfs_cleanup - site.repository.git_sh("git", "lfs", "prune") - site.repository.git_sh("git", "lfs", "dedup") + git_sh("git", "lfs", "prune") + git_sh("git", "lfs", "dedup") end end end From 67d9731b1e37606f6b150704fd9d853b6caf34e3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 15:04:07 -0300 Subject: [PATCH 557/814] feat: enviar reportes remotos --- .../activity_pub/remote_flags_controller.rb | 27 +++++++++++ app/jobs/activity_pub/remote_flag_job.rb | 25 ++++++++++ app/models/activity_pub/actor.rb | 1 + app/models/deploy_social_distributed_press.rb | 9 +--- app/models/site/social_distributed_press.rb | 8 ++++ app/models/social_inbox.rb | 26 ++++++++--- config/routes.rb | 4 ++ ...201155_create_activity_pub_remote_flags.rb | 16 +++++++ db/structure.sql | 46 ++++++++++++++++++- 9 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 app/controllers/api/v1/activity_pub/remote_flags_controller.rb create mode 100644 app/jobs/activity_pub/remote_flag_job.rb create mode 100644 db/migrate/20240229201155_create_activity_pub_remote_flags.rb diff --git a/app/controllers/api/v1/activity_pub/remote_flags_controller.rb b/app/controllers/api/v1/activity_pub/remote_flags_controller.rb new file mode 100644 index 00000000..23245b8b --- /dev/null +++ b/app/controllers/api/v1/activity_pub/remote_flags_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Api + module V1 + module ActivityPub + # Devuelve los reportes remotos hechos + # + # @todo Verificar la firma. Por ahora no es necesario porque no es + # posible obtener remotamente todos los reportes y se identifican por + # UUIDv4. + class RemoteFlagsController < BaseController + skip_forgery_protection + + def show + render json: (remote_flag&.content || {}), content_type: 'application/activity+json' + end + + private + + # @return [ActivityPub::RemoteFlag,nil] + def remote_flag + @remote_flag ||= ::ActivityPub::RemoteFlag.find(params[:id]) + end + end + end + end +end diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb new file mode 100644 index 00000000..332d31ac --- /dev/null +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# Envía un reporte directamente a la instancia remota +# +# @todo El panel debería ser su propia instancia y firmar sus propios +# mensajes. +# @todo Como la Social Inbox no soporta enviar actividades +# a destinataries que no sean seguidores, enviamos el reporte +# directamente a la instancia. +# @see {https://github.com/hyphacoop/social.distributed.press/issues/14} +class ActivityPub + class RemoteFlagJob < ApplicationJob + self.priority = 30 + + def perform(remote_flag:) + client = remote_flag.site.social_inbox.client_for(remote_flag.actor.content['inbox']) + response = client.post(endpoint: '', body: remote_flag.content) + + raise 'No se pudo enviar el reporte' unless response.ok? + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response }) + raise + end + end +end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index a5171815..fe6052bf 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -13,6 +13,7 @@ class ActivityPub has_many :actor_moderation has_many :activity_pubs, as: :object has_many :activities + has_many :remote_flags # Obtiene el nombre de la Actor como mención, solo si obtuvimos el # contenido de antemano. diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 9f968f36..eec8189b 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -58,13 +58,6 @@ class DeploySocialDistributedPress < Deploy private - # Obtiene el hostname de la API de Sutty - # - # @return [String] - def api_hostname - Rails.application.routes.default_url_options[:host].sub('panel', 'api') - end - # Crea los hooks en la Social Inbox para que nos avise de actividades # nuevas # @@ -80,7 +73,7 @@ class DeploySocialDistributedPress < Deploy webhook_class.new.call({ method: 'POST', url: Rails.application.routes.url_helpers.public_send( - event_url, site_id: site.name, host: api_hostname + event_url, site_id: site.name, host: site.social_inbox_hostname ), headers: { 'X-Social-Inbox': rol.token diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index e916bf3e..0716a670 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -15,6 +15,7 @@ class Site has_many :actor_moderations has_many :fediblock_states has_many :instances, through: :instance_moderations + has_many :remote_flags, class_name: 'ActivityPub::RemoteFlag' before_save :generate_private_key_pem!, unless: :private_key_pem? @@ -23,6 +24,13 @@ class Site @social_inbox ||= SocialInbox.new(site: self) end + # Obtiene el hostname de la API de Sutty + # + # @return [String] + def social_inbox_hostname + Rails.application.routes.default_url_options[:host].sub('panel', 'api') + end + private # Genera la llave privada y la almacena diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 6677a320..183ebfb0 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -37,13 +37,25 @@ class SocialInbox # @return [DistributedPress::V1::Social::Client] def client - @client ||= DistributedPress::V1::Social::Client.new( - url: site.config.dig('activity_pub', 'url'), - public_key_url: public_key_url, - private_key_pem: site.private_key_pem, - logger: Rails.logger, - cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER']) - ) + @client ||= client_for site.config.dig('activity_pub', 'url') + end + + # Permite enviar mensajes directo a otro servidor + # + # @param url [String] + # @return [DistributedPress::V1::Social::Client] + def client_for(url) + raise "Falló generar un cliente" if url.blank? + + @client_for ||= {} + @client_for[url] ||= + DistributedPress::V1::Social::Client.new( + url: url, + public_key_url: public_key_url, + private_key_pem: site.private_key_pem, + logger: Rails.logger, + cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER']) + ) end # @return [DistributedPress::V1::Social::Inbox] diff --git a/config/routes.rb b/config/routes.rb index ceffcd26..32936d42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,10 @@ Rails.application.routes.draw do namespace :v1 do resources :csp_reports, only: %i[create] + namespace :activity_pub do + resources :remote_flags, only: %i[show] + end + resources :sites, only: %i[index], constraints: { site_id: /[a-z0-9\-.]+/, id: /[a-z0-9\-.]+/ } do get :'invitades/cookie', to: 'invitades#cookie' post :'posts/:layout', to: 'posts#create', as: :posts diff --git a/db/migrate/20240229201155_create_activity_pub_remote_flags.rb b/db/migrate/20240229201155_create_activity_pub_remote_flags.rb new file mode 100644 index 00000000..c60aca22 --- /dev/null +++ b/db/migrate/20240229201155_create_activity_pub_remote_flags.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Lleva el registro de reportes remotos +class CreateActivityPubRemoteFlags < ActiveRecord::Migration[6.1] + def change + create_table :activity_pub_remote_flags, id: :uuid do |t| + t.timestamps + t.belongs_to :site + t.uuid :actor_id, index: true + + t.text :message + + t.index %i[site_id actor_id], unique: true + end + end +end diff --git a/db/structure.sql b/db/structure.sql index e4d39ad0..6cdb49f1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -546,6 +546,20 @@ CREATE TABLE public.activity_pub_objects ( ); +-- +-- Name: activity_pub_remote_flags; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.activity_pub_remote_flags ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + site_id bigint, + actor_id uuid, + message text +); + + -- -- Name: activity_pubs; Type: TABLE; Schema: public; Owner: - -- @@ -1762,6 +1776,14 @@ ALTER TABLE ONLY public.activity_pub_objects ADD CONSTRAINT activity_pub_objects_pkey PRIMARY KEY (id); +-- +-- Name: activity_pub_remote_flags activity_pub_remote_flags_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.activity_pub_remote_flags + ADD CONSTRAINT activity_pub_remote_flags_pkey PRIMARY KEY (id); + + -- -- Name: activity_pubs activity_pubs_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -2122,6 +2144,27 @@ CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USIN CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname); +-- +-- Name: index_activity_pub_remote_flags_on_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_remote_flags_on_actor_id ON public.activity_pub_remote_flags USING btree (actor_id); + + +-- +-- Name: index_activity_pub_remote_flags_on_site_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_activity_pub_remote_flags_on_site_id ON public.activity_pub_remote_flags USING btree (site_id); + + +-- +-- Name: index_activity_pub_remote_flags_on_site_id_and_actor_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_activity_pub_remote_flags_on_site_id_and_actor_id ON public.activity_pub_remote_flags USING btree (site_id, actor_id); + + -- -- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: - -- @@ -2653,6 +2696,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240227134845'), ('20240227142019'), ('20240228171335'), -('20240228202830'); +('20240228202830'), +('20240229201155'); From 3fa19ee8b042e5e0a35481450ba07f3d734f3392 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 15:51:54 -0300 Subject: [PATCH 558/814] feat: reportar desde el panel --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- .../actor_moderations_controller.rb | 12 ++++++++++- app/models/activity_pub/remote_flag.rb | 20 +++++++++++++++++++ app/models/actor_moderation.rb | 9 +++++++++ app/views/components/_profiles_btn_box.haml | 11 +++++++++- app/views/moderation_queue/_account.haml | 5 +++-- config/locales/en.yml | 1 + config/locales/es.yml | 1 + ...224_add_remote_flag_to_actor_moderation.rb | 18 +++++++++++++++++ db/structure.sql | 6 ++++-- 11 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 app/models/activity_pub/remote_flag.rb create mode 100644 db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb diff --git a/Gemfile b/Gemfile index d720a2d6..f4125f65 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'devise-i18n' gem 'devise_invitable' gem 'redis-client' gem 'hiredis-client' -gem 'distributed-press-api-client', '~> 0.4.0rc2' +gem 'distributed-press-api-client', '~> 0.4.0rc3' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 72a30af1..366b58a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,12 +166,12 @@ GEM devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.4.0rc2) + distributed-press-api-client (0.4.0rc3) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema httparty (~> 0.18) - httparty-cache (~> 0.0.4) + httparty-cache (~> 0.0.6) json (~> 2.1, >= 2.1.0) jwt (~> 2.6.0) dotenv (2.8.1) @@ -272,7 +272,7 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - httparty-cache (0.0.5) + httparty-cache (0.0.6) httparty (~> 0.18) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -626,7 +626,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.4.0rc2) + distributed-press-api-client (~> 0.4.0rc3) dotenv-rails down ed25519 diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index f4637d70..7450835b 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -2,10 +2,13 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController - ActorModeration.aasm.events.map(&:name).each do |actor_event| + ActorModeration.events.each do |actor_event| define_method(actor_event) do authorize actor_moderation + # Crea una RemoteFlag si se envían los parámetros adecuados + actor_moderation.update(actor_moderation_params) if actor_event == :report + actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) @@ -22,4 +25,11 @@ class ActorModerationsController < ApplicationController def actor_moderation @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end + + def actor_moderation_params + params.require(:actor_moderation).permit(remote_flag_attributes: %i[message]).tap do |p| + p[:remote_flag_attributes][:site_id] = actor_moderation.site_id + p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id + end + end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb new file mode 100644 index 00000000..b790c4b1 --- /dev/null +++ b/app/models/activity_pub/remote_flag.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class ActivityPub + class RemoteFlag < ApplicationRecord + belongs_to :actor + belongs_to :site + + # Genera la actividad a enviar + def content + { + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => Rails.application.routes.url_helpers.v1_activity_pub_remote_flag_url(self, host: site.social_inbox_hostname), + 'type' => 'Flag', + 'actor' => ENV.fetch('PANEL_ACTOR_ID') { "https://#{ENV['SUTTY']}/about.jsonld" }, + 'content' => message.to_s, + 'object' => [ actor.uri ] + } + end + end +end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 1d9bae5d..c6f8bfc0 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -5,8 +5,11 @@ class ActorModeration < ApplicationRecord include AASM belongs_to :site + belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' belongs_to :actor, class_name: 'ActivityPub::Actor' + accepts_nested_attributes_for :remote_flag + # Bloquea todes les Actores bloqueables def self.block_all! self.update_all(aasm_state: 'blocked', updated_at: Time.now) @@ -53,8 +56,14 @@ class ActorModeration < ApplicationRecord end end + # Al reportar, necesitamos asociar una RemoteFlag para poder + # enviarla. event :report do transitions from: %i[blocked], to: :reported + + before do + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + end end end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index bd994f84..3ec95e59 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,5 +1,13 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) +- form_params = {} +- form_params[:report] = { actor_moderation: { remote_flag_attributes: { message: '' } } } +- I18n.available_locales.each do |locale| + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t(locale) + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += ': ' + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t('.report_message', locale: locale, panel_actor_mention: ENV.fetch('PANEL_ACTOR_MENTION') { '@sutty@sutty.nl' }) + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += '\n\n' + .d-flex.flex-row - btn_class = 'btn-secondary' - ActorModeration.events.each do |actor_event| @@ -7,4 +15,5 @@ text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?") + disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), + params: form_params[actor_event] diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index cdcc0ad4..5e574c71 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -8,5 +8,6 @@ = sanitize profile['summary'].html_safe -# Botones de Moderación - .d-flex.pb-4 - = render 'components/profiles_btn_box', actor_moderation: actor_moderation + - cache actor_moderation do + .d-flex.pb-4 + = render 'components/profiles_btn_box', actor_moderation: actor_moderation diff --git a/config/locales/en.yml b/config/locales/en.yml index 62e9a1a7..4aea89f7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,6 +106,7 @@ en: text_allow: Always approve text_block: Block text_report: Report + report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." actor_moderations: show: user: Username diff --git a/config/locales/es.yml b/config/locales/es.yml index 3dc68d98..7b033859 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,6 +106,7 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar + report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." actor_moderations: show: user: Nombre de usuarie diff --git a/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb b/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb new file mode 100644 index 00000000..63e4ce1b --- /dev/null +++ b/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Las acciones de moderación pueden tener un reporte remoto asociado +class AddRemoteFlagToActorModeration < ActiveRecord::Migration[6.1] + def up + add_column :actor_moderations, :remote_flag_id, :uuid, null: true + + ActivityPub::RemoteFlag.all.find_each do |remote_flag| + actor_moderation = ActorModeration.find_by(actor_id: remote_flag.actor_id) + + actor_moderation&.update_column(:remote_flag_id, remote_flag.id) + end + end + + def down + remove_column :actor_moderations, :remote_flag_id + end +end diff --git a/db/structure.sql b/db/structure.sql index 6cdb49f1..38a56b46 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -586,7 +586,8 @@ CREATE TABLE public.actor_moderations ( updated_at timestamp(6) without time zone NOT NULL, site_id bigint, actor_id uuid, - aasm_state character varying NOT NULL + aasm_state character varying NOT NULL, + remote_flag_id uuid ); @@ -2697,6 +2698,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240227142019'), ('20240228171335'), ('20240228202830'), -('20240229201155'); +('20240229201155'), +('20240301181224'); From f8b45866336c097267261bc34c80bfb5afd1e4d5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:11:33 -0300 Subject: [PATCH 559/814] feat: poder cambiar el estado a varies actores --- .../actor_moderations_controller.rb | 18 +++++++++++++ .../components/_profiles_checked_submenu.haml | 6 ++--- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_accounts.haml | 26 ++++++++++--------- config/locales/en.yml | 4 +-- config/locales/es.yml | 8 +++--- config/routes.rb | 2 ++ 7 files changed, 43 insertions(+), 23 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 7450835b..907f21c6 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -20,6 +20,24 @@ class ActorModerationsController < ApplicationController @remote_profile = actor_moderation.actor.content end + def action_on_several + actor_moderations = site.actor_moderations.where(id: params[:actor_moderation]) + + authorize actor_moderations + + action = params[:actor_moderation_action].to_sym + method = :"#{action}!" + may = :"may_#{action}?" + + return unless ActorModeration.events.include? action + + ActorModeration.transaction do + actor_moderations.find_each do |actor_moderation| + actor_moderation.public_send(method) if actor_moderation.public_send(may) + end + end + end + private def actor_moderation diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index 8d8f8940..c0b99aa5 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,4 +1,2 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_block'), path: '/' +- ActorModeration.events.each do |actor_event| + = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 5e574c71..e891b4ad 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: profile['id'], name: 'actor[]', value: profile['id'], data: { target: 'select-all.input' } + = render 'components/checkbox', id: actor_moderation.id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 = link_to sanitize(profile['name']), site_actor_moderation_path(id: actor_moderation) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index c7dba0a1..35b0b86e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,12 +1,14 @@ -.row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'actors' - .col-11 - -# Filtros - = render 'components/profiles_filters', actor_moderations: actor_moderations - .col-12 - - if actor_moderations.count.zero? - %h4= t('moderation_queue.nothing') - - actor_moderations.find_each do |actor_moderation| - %hr - = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content +%form{ action: site_actor_moderations_action_on_several_path, method: :post } + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'actors' + .col-11 + -# Filtros + = render 'components/profiles_filters', actor_moderations: actor_moderations + .col-12 + - if actor_moderations.count.zero? + %h4= t('moderation_queue.nothing') + - actor_moderations.find_each do |actor_moderation| + - cache [actor_moderation, actor_moderation.actor] do + %hr + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content diff --git a/config/locales/en.yml b/config/locales/en.yml index 4aea89f7..6d5baf5a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -81,9 +81,9 @@ en: text_checked: With selected profiles_checked_submenu: submenu_pause: Pause - submenu_accept: Accept - submenu_reject: Reject + submenu_allow: Allow submenu_block: Block + submenu_report: Report profiles_show_submenu: submenu_paused: "Paused (%{count})" submenu_allowed: "Allowed (%{count})" diff --git a/config/locales/es.yml b/config/locales/es.yml index 7b033859..13534822 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -80,10 +80,10 @@ es: text_show: Ver text_checked: Con los marcados profiles_checked_submenu: - submenu_pause: Pausado - submenu_accept: Aceptado - submenu_reject: Rechazado - submenu_block: Bloqueado + submenu_pause: Pausar + submenu_allow: Aceptar + submenu_block: Bloquear + submenu_report: Reportar profiles_show_submenu: submenu_paused: "Pausadas (%{count})" submenu_allowed: "Permitidas (%{count})" diff --git a/config/routes.rb b/config/routes.rb index 32936d42..9d825a3c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,8 @@ Rails.application.routes.draw do end end + patch :actor_moderations_action_on_several, to: 'actor_moderations#action_on_several' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From 567f0a10fb9f8427157992352be9ebe8dfd636f5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:12:34 -0300 Subject: [PATCH 560/814] =?UTF-8?q?fix:=20no=20fallar=20si=20no=20se=20pue?= =?UTF-8?q?de=20hacer=20la=20acci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/instance_moderations_controller.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index d25e1450..dc9e1dfa 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -24,14 +24,14 @@ class InstanceModerationsController < ApplicationController action = params[:instance_moderation_action].to_sym method = :"#{action}!" + may = :"may_#{action}?" + events = instance_moderation.aasm.events.map(&:name) + + return unless events.include? action InstanceModeration.transaction do instance_moderations.find_each do |instance_moderation| - events = instance_moderation.aasm.events.map(&:name) - - next unless events.include? action - - instance_moderation.public_send(method) + instance_moderation.public_send(method) if instance_moderation.public_send(may) end end end From 163f3fa7375e624bb7e30a6076f019c2d413eddd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:47:00 -0300 Subject: [PATCH 561/814] fix: namespace --- .../v1/webhooks/social_inbox_controller.rb | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 34ef1d6c..9c1a62ba 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -25,7 +25,8 @@ module Api # Devuelve un error si el token no es válido usuarie.present? - ActivityPub.transaction do + ::ActivityPub.transaction do + # Crea todos los registros necesarios y actualiza el estado actor.present? instance.present? @@ -47,7 +48,7 @@ module Api # # @todo DRY def onapproved - ActivityPub.transaction do + ::ActivityPub.transaction do actor.present? instance.present? object.present? @@ -63,7 +64,7 @@ module Api # # @todo DRY def onrejected - ActivityPub.transaction do + ::ActivityPub.transaction do actor.present? instance.present? object.present? @@ -110,7 +111,7 @@ module Api # # @return [ActivityPub::Object] def object - @object ||= ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| + @object ||= ::ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| # XXX: Si el objeto es una actividad, esto siempre va a ser # Generic o.type ||= 'ActivityPub::Object::Generic' @@ -120,7 +121,7 @@ module Api # XXX: el objeto necesita ser guardado antes de poder # procesarlo - ActivityPub::FetchJob.perform_later(site: site, object: o) unless object_embedded? + ::ActivityPub::FetchJob.perform_later(site: site, object: o) unless object_embedded? end end @@ -137,7 +138,7 @@ module Api # @return [ActivityPub::Activity] def activity @activity ||= - ActivityPub::Activity + ::ActivityPub::Activity .type_from(original_activity) .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup @@ -151,20 +152,20 @@ module Api # # @return [Actor] def actor - @actor ||= ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| + @actor ||= ::ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| unless a.instance - a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + a.instance = ::ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) site.instance_moderations.find_or_create_by(instance: a.instance) - ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + ::ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) end a.save! site.actor_moderations.find_or_create_by(actor: a) - ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) + ::ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) end end From 4bef3096210f73b2be57016f21d5e8d2c49a82dc Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:47:11 -0300 Subject: [PATCH 562/814] fix: soportar flags --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 9c1a62ba..c6aad11f 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -91,6 +91,7 @@ module Api def object_uri @object_uri ||= case original_activity[:object] + when Array then original_activity[:object].first when String then original_activity[:object] when Hash then original_activity.dig(:object, :id) end From 2e1087107af045aa0563c1f0dd5078b27d6bc225 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:47:23 -0300 Subject: [PATCH 563/814] fix: indexar por el tipo actual --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c6aad11f..23bd749d 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -131,7 +131,7 @@ module Api # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object: object) + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object_id: object.id, object_type: object.type) end # Crea la actividad y la vincula con el estado From 09e56b88ed5bfa2329b153ef33cf78a534ed5a40 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 16:51:40 -0300 Subject: [PATCH 564/814] =?UTF-8?q?fix:=20detectar=20si=20viene=20vac?= =?UTF-8?q?=C3=ADo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 23bd749d..3de32104 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -96,7 +96,7 @@ module Api when Hash then original_activity.dig(:object, :id) end ensure - raise ActiveRecord::RecordNotFound, 'object id missing' unless @object_uri + raise ActiveRecord::RecordNotFound, 'object id missing' if @object_uri.blank? end # Atajo a la instancia From 22f730b805dbcfc4daa16bde2147872d07250ceb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 17:14:24 -0300 Subject: [PATCH 565/814] fix: guardar el tipo correcto de objeto si lo soportamos --- .../api/v1/webhooks/social_inbox_controller.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 3de32104..dec2ee97 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -116,7 +116,15 @@ module Api # XXX: Si el objeto es una actividad, esto siempre va a ser # Generic o.type ||= 'ActivityPub::Object::Generic' - o.content = original_object if object_embedded? + + if object_embedded? + o.content = original_object + begin + type = original_object[:type].presence + o.type = "ActivityPub::Object::#{type}".constantize if type + rescue NameError + end + end o.save! From 85c45d48236f0a7040e2e23545ee08bfc6f2fb9e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Mar 2024 17:29:08 -0300 Subject: [PATCH 566/814] =?UTF-8?q?fix:=20no=20duplicar=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 7 +------ app/models/activity_pub.rb | 3 ++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index dec2ee97..fda51f49 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -89,12 +89,7 @@ module Api # # @return [String] def object_uri - @object_uri ||= - case original_activity[:object] - when Array then original_activity[:object].first - when String then original_activity[:object] - when Hash then original_activity.dig(:object, :id) - end + @object_uri ||= ::ActivityPub.uri_from_object(original_activity[:object]) ensure raise ActiveRecord::RecordNotFound, 'object id missing' if @object_uri.blank? end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 1afeee96..86c3f240 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -24,8 +24,9 @@ class ActivityPub < ApplicationRecord # @return [String, nil] def self.uri_from_object(object) case object + when Array then uri_from_object(object.first) when String then object - when Hash then object['id'] + when Hash then (object['id'] || object[:id]) end end From b255acf2fd98d2541a8bf6277390a7dc06609843 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 11:59:29 -0300 Subject: [PATCH 567/814] feat: comentarios por actore --- .../v1/webhooks/social_inbox_controller.rb | 2 +- .../moderation_queue_controller.rb | 1 + app/models/activity_pub.rb | 1 + app/processors/activity_pub_processor.rb | 15 ++++++++ app/views/moderation_queue/_comment.haml | 37 +++++++++---------- app/views/moderation_queue/_comments.haml | 10 ++--- app/views/moderation_queue/index.haml | 4 +- ...301202955_add_actor_id_to_activity_pubs.rb | 16 ++++++++ db/structure.sql | 6 ++- 9 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 app/processors/activity_pub_processor.rb create mode 100644 db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index fda51f49..464a0ffe 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -134,7 +134,7 @@ module Api # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, instance: instance, object_id: object.id, object_type: object.type) + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, actor: actor, instance: instance, object_id: object.id, object_type: object.type) end # Crea la actividad y la vincula con el estado diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 95639b35..b803ccc9 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -12,6 +12,7 @@ class ModerationQueueController < ApplicationController @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) + @moderation_queue = rubanok_process(site.activity_pubs, with: ActivityPubProcessor) end # todon.nl está usando /api/v2/instance diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 86c3f240..b52c2a76 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -13,6 +13,7 @@ class ActivityPub < ApplicationRecord belongs_to :instance belongs_to :site belongs_to :object, polymorphic: true + belongs_to :actor has_many :activities validates :site_id, presence: true diff --git a/app/processors/activity_pub_processor.rb b/app/processors/activity_pub_processor.rb new file mode 100644 index 00000000..52cdb6d3 --- /dev/null +++ b/app/processors/activity_pub_processor.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Gestiona los filtros de ActivityPub +class ActivityPubProcessor < Rubanok::Processor + # En orden descendiente para encontrar la última actividad + # + # Por ahora solo queremos moderar comentarios. + prepare do + raw.where(object_type: %w[ActivityPub::Object::Note ActivityPub::Object::Article]).order(updated_at: :desc) + end + + map :activity_pub_state, activate_always: true do |activity_pub_state: 'paused'| + raw.where(aasm_state: activity_pub_state) + end +end diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index afd2a335..495aaf55 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -4,24 +4,21 @@ .col-1 = render 'components/checkbox', id: comment['id'] .col-11 - .row.no-gutters - .col.col-lg-10.d-inline-flex.justify-content-between - %h4 - %a{ href: comment['attributedTo'] }= profile['preferredUsername'] + .d-flex.flex-row.align-items-center.justify-content-between + %h4.mb-0 + %a{ href: comment['attributedTo'] }= sanitize profile['preferredUsername'] + %small = render 'layouts/time', time: comment['published'] - - if comment['inReplyTo'] - .row.no-gutters - .col.p-0 - %p - %span= t('.reply_to') - %span - %a{ href: comment['inReplyTo'] }= comment['inReplyTo'] - .row.no-gutters - .col.p-0 - - if comment['summary'] - - summary = comment['summary'] - = render 'layouts/details', summary: summary do - %p= comment['content'].html_safe - - else - %p= comment['content'].html_safe - + - if comment['inReplyTo'].present? + %dl + %dt.d-inline + %small= t('.reply_to') + %dd.d-inline + %small + %a{ href: comment['inReplyTo'] }= sanitize comment['inReplyTo'] + %div + - if comment['summary'].present? + = render 'layouts/details', summary: comment['summary'], summary_class: 'h5' do + = sanitize comment['content'] + - else + = sanitize comment['content'] diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index eadfd78b..4fe84652 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,14 @@ .row.no-gutters.pt-2 .col-1.d-flex.align-items-center - = render 'components/checkbox', id: moderation_queue.first['id'] + = render 'components/select_all', id: 'select-all-comments' .col-md-9 -# Filtros = render 'components/comments_filters' -- moderation_queue.each do |comment| +- moderation_queue.each do |activity_pub| %hr - = render 'comment', comment: comment, profile: comment['attributedTo'] - + = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content + -# Botones moderación .d-flex.justify-content-center - = render 'components/comments_btn_box', comment: comment \ No newline at end of file + = render 'components/comments_btn_box', comment: activity_pub.object.content diff --git a/app/views/moderation_queue/index.haml b/app/views/moderation_queue/index.haml index 799fc641..80f0bd7c 100644 --- a/app/views/moderation_queue/index.haml +++ b/app/views/moderation_queue/index.haml @@ -7,7 +7,7 @@ = render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations, fediblock_states: @site.fediblock_states %hr = render 'layouts/details', id: 'accounts', summary: t('.accounts') do - = render 'moderation_queue/accounts', site: @site, post: @post, actor_moderations: @actor_moderations + = render 'moderation_queue/accounts', site: @site, actor_moderations: @actor_moderations %hr = render 'layouts/details', id: 'comments', summary: t('.comments') do - = render 'moderation_queue/comments', site: @site, post: @post, moderation_queue: @moderation_queue + = render 'moderation_queue/comments', site: @site, moderation_queue: @moderation_queue diff --git a/db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb b/db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb new file mode 100644 index 00000000..37db4bfc --- /dev/null +++ b/db/migrate/20240301202955_add_actor_id_to_activity_pubs.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Relaciona estados de actividades con les actores que las hicieron +class AddActorIdToActivityPubs < ActiveRecord::Migration[6.1] + def up + add_column :activity_pubs, :actor_id, :uuid + + ActivityPub.all.find_each do |activity_pub| + activity_pub.update_column(:actor_id, activity_pub.activities.last.actor_id) + end + end + + def down + remove_column :activity_pubs, :actor_id + end +end diff --git a/db/structure.sql b/db/structure.sql index 38a56b46..ca3a868b 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -572,7 +572,8 @@ CREATE TABLE public.activity_pubs ( object_id uuid NOT NULL, object_type character varying NOT NULL, aasm_state character varying NOT NULL, - instance_id uuid + instance_id uuid, + actor_id uuid ); @@ -2699,6 +2700,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240228171335'), ('20240228202830'), ('20240229201155'), -('20240301181224'); +('20240301181224'), +('20240301202955'); From d1a87177a58664da0c420e17764e297fdb74ffa9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 12:01:32 -0300 Subject: [PATCH 568/814] fix: eliminar indice unico en realidad lo queremos mantener... --- ...240301194154_remove_unique_index_from_activity_pubs.rb | 8 ++++++++ db/structure.sql | 8 +------- 2 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb diff --git a/db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb b/db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb new file mode 100644 index 00000000..0fa80e60 --- /dev/null +++ b/db/migrate/20240301194154_remove_unique_index_from_activity_pubs.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# A veces tenemos varias acciones sobre el mismo objeto +class RemoveUniqueIndexFromActivityPubs < ActiveRecord::Migration[6.1] + def change + remove_index :activity_pubs, %i[site_id object_id object_type], unique: true + end +end diff --git a/db/structure.sql b/db/structure.sql index ca3a868b..ff6cf895 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2167,13 +2167,6 @@ CREATE INDEX index_activity_pub_remote_flags_on_site_id ON public.activity_pub_r CREATE UNIQUE INDEX index_activity_pub_remote_flags_on_site_id_and_actor_id ON public.activity_pub_remote_flags USING btree (site_id, actor_id); --- --- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_activity_pubs_on_site_id_and_object_id_and_object_type ON public.activity_pubs USING btree (site_id, object_id, object_type); - - -- -- Name: index_actor_moderations_on_actor_id; Type: INDEX; Schema: public; Owner: - -- @@ -2701,6 +2694,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240228202830'), ('20240229201155'), ('20240301181224'), +('20240301194154'), ('20240301202955'); From b8e7e53ebd651332cae10f0c23dfb8239a3d1089 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:09:36 -0300 Subject: [PATCH 569/814] feat: limpieza de texto --- app/helpers/application_helper.rb | 22 ++++++++++++++++++---- app/models/metadata_template.rb | 14 ++------------ app/views/posts/show.haml | 1 - config/application.rb | 5 +++++ 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9f7be213..146846f0 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,10 +33,24 @@ module ApplicationHelper end end - # Devuelve todas las etiquetas HTML que queremos mantener - def all_html_tags - %w[h1 h2 h3 h4 h5 h6 p a ul ol li table tr td th tbody thead - tfoot em strong sup blockquote cite pre section article] + # Sanitizador que elimina todo + # + # @param html [String] + # @return [String] + def text_plain(html) + sanitize(html, tags: [], attributes: []) + end + + # Sanitizador con etiquetas y atributos por defecto + # + # @param html [String] + # @param options [Hash] + # @return [String] + def sanitize(html, options = {}) + options[:tags] ||= Sutty::ALLOWED_TAGS + options[:attributes] ||= Sutty::ALLOWED_ATTRIBUTES + + super(html, options) end # Genera HTML y limpia etiquetas innecesarias diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 823443d2..a9765918 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -190,8 +190,8 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, sanitizer .sanitize(string.tr("\r", '').unicode_normalize, - tags: allowed_tags, - attributes: allowed_attributes) + tags: Sutty::ALLOWED_TAGS, + attributes: Sutty::ALLOWED_ATTRIBUTES) .strip .html_safe end @@ -200,16 +200,6 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, @sanitizer ||= Rails::Html::Sanitizer.safe_list_sanitizer.new end - def allowed_attributes - @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name rel target referrerpolicy class colspan rowspan role data-turbo start type reversed].freeze - end - - def allowed_tags - @allowed_tags ||= %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote - figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze - end - # Decifra el valor # # XXX: Otros tipos de valores necesitan implementar su propio método diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index ec191d87..10fe64e3 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -20,7 +20,6 @@ post: @post, attribute: attr, metadata: metadata, site: @site, - tags: all_html_tags, locale: @locale, dir: dir) diff --git a/config/application.rb b/config/application.rb index 27a21cc6..ed7e5a78 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,6 +37,11 @@ if %w[development test].include? ENV['RAILS_ENV'] end module Sutty + ALLOWED_ATTRIBUTES = %w[style href src alt controls data-align data-multimedia data-multimedia-inner id name rel + target referrerpolicy class colspan rowspan role data-turbo start type reversed].freeze + ALLOWED_TAGS = %w[strong em del u mark p h1 h2 h3 h4 h5 h6 ul ol li img iframe audio video div figure blockquote + figcaption a sub sup small table thead tbody tfoot tr th td br code].freeze + # Sutty! class Application < Rails::Application # Initialize configuration defaults for originally generated Rails From 01c042b51265222638d32c8a06d89d66c4f8cf38 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:11:17 -0300 Subject: [PATCH 570/814] fix: limpiar html remoto --- app/views/components/_actor.haml | 8 ++++---- app/views/moderation_queue/_account.haml | 4 ++-- app/views/moderation_queue/_comment.haml | 10 ++++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/views/components/_actor.haml b/app/views/components/_actor.haml index 68aa3f90..3983d617 100644 --- a/app/views/components/_actor.haml +++ b/app/views/components/_actor.haml @@ -3,18 +3,18 @@ .py-2 %dl %dt= t('.profile_name') - %dd= sanitize remote_profile['name'] + %dd= text_plain remote_profile['name'] %dt= t('.preferred_name') - %dd= sanitize remote_profile['preferredUsername'] + %dd= text_plain remote_profile['preferredUsername'] %dt= t('.profile_id') %dd - = link_to sanitize(remote_profile['id']) + = link_to text_plain(remote_profile['id']) - if remote_profile['published'].present? %dt= t('.profile_published') %dd - = render 'layouts/time', time: sanitize(remote_profile['published']) + = render 'layouts/time', time: text_plain(remote_profile['published']) %dt= t('.profile_summary') %dd= sanitize remote_profile['summary'] diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index e891b4ad..fee90316 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -3,9 +3,9 @@ = render 'components/checkbox', id: actor_moderation.id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 - = link_to sanitize(profile['name']), site_actor_moderation_path(id: actor_moderation) + = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) .mb-3 - = sanitize profile['summary'].html_safe + = sanitize profile['summary'] -# Botones de Moderación - cache actor_moderation do diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 495aaf55..e0e625fd 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,24 +1,26 @@ -# Componente Comentario +- in_reply_to = text_plain comment['inReplyTo'] + .row.no-gutters .col-1 = render 'components/checkbox', id: comment['id'] .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 - %a{ href: comment['attributedTo'] }= sanitize profile['preferredUsername'] + %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] %small = render 'layouts/time', time: comment['published'] - - if comment['inReplyTo'].present? + - if in_reply_to.present? %dl %dt.d-inline %small= t('.reply_to') %dd.d-inline %small - %a{ href: comment['inReplyTo'] }= sanitize comment['inReplyTo'] + %a{ href: in_reply_to) }= in_reply_to %div - if comment['summary'].present? - = render 'layouts/details', summary: comment['summary'], summary_class: 'h5' do + = render 'layouts/details', summary: text_plain(comment['summary']), summary_class: 'h5' do = sanitize comment['content'] - else = sanitize comment['content'] From 6110172324f6f267f5d10a1b33e2458f061ea67a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:12:22 -0300 Subject: [PATCH 571/814] feat: poder cambiar el nivel de summary --- app/assets/stylesheets/application.scss | 34 ++++++++++++++----------- app/views/layouts/_details.haml | 9 +++++-- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a24af4c8..cdf97b5b 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -561,24 +561,28 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); // details styles .details { - summary { + & > summary { list-style: none; - cursor: default; - position: relative; + cursor: pointer; + + .hide-when-open { + display: inline; + } + + .show-when-open { + display: none; + } } - summary::after { - content: '▶'; - font-size: 1.8rem; - position: absolute; - left: 97%; - bottom: 3%; - transform: rotate(180deg); - } + &[open] { & > summary { - &::after { - transform: rotate(90deg); - } + .hide-when-open { + display: none; + } + + .show-when-open { + display: inline; + } } } -} +} diff --git a/app/views/layouts/_details.haml b/app/views/layouts/_details.haml index 3260bfcb..a21f46c1 100644 --- a/app/views/layouts/_details.haml +++ b/app/views/layouts/_details.haml @@ -4,8 +4,13 @@ @param :id [String] El ID opcional sirve para mantener el historial de cuál estaba abierto y recuperarlo al cargar la página @param :summary [String] El resumen + @param :summary_class [String] Clases para el summary + +- local_assigns[:summary_class] ||= 'h3' %details.details.py-2{ id: local_assigns[:id], data: { controller: 'details', action: 'toggle->details#store' } } - %summary - %h3.py-2.pr-2= summary + %summary.d-flex.flex-row.align-items-center.justify-content-between{ class: local_assigns[:summary_class] } + %span= summary + %span.hide-when-open ▶ + %span.show-when-open ▼ = yield From d8487ea7e9b29ef389d8a1c3ebd790bcf52f6ebe Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:17:21 -0300 Subject: [PATCH 572/814] fixup! fix: limpiar html remoto --- app/views/moderation_queue/_comment.haml | 11 ++++++----- app/views/moderation_queue/_instance.haml | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index e0e625fd..29888ef7 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,6 +1,7 @@ -# Componente Comentario - in_reply_to = text_plain comment['inReplyTo'] +- summary = text_plain(comment['summary']) .row.no-gutters .col-1 @@ -10,17 +11,17 @@ %h4.mb-0 %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] %small - = render 'layouts/time', time: comment['published'] + = render 'layouts/time', time: text_plain(comment['published']) - if in_reply_to.present? %dl %dt.d-inline %small= t('.reply_to') %dd.d-inline %small - %a{ href: in_reply_to) }= in_reply_to - %div - - if comment['summary'].present? - = render 'layouts/details', summary: text_plain(comment['summary']), summary_class: 'h5' do + %a{ href: in_reply_to }= in_reply_to + .content + - if summary.present? + = render 'layouts/details', summary: summary, summary_class: 'h5' do = sanitize comment['content'] - else = sanitize comment['content'] diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 73655e1b..97d23f10 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -7,11 +7,12 @@ .col-11 %h4 %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname - %p= sanitize instance.content['description'] + .content + = sanitize instance.content['description'] - if usuaries.present? %dl %dt.d-inline= t('.users') - %dd.d-inline= sanitize usuaries.to_s + %dd.d-inline= text_plain usuaries.to_s -# Botones moderación .d-flex.pb-4 From 5fabe9cd832753e90b2f27f9e5cab77c7c2c6a0d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:49:07 -0300 Subject: [PATCH 573/814] feat: acciones sobre comentarios --- app/controllers/activity_pubs_controller.rb | 22 +++++++++++++++++ app/models/activity_pub.rb | 3 +++ app/models/actor_moderation.rb | 10 +++----- app/models/concerns/aasm_events_concern.rb | 14 +++++++++++ app/views/components/_btn_base.haml | 1 + app/views/components/_comments_btn_box.haml | 12 +++++----- app/views/moderation_queue/_comment.haml | 12 +++++++--- app/views/moderation_queue/_comments.haml | 26 ++++++++++----------- config/locales/en.yml | 2 +- config/locales/es.yml | 5 ++-- config/routes.rb | 8 +++++++ 11 files changed, 82 insertions(+), 33 deletions(-) create mode 100644 app/controllers/activity_pubs_controller.rb create mode 100644 app/models/concerns/aasm_events_concern.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb new file mode 100644 index 00000000..dfe388a4 --- /dev/null +++ b/app/controllers/activity_pubs_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Gestiona acciones de moderación +class ActivityPubsController < ApplicationController + ActivityPub.events.each do |event| + define_method(event) do + activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") + + redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + end + end + + def action_on_several + + end + + private + + def activity_pub + @activity_pub ||= site.activity_pubs.find(params[:activity_pub_id]) + end +end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index b52c2a76..95fa3bf3 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -9,6 +9,9 @@ # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} class ActivityPub < ApplicationRecord include AASM + include AasmEventsConcern + + IGNORED_EVENTS = %i[remove] belongs_to :instance belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index c6f8bfc0..1fc1a42a 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -3,6 +3,9 @@ # Mantiene la relación entre Site y Actor class ActorModeration < ApplicationRecord include AASM + include AasmEventsConcern + + IGNORED_EVENTS = [] belongs_to :site belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' @@ -19,13 +22,6 @@ class ActorModeration < ApplicationRecord self.update_all(aasm_state: 'paused', updated_at: Time.now) end - # Todos los eventos de la máquina de estados - # - # @return [Array] - def self.events - aasm.events.map(&:name) - end - aasm do state :paused, initial: true state :allowed diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb new file mode 100644 index 00000000..79250ea9 --- /dev/null +++ b/app/models/concerns/aasm_events_concern.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module AasmEventsConcern + extend ActiveSupport::Concern + + included do + # Todos los eventos de la máquina de estados + # + # @return [Array] + def self.events + aasm.events.map(&:name) - self::IGNORED_EVENTS + end + end +end diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 677b88f1..a950ad5a 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,6 +1,7 @@ -# Componente Botón general Moderación - local_assigns[:method] ||= 'patch' +- local_assigns[:class] ||= 'btn-secondary' - local_assigns[:class] = "btn #{local_assigns[:class]}" -# @todo path es obligatorio diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 8b8d7268..285eefdb 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,8 +1,8 @@ -# Componente Botonera de Comentarios -- btn_class = 'btn-secondary py-1 px-2' -= render 'components/btn_base', text: t('.text_pause'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_reject'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_accept'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_reply'), class: btn_class, href: '' -= render 'components/btn_base', text: t('.text_report'), class: btn_class, href: '' \ No newline at end of file +.d-flex.flex-row + - ActivityPub.events.each do |event| + = render 'components/btn_base', + text: t(".text_#{event}"), + path: public_send(:"site_activity_pub_#{event}_path", activity_pub_id: activity_pub), + disabled: !activity_pub.public_send(:"may_#{event}?") diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 29888ef7..ffaf76cf 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,11 +1,16 @@ --# Componente Comentario +-# + Componente Comentario + + @param profile [Hash] + @param comment [Hash] + @param activity_pub [ActivityPub] - in_reply_to = text_plain comment['inReplyTo'] -- summary = text_plain(comment['summary']) +- summary = text_plain comment['summary'] .row.no-gutters .col-1 - = render 'components/checkbox', id: comment['id'] + = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' } .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 @@ -25,3 +30,4 @@ = sanitize comment['content'] - else = sanitize comment['content'] + = render 'components/comments_btn_box', activity_pub: activity_pub diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 4fe84652..97f77e3c 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,14 @@ -.row.no-gutters.pt-2 - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'select-all-comments' - .col-md-9 - -# Filtros - = render 'components/comments_filters' +%form{ action: site_activity_pubs_action_on_several_path, method: :post, data: { controller: 'select-all' } } + .row.no-gutters.pt-2 + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'select-all-comments' + .col-md-9 + -# Filtros + = render 'components/comments_filters' -- moderation_queue.each do |activity_pub| - %hr - = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content - - -# Botones moderación - .d-flex.justify-content-center - = render 'components/comments_btn_box', comment: activity_pub.object.content + - if moderation_queue.count.zero? + %h4= t('moderation_queue.nothing') + - moderation_queue.each do |activity_pub| + - cache [activity_pub, activity_pub.object, activity_pub.actor] do + %hr + = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub diff --git a/config/locales/en.yml b/config/locales/en.yml index 6d5baf5a..f69d60b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -93,8 +93,8 @@ en: title: Block lists comments_btn_box: text_pause: Pause + text_approve: Approve text_reject: Reject - text_accept: Accept text_reply: Reply text_report: Report instances_btn_box: diff --git a/config/locales/es.yml b/config/locales/es.yml index 13534822..a0aaa4d6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -92,10 +92,9 @@ es: block_lists: title: Listas de bloqueo comments_btn_box: - text_pause: Pausa + text_pause: Pausar + text_approve: Aceptar text_reject: Rechazar - text_accept: Aceptar Publicación - text_reply: Responder text_report: Reportar instances_btn_box: text_check: Moderar caso por caso diff --git a/config/routes.rb b/config/routes.rb index 9d825a3c..8809767b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -82,6 +82,14 @@ Rails.application.routes.draw do patch :actor_moderations_action_on_several, to: 'actor_moderations#action_on_several' + resources :activity_pub, only: [] do + ActivityPub.events.each do |event| + patch event, to: "activity_pubs##{event}" + end + end + + patch :activity_pubs_action_on_several, to: 'activity_pubs#action_on_several' + # Gestionar artículos según idioma nested do scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do From a2204779af2bca3f5b158e59553fa6c8787986b0 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 13:59:01 -0300 Subject: [PATCH 574/814] feat: filtrar por estado del comentario --- app/helpers/moderation_queue_helper.rb | 7 +++++++ app/models/activity_pub.rb | 1 + app/models/actor_moderation.rb | 1 + app/models/concerns/aasm_events_concern.rb | 7 +++++++ app/views/components/_comments_filters.haml | 2 +- app/views/components/_comments_show_submenu.haml | 8 ++++---- app/views/components/_profiles_show_submenu.haml | 4 ++-- app/views/moderation_queue/_comments.haml | 2 +- config/locales/en.yml | 8 ++++---- config/locales/es.yml | 8 ++++---- 10 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 app/helpers/moderation_queue_helper.rb diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb new file mode 100644 index 00000000..3681bec3 --- /dev/null +++ b/app/helpers/moderation_queue_helper.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module ModerationQueueHelper + def filter_states(**args) + params.permit(:state, :actor_state, :activity_pub_state).merge(**args) + end +end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 95fa3bf3..51ee0d71 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -12,6 +12,7 @@ class ActivityPub < ApplicationRecord include AasmEventsConcern IGNORED_EVENTS = %i[remove] + IGNORED_STATES = %i[removed] belongs_to :instance belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 1fc1a42a..421d4c6e 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -6,6 +6,7 @@ class ActorModeration < ApplicationRecord include AasmEventsConcern IGNORED_EVENTS = [] + IGNORED_STATES = [] belongs_to :site belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 79250ea9..59ea243f 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -10,5 +10,12 @@ module AasmEventsConcern def self.events aasm.events.map(&:name) - self::IGNORED_EVENTS end + + # Todos los estados de la máquina de estados + # + # @return [Array] + def self.states + aasm.states.map(&:name) - self::IGNORED_STATES + end end end diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index 7c453088..b4597be5 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -3,4 +3,4 @@ = render 'components/comments_checked_submenu' = render 'components/dropdown', text: t('.text_show') do - = render 'components/comments_show_submenu' \ No newline at end of file + = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml index 0308b926..eb037975 100644 --- a/app/views/components/_comments_show_submenu.haml +++ b/app/views/components/_comments_show_submenu.haml @@ -1,4 +1,4 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_report'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file +- ActivityPub.states.each do |state| + = render 'components/dropdown_item', + text: t(".submenu_#{state}", count: activity_pubs.unscope(where: :aasm_state).public_send(state).count), + path: site_moderation_queue_path(filter_states(activity_pub_state: state)) diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 703e4a15..0209ef2f 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,4 +1,4 @@ -- ActorModeration.aasm.states.map(&:name).each do |actor_state| +- ActorModeration.states.each do |actor_state| = render 'components/dropdown_item', text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), - path: site_moderation_queue_path(params.permit(:state, :actor_state).merge(actor_state: actor_state)) + path: site_moderation_queue_path(filter_states(actor_state: actor_state)) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 97f77e3c..f243b02a 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -4,7 +4,7 @@ = render 'components/select_all', id: 'select-all-comments' .col-md-9 -# Filtros - = render 'components/comments_filters' + = render 'components/comments_filters', activity_pubs: moderation_queue - if moderation_queue.count.zero? %h4= t('moderation_queue.nothing') diff --git a/config/locales/en.yml b/config/locales/en.yml index f69d60b0..eecd5ebd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -72,10 +72,10 @@ en: submenu_accept: Accept submenu_reject: Reject comments_show_submenu: - submenu_pause: Pause - submenu_accept: Accept - submenu_report: Report - submenu_reject: Reject + submenu_paused: "Paused (%{count})" + submenu_approved: "Approved (%{count})" + submenu_rejected: "Rejected (%{count})" + submenu_reported: "Reported (%{count})" profiles_filters: text_show: Show text_checked: With selected diff --git a/config/locales/es.yml b/config/locales/es.yml index a0aaa4d6..0f9eb68a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -72,10 +72,10 @@ es: submenu_accept: Aceptado submenu_reject: Rechazado comments_show_submenu: - submenu_pause: Pausado - submenu_accept: Aceptado - submenu_report: Reportado - submenu_reject: Rechazado + submenu_paused: "Pausados (%{count})" + submenu_approved: "Aprobados (%{count})" + submenu_rejected: "Rechazados (%{count})" + submenu_reported: "Reportados (%{count})" profiles_filters: text_show: Ver text_checked: Con los marcados From 0b3f4e33fb4f32671f11bc6b2593adfe3a60524b Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:25:19 -0300 Subject: [PATCH 575/814] =?UTF-8?q?fix:=20siempre=20es=20un=20bot=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://blog.saeloun.com/2021/08/24/rails-7-button-to-rendering/ --- app/views/components/_btn_base.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index a950ad5a..4d8566d3 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -5,4 +5,5 @@ - local_assigns[:class] = "btn #{local_assigns[:class]}" -# @todo path es obligatorio -= button_to text, local_assigns[:path], **local_assigns += button_to local_assigns[:path], **local_assigns do + = text From 27d7589f9aab294283df57a14fa3b9a7cb7c7ee9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:26:41 -0300 Subject: [PATCH 576/814] fix: no se pueden anidar formularios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usando el atributo form, podemos crear un formulario vacío y colocar inputs por fuera de su contexto. de lo contrario el primer botón de acción individual no funciona --- app/models/instance_moderation.rb | 7 +++-- app/views/components/_checkbox.haml | 2 +- app/views/components/_dropdown_button.haml | 2 +- .../_instances_checked_submenu.haml | 5 ++- app/views/components/_instances_filters.haml | 2 +- app/views/components/_select_all.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 31 ++++++++++--------- 9 files changed, 28 insertions(+), 27 deletions(-) diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 10b5e8e0..7447cc89 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -3,6 +3,10 @@ # Mantiene el registro de relaciones entre sitios e instancias class InstanceModeration < ApplicationRecord include AASM + include AasmEventsConcern + + IGNORED_EVENTS = [] + IGNORED_STATES = [] belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' @@ -11,9 +15,6 @@ class InstanceModeration < ApplicationRecord # todas las que no estén bloqueadas ya. scope :may_block, -> { where.not(aasm_state: 'blocked') } scope :may_pause, -> { where.not(aasm_state: 'paused') } - scope :paused, -> { where(aasm_state: 'paused') } - scope :blocked, -> { where(aasm_state: 'blocked') } - scope :allowed, -> { where(aasm_state: 'allowed') } # Bloquear instancias en masa def self.block_all! diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 596ff074..68f1a663 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,5 +1,5 @@ -# Componente Checkbox - local_assigns[:name] ||= id .custom-control.custom-checkbox - %input.custom-control-input{ type: 'checkbox', id: id, **local_assigns } + %input.custom-control-input{ form: local_assigns[:form_id], type: 'checkbox', id: id, **local_assigns } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_dropdown_button.haml b/app/views/components/_dropdown_button.haml index 8b0c4684..c8c98209 100644 --- a/app/views/components/_dropdown_button.haml +++ b/app/views/components/_dropdown_button.haml @@ -1,4 +1,4 @@ -# @param name [String] @param value [String] -%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value }= text +%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value, form: local_assigns[:form_id] }= text diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index c3573ead..2d28fb1c 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,3 +1,2 @@ -= render 'components/dropdown_button', text: t('.submenu_pause'), name: 'instance_moderation_action', value: 'pause' -= render 'components/dropdown_button', text: t('.submenu_allow'), name: 'instance_moderation_action', value: 'allow' -= render 'components/dropdown_button', text: t('.submenu_block'), name: 'instance_moderation_action', value: 'block' +- InstanceModeration.events.each do |event| + = render 'components/dropdown_button', text: t(".submenu_#{event}"), name: 'instance_moderation_action', value: event, form_id: form_id diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index fe40ced3..2c05693a 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/instances_checked_submenu' + = render 'components/instances_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/instances_show_submenu', site: site diff --git a/app/views/components/_select_all.haml b/app/views/components/_select_all.haml index 2603dfd3..68711c4a 100644 --- a/app/views/components/_select_all.haml +++ b/app/views/components/_select_all.haml @@ -1,4 +1,4 @@ -# @param id [String] -= render 'components/checkbox', id: id, data: { action: 'select-all#toggle', target: 'select-all.toggle' } do += render 'components/checkbox', id: id, form: local_assigns[:form_id], data: { action: 'select-all#toggle', target: 'select-all.toggle' } do %span.sr-only= t('.label') diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index ffaf76cf..33ebc722 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -10,7 +10,7 @@ .row.no-gutters .col-1 - = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' }, form: form_id .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 97d23f10..05510724 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -3,7 +3,7 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: instance.hostname, form_id: form_id, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 77b6adea..83b0c772 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,22 +1,23 @@ +- form_id = 'instance_moderation_action_on_several' %section - %form{ action: site_instance_moderations_action_on_several_path, method: :post } - .row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'instances' - .col-11 - -# Filtros - = render 'components/instances_filters', site: site + %form{ id: form_id, action: site_instance_moderations_action_on_several_path, method: :post } + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'instances', form_id: form_id + .col-11 + -# Filtros + = render 'components/instances_filters', site: site, form_id: form_id - .col-12 - - if instance_moderations.count.zero? - %h4= t('moderation_queue.nothing') + .col-12 + - if instance_moderations.count.zero? + %h4= t('moderation_queue.nothing') - - instance_moderations.each do |instance_moderation| - - cache [instance_moderation.aasm_state, instance_moderation.instance] do - %hr - = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance + - instance_moderations.each do |instance_moderation| + - cache [instance_moderation.aasm_state, instance_moderation.instance] do + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form_id: form_id - %hr + %hr %div %h3.mt-5= t('moderation_queue.instances.title') %lead= t('moderation_queue.instances.description') From 5211c9bd28c089ea6db5b568bf20e2497e5a1597 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:39:06 -0300 Subject: [PATCH 577/814] fix: formularios --- .../components/_profiles_checked_submenu.haml | 2 +- app/views/components/_profiles_filters.haml | 2 +- app/views/moderation_queue/_account.haml | 2 +- app/views/moderation_queue/_accounts.haml | 31 ++++++++++--------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index c0b99aa5..13e016ca 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,2 +1,2 @@ - ActorModeration.events.each do |actor_event| - = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event + = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event, form_id: form_id diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index c6397e69..a2593f4c 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu' + = render 'components/profiles_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index fee90316..f63b6f6f 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,6 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: actor_moderation.id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: actor_moderation.id, form_id: form_id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 35b0b86e..53d2f28e 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,14 +1,17 @@ -%form{ action: site_actor_moderations_action_on_several_path, method: :post } - .row.no-gutters.pt-2{ data: { controller: 'select-all' } } - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'actors' - .col-11 - -# Filtros - = render 'components/profiles_filters', actor_moderations: actor_moderations - .col-12 - - if actor_moderations.count.zero? - %h4= t('moderation_queue.nothing') - - actor_moderations.find_each do |actor_moderation| - - cache [actor_moderation, actor_moderation.actor] do - %hr - = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content +- form_id = 'actor_moderations_action_on_several' + += form_tag site_actor_moderations_action_on_several_path, id: form_id, method: :patch + +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'actors', form_id: form_id + .col-11 + -# Filtros + = render 'components/profiles_filters', actor_moderations: actor_moderations, form_id: form_id + .col-12 + - if actor_moderations.count.zero? + %h4= t('moderation_queue.nothing') + - actor_moderations.find_each do |actor_moderation| + - cache [actor_moderation, actor_moderation.actor] do + %hr + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form_id: form_id From 8e681cdba79024e6fb584654025ce730d9c5d90a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:47:20 -0300 Subject: [PATCH 578/814] fix: sincronizar controladores --- app/controllers/activity_pubs_controller.rb | 8 +++-- .../actor_moderations_controller.rb | 6 +++- .../concerns/moderation_concern.rb | 13 ++++++++ .../instance_moderations_controller.rb | 32 ++++++------------- .../moderation_queue_controller.rb | 2 +- app/policies/activity_pub_policy.rb | 16 ++++++++++ app/policies/instance_moderation_policy.rb | 14 +++----- 7 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 app/controllers/concerns/moderation_concern.rb create mode 100644 app/policies/activity_pub_policy.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index dfe388a4..057e65f7 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -2,16 +2,20 @@ # Gestiona acciones de moderación class ActivityPubsController < ApplicationController + include ModerationConcern + ActivityPub.events.each do |event| define_method(event) do + authorize activity_pub + activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") - redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + redirect_to_moderation_queue! end end def action_on_several - + redirect_to_moderation_queue! end private diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 907f21c6..eadc2165 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -2,6 +2,8 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController + include ModerationConcern + ActorModeration.events.each do |actor_event| define_method(actor_event) do authorize actor_moderation @@ -11,7 +13,7 @@ class ActorModerationsController < ApplicationController actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") - redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + redirect_to_moderation_queue! end end @@ -29,6 +31,8 @@ class ActorModerationsController < ApplicationController method = :"#{action}!" may = :"may_#{action}?" + redirect_to_moderation_queue! + return unless ActorModeration.events.include? action ActorModeration.transaction do diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb new file mode 100644 index 00000000..9a4f1c16 --- /dev/null +++ b/app/controllers/concerns/moderation_concern.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ModerationConcern + extend ActiveSupport::Concern + + included do + private + + def redirect_to_moderation_queue! + redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) + end + end +end diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index dc9e1dfa..270f0588 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -2,19 +2,16 @@ # Actualiza la relación entre un sitio y una instancia class InstanceModerationsController < ApplicationController - before_action :authorize_policy, except: %i[action_on_several] - around_action :redirect_to_moderation_queue! + include ModerationConcern - def pause - instance_moderation.pause! if instance_moderation.may_pause? - end + InstanceModeration.events.each do |event| + define_method(event) do + authorize instance_moderation - def allow - instance_moderation.allow! if instance_moderation.may_allow? - end + instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?") - def block - instance_moderation.block! if instance_moderation.may_block? + redirect_to_moderation_queue! + end end def action_on_several @@ -25,9 +22,10 @@ class InstanceModerationsController < ApplicationController action = params[:instance_moderation_action].to_sym method = :"#{action}!" may = :"may_#{action}?" - events = instance_moderation.aasm.events.map(&:name) - return unless events.include? action + redirect_to_moderation_queue! + + return unless InstanceModeration.events.include? action InstanceModeration.transaction do instance_moderations.find_each do |instance_moderation| @@ -38,18 +36,8 @@ class InstanceModerationsController < ApplicationController private - def redirect_to_moderation_queue!(&action) - redirect_back fallback_location: site_moderation_queue_path, state: session[:moderation_queue_filtered_by_state] - - yield - end - # @return [InstanceModeration] def instance_moderation @instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id]) end - - def authorize_policy - authorize instance_moderation - end end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index b803ccc9..6a628aaa 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,7 +6,7 @@ class ModerationQueueController < ApplicationController def index dummy_data - session[:moderation_queue_filters] = params.permit(:state, :actor_state) + session[:moderation_queue_filters] = params.permit(:state, :actor_state, :activity_pub_state) # @todo cambiar el estado por query @activity_pubs = site.activity_pubs diff --git a/app/policies/activity_pub_policy.rb b/app/policies/activity_pub_policy.rb new file mode 100644 index 00000000..f5755840 --- /dev/null +++ b/app/policies/activity_pub_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Solo les usuaries pueden moderar comentarios +ActivityPubPolicy = Struct.new(:usuarie, :activity_pub) do + ActivityPub.events.each do |event| + define_method(:"#{event}?") do + activity_pub.site.usuarie? usuarie + end + end + + # En este paso tenemos varias instancias por moderar pero todas son + # del mismo sitio. + def action_on_several? + activity_pub.first.site.usuarie? usuarie + end +end diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb index c07455b3..13ebfeca 100644 --- a/app/policies/instance_moderation_policy.rb +++ b/app/policies/instance_moderation_policy.rb @@ -2,16 +2,10 @@ # Solo les usuaries pueden moderar instancias InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do - def pause? - instance_moderation.site.usuarie? usuarie - end - - def allow? - pause? - end - - def block? - pause? + InstanceModeration.events.each do |event| + define_method(:"#{event}?") do + instance_moderation.site.usuarie? usuarie + end end # En este paso tenemos varias instancias por moderar pero todas son From a7d33976ec7c5da2d3a7a5257eee7ba66d329ce9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 14:59:17 -0300 Subject: [PATCH 579/814] fixup! fix: no se pueden anidar formularios --- app/views/moderation_queue/_instances.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 83b0c772..a707d48a 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,6 +1,8 @@ - form_id = 'instance_moderation_action_on_several' + %section - %form{ id: form_id, action: site_instance_moderations_action_on_several_path, method: :post } + = form_tag site_instance_moderations_action_on_several_path, id: form_id, method: :patch + .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center = render 'components/select_all', id: 'instances', form_id: form_id From 3967a631632c09a1310c4248c7b1a61406284d3e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 15:10:20 -0300 Subject: [PATCH 580/814] feat: extraer en un componente --- app/views/components/_select_all_container.haml | 13 +++++++++++++ app/views/moderation_queue/_accounts.haml | 2 +- app/views/moderation_queue/_instances.haml | 3 +-- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 app/views/components/_select_all_container.haml diff --git a/app/views/components/_select_all_container.haml b/app/views/components/_select_all_container.haml new file mode 100644 index 00000000..5fa91e2d --- /dev/null +++ b/app/views/components/_select_all_container.haml @@ -0,0 +1,13 @@ +-# + Contenedor para las acciones en masa. + + Es un formulario auto-contenido, que permite colocar los elementos + fuera del formulario para evitar anidarlos. Mientras los elementos + tengan el atributo `form` con el mismo parámetro `form_id`, el + navegador los va a asignar a este formulario. + + @param path [String] + @param form_id [String] + += form_tag path, id: form_id, method: :patch do + -# nada diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 53d2f28e..65ff953f 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,6 +1,6 @@ - form_id = 'actor_moderations_action_on_several' -= form_tag site_actor_moderations_action_on_several_path, id: form_id, method: :patch += render 'components/select_all_container', path: site_actor_moderations_action_on_several_path, form_id: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index a707d48a..d9db967f 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,8 +1,7 @@ - form_id = 'instance_moderation_action_on_several' %section - = form_tag site_instance_moderations_action_on_several_path, id: form_id, method: :patch - + = render 'components/select_all_container', path: site_instance_moderations_action_on_several_path, form_id: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center = render 'components/select_all', id: 'instances', form_id: form_id From b201c3de1881c0e20f8b53468ea69f62b8aeb386 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 15:11:29 -0300 Subject: [PATCH 581/814] feat: filtros y acciones para comentarios --- .../components/_comments_checked_submenu.haml | 5 ++-- app/views/components/_comments_filters.haml | 2 +- app/views/moderation_queue/_comments.haml | 27 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml index 4998e5c7..fa3d7612 100644 --- a/app/views/components/_comments_checked_submenu.haml +++ b/app/views/components/_comments_checked_submenu.haml @@ -1,3 +1,2 @@ -= render 'components/dropdown_item', text: t('.submenu_pause'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_accept'), path: '/' -= render 'components/dropdown_item', text: t('.submenu_reject'), path: '/' \ No newline at end of file +- ActivityPub.events.each do |event| + = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event}"), name: 'activity_pub_action', value: event diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index b4597be5..15f5173d 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -1,6 +1,6 @@ .d-flex.py-2 = render 'components/dropdown', text: t('.text_checked') do - = render 'components/comments_checked_submenu' + = render 'components/comments_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index f243b02a..bf1e94a0 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,14 +1,17 @@ -%form{ action: site_activity_pubs_action_on_several_path, method: :post, data: { controller: 'select-all' } } - .row.no-gutters.pt-2 - .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'select-all-comments' - .col-md-9 - -# Filtros - = render 'components/comments_filters', activity_pubs: moderation_queue +- form_id = 'activity_pub_action_on_several' - - if moderation_queue.count.zero? - %h4= t('moderation_queue.nothing') - - moderation_queue.each do |activity_pub| - - cache [activity_pub, activity_pub.object, activity_pub.actor] do += render 'components/select_all_container', path: site_activity_pubs_action_on_several_path, form_id: form_id + +.row.no-gutters.pt-2{ data: { controller: 'select-all' } } + .col-1.d-flex.align-items-center + = render 'components/select_all', id: 'select-all-comments', form_id: form_id + .col-md-9 + -# Filtros + = render 'components/comments_filters', activity_pubs: moderation_queue, form_id: form_id + .col-12 + - if moderation_queue.count.zero? + %h4= t('moderation_queue.nothing') + - moderation_queue.each do |activity_pub| + -# cache [activity_pub, activity_pub.object, activity_pub.actor] do %hr - = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub + = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form_id: form_id From b7989808655e29cfad5db4d04755b28194108a88 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 15:13:01 -0300 Subject: [PATCH 582/814] feat: acciones masivas para comentarios --- app/controllers/activity_pubs_controller.rb | 16 ++++++++++++++++ config/locales/en.yml | 3 ++- config/locales/es.yml | 7 ++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 057e65f7..9bbbb9cc 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -15,7 +15,23 @@ class ActivityPubsController < ApplicationController end def action_on_several + activity_pubs = site.activity_pubs.where(id: params[:activity_pub]) + + authorize activity_pubs + + action = params[:activity_pub_action].to_sym + method = :"#{action}!" + may = :"may_#{action}?" + redirect_to_moderation_queue! + + return unless ActivityPub.events.include? action + + ActivityPub.transaction do + activity_pubs.find_each do |activity_pub| + activity_pub.public_send(method) if activity_pub.public_send(may) + end + end end private diff --git a/config/locales/en.yml b/config/locales/en.yml index eecd5ebd..a10b9f3a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -69,8 +69,9 @@ en: text_checked: With selected comments_checked_submenu: submenu_pause: Pause - submenu_accept: Accept + submenu_approve: Approve submenu_reject: Reject + submenu_report: Report comments_show_submenu: submenu_paused: "Paused (%{count})" submenu_approved: "Approved (%{count})" diff --git a/config/locales/es.yml b/config/locales/es.yml index 0f9eb68a..f5487e47 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -68,9 +68,10 @@ es: text_show: Ver text_checked: Con los marcados comments_checked_submenu: - submenu_pause: Pausado - submenu_accept: Aceptado - submenu_reject: Rechazado + submenu_pause: Pausar + submenu_approve: Aprobar + submenu_reject: Rechazar + submenu_report: Reportar comments_show_submenu: submenu_paused: "Pausados (%{count})" submenu_approved: "Aprobados (%{count})" From ccd3df2038b893b0ead29682df691dbb81862dfa Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 16:46:43 -0300 Subject: [PATCH 583/814] feat: aprobar o rechazar actividades --- app/models/activity_pub.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 51ee0d71..838eea80 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -64,14 +64,26 @@ class ActivityPub < ApplicationRecord transitions from: %i[approved rejected], to: :paused end - # La actividad se aprueba + # La actividad se aprueba, informándole a la Social Inbox que está + # aprobada. También recibimos la aprobación via + # webhook a modo de confirmación. event :approve do transitions from: %i[paused rejected], to: :approved + + before do + raise AASM::InvalidTransition unless + site.social_inbox.inbox.accept(id: object.uri).ok? + end end # La actividad fue rechazada event :reject do transitions from: %i[paused approved], to: :rejected + + before do + raise AASM::InvalidTransition unless + site.social_inbox.inbox.reject(id: object.uri).ok? + end end # Solo podemos reportarla luego de rechazarla From 0e2a4c42882774f56a494e29fb674401b10904e2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 16:52:28 -0300 Subject: [PATCH 584/814] =?UTF-8?q?fix:=20todav=C3=ADa=20no=20se=20puede?= =?UTF-8?q?=20volver=20de=20una=20actividad=20rechazada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 838eea80..0cd44814 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -61,14 +61,14 @@ class ActivityPub < ApplicationRecord # Si un objeto previamente aprobado fue actualizado, volvemos a # pausarlo. event :pause do - transitions from: %i[approved rejected], to: :paused + transitions from: %i[approved], to: :paused end # La actividad se aprueba, informándole a la Social Inbox que está # aprobada. También recibimos la aprobación via # webhook a modo de confirmación. event :approve do - transitions from: %i[paused rejected], to: :approved + transitions from: %i[paused], to: :approved before do raise AASM::InvalidTransition unless From 1fe6199cea375c319e6eb3423985151337d091e8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 16:53:23 -0300 Subject: [PATCH 585/814] =?UTF-8?q?fix:=20todav=C3=ADa=20no=20se=20puede?= =?UTF-8?q?=20pausar=20luego=20de=20aprobar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 0cd44814..6f0d884c 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -58,12 +58,6 @@ class ActivityPub < ApplicationRecord end end - # Si un objeto previamente aprobado fue actualizado, volvemos a - # pausarlo. - event :pause do - transitions from: %i[approved], to: :paused - end - # La actividad se aprueba, informándole a la Social Inbox que está # aprobada. También recibimos la aprobación via # webhook a modo de confirmación. From c49182e278edd723a29fcad7671a138ee1f1d623 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 17:14:46 -0300 Subject: [PATCH 586/814] feat: poder bloquear en masa --- .../actor_moderations_controller.rb | 27 ++++++++++++++++--- app/views/components/_profiles_btn_box.haml | 12 +-------- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index eadc2165..2d834015 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -9,7 +9,7 @@ class ActorModerationsController < ApplicationController authorize actor_moderation # Crea una RemoteFlag si se envían los parámetros adecuados - actor_moderation.update(actor_moderation_params) if actor_event == :report + actor_moderation.update(actor_moderation_params(actor_moderation)) if actor_event == :report actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") @@ -37,7 +37,11 @@ class ActorModerationsController < ApplicationController ActorModeration.transaction do actor_moderations.find_each do |actor_moderation| - actor_moderation.public_send(method) if actor_moderation.public_send(may) + next unless actor_moderation.public_send(may) + + actor_moderation.update(actor_moderation_params(actor_moderation)) if action == :report + + actor_moderation.public_send(method) end end end @@ -48,10 +52,25 @@ class ActorModerationsController < ApplicationController @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end - def actor_moderation_params - params.require(:actor_moderation).permit(remote_flag_attributes: %i[message]).tap do |p| + # @return [String] + def panel_actor_mention + @panel_actor_mention ||= ENV.fetch('PANEL_ACTOR_MENTION', '@sutty@sutty.nl') + end + + # @return [Hash] + def actor_moderation_params(actor_moderation) + { remote_flag_attributes: { id: actor_moderation.remote_flag_id, message: '' } }.tap do |p| p[:remote_flag_attributes][:site_id] = actor_moderation.site_id p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id + + I18n.available_locales.each do |locale| + p[:remote_flag_attributes][:message].tap do |m| + m += I18n.t(locale) + m += ': ' + m += I18n.t('actor_moderations.report_message', locale: locale, panel_actor_mention: panel_actor_mention) + m += '\n\n' + end + end end end end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 3ec95e59..073c142e 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,13 +1,4 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) - -- form_params = {} -- form_params[:report] = { actor_moderation: { remote_flag_attributes: { message: '' } } } -- I18n.available_locales.each do |locale| - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t(locale) - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += ': ' - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t('.report_message', locale: locale, panel_actor_mention: ENV.fetch('PANEL_ACTOR_MENTION') { '@sutty@sutty.nl' }) - - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += '\n\n' - .d-flex.flex-row - btn_class = 'btn-secondary' - ActorModeration.events.each do |actor_event| @@ -15,5 +6,4 @@ text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), - params: form_params[actor_event] + disabled: !actor_moderation.public_send(:"may_#{actor_event}?") diff --git a/config/locales/en.yml b/config/locales/en.yml index a10b9f3a..fe8798f4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -107,7 +107,6 @@ en: text_allow: Always approve text_block: Block text_report: Report - report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." actor_moderations: show: user: Username @@ -117,6 +116,7 @@ en: profile_id: ID profile_published: Published profile_summary: Summary + report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." moderation_queue: everything: 'Select all' nothing: "There's nothing for this filter" diff --git a/config/locales/es.yml b/config/locales/es.yml index f5487e47..e22fdf57 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,7 +106,6 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar - report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." actor_moderations: show: user: Nombre de usuarie @@ -116,6 +115,7 @@ es: profile_id: ID profile_published: Publicada profile_summary: Presentación + report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." moderation_queue: everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' From 67a56c540aff22e01c76a42dbb5c71ba6f414ee6 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Mar 2024 17:45:16 -0300 Subject: [PATCH 587/814] feat: no mostrar opciones que no se pueden ejecutar con el filtro actual --- app/models/concerns/aasm_events_concern.rb | 10 ++++++++++ app/views/components/_comments_checked_submenu.haml | 8 ++++++-- app/views/components/_comments_filters.haml | 7 +++++-- app/views/components/_instances_checked_submenu.haml | 2 +- app/views/components/_instances_filters.haml | 7 +++++-- app/views/components/_profiles_checked_submenu.haml | 2 +- app/views/components/_profiles_filters.haml | 7 +++++-- app/views/moderation_queue/_comments.haml | 2 +- 8 files changed, 34 insertions(+), 11 deletions(-) diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 59ea243f..418368d8 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -11,6 +11,16 @@ module AasmEventsConcern aasm.events.map(&:name) - self::IGNORED_EVENTS end + # Encuentra todos los eventos que se pueden ejecutar con el filtro + # actual. + # + # @return [Array] + def self.transitionable_events(current_state) + self.events.select do |event| + aasm.events.find { |x| x.name == event }.transitions_from_state? current_state + end + end + # Todos los estados de la máquina de estados # # @return [Array] diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml index fa3d7612..a09da426 100644 --- a/app/views/components/_comments_checked_submenu.haml +++ b/app/views/components/_comments_checked_submenu.haml @@ -1,2 +1,6 @@ -- ActivityPub.events.each do |event| - = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event}"), name: 'activity_pub_action', value: event +- current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first + +- ActivityPub.aasm.events.each do |event| + - next if ActivityPub::IGNORED_EVENTS.include? event.name + - next unless event.transitions_from_state?(current_state) + = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event.name}"), name: 'activity_pub_action', value: event.name diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index 15f5173d..35cd5dda 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -1,6 +1,9 @@ +- current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first + .d-flex.py-2 - = render 'components/dropdown', text: t('.text_checked') do - = render 'components/comments_checked_submenu', form_id: form_id + - if ActivityPub.transitionable_events(current_state).present? + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/comments_checked_submenu', form_id: form_id = render 'components/dropdown', text: t('.text_show') do = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index 2d28fb1c..4c45b7ab 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,2 +1,2 @@ -- InstanceModeration.events.each do |event| +- InstanceModeration.transitionable_events(current_state).each do |event| = render 'components/dropdown_button', text: t(".submenu_#{event}"), name: 'instance_moderation_action', value: event, form_id: form_id diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 2c05693a..9e8509c4 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -1,6 +1,9 @@ +- current_state = params[:state]&.to_sym || InstanceModeration.states.first + .d-flex.py-2 - = render 'components/dropdown', text: t('.text_checked') do - = render 'components/instances_checked_submenu', form_id: form_id + - if InstanceModeration.transitionable_events(current_state).present? + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/instances_checked_submenu', form_id: form_id, current_state: current_state = render 'components/dropdown', text: t('.text_show') do = render 'components/instances_show_submenu', site: site diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index 13e016ca..66a0fa78 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,2 +1,2 @@ -- ActorModeration.events.each do |actor_event| +- ActorModeration.transitionable_events(current_state).each do |actor_event| = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event, form_id: form_id diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index a2593f4c..bf7fb48a 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,6 +1,9 @@ +- current_state = params[:actor_state]&.to_sym || ActorModeration.states.first + .d-flex.py-2 - = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu', form_id: form_id + - if ActorModeration.transitionable_events(current_state).present? + = render 'components/dropdown', text: t('.text_checked') do + = render 'components/profiles_checked_submenu', form_id: form_id, current_state: current_state = render 'components/dropdown', text: t('.text_show') do = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index bf1e94a0..436777db 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -5,7 +5,7 @@ .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center = render 'components/select_all', id: 'select-all-comments', form_id: form_id - .col-md-9 + .col-11 -# Filtros = render 'components/comments_filters', activity_pubs: moderation_queue, form_id: form_id .col-12 From ff428c652713c0d412b0660cb5788d274fec71fa Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 14:18:06 -0300 Subject: [PATCH 588/814] feat: poder reportar comentarios --- app/controllers/activity_pubs_controller.rb | 5 +++- .../actor_moderations_controller.rb | 24 +------------------ .../concerns/moderation_concern.rb | 21 ++++++++++++++++ app/jobs/activity_pub/remote_flag_job.rb | 2 +- app/models/activity_pub.rb | 7 ++++++ app/models/activity_pub/remote_flag.rb | 7 +++++- config/locales/en.yml | 1 + config/locales/es.yml | 1 + .../20240305164653_change_remote_flags.rb | 12 ++++++++++ db/structure.sql | 6 +++-- 10 files changed, 58 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20240305164653_change_remote_flags.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 9bbbb9cc..37702d96 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -8,6 +8,7 @@ class ActivityPubsController < ApplicationController define_method(event) do authorize activity_pub + activity_pub.update(remote_flag_params(activity_pub)) if event == :report activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") redirect_to_moderation_queue! @@ -29,7 +30,9 @@ class ActivityPubsController < ApplicationController ActivityPub.transaction do activity_pubs.find_each do |activity_pub| - activity_pub.public_send(method) if activity_pub.public_send(may) + next unless activity_pub.public_send(may) + + activity_pub.public_send(method) end end end diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 2d834015..56adda4a 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -9,7 +9,7 @@ class ActorModerationsController < ApplicationController authorize actor_moderation # Crea una RemoteFlag si se envían los parámetros adecuados - actor_moderation.update(actor_moderation_params(actor_moderation)) if actor_event == :report + actor_moderation.update(remote_flag_params(actor_moderation)) if actor_event == :report actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") @@ -51,26 +51,4 @@ class ActorModerationsController < ApplicationController def actor_moderation @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end - - # @return [String] - def panel_actor_mention - @panel_actor_mention ||= ENV.fetch('PANEL_ACTOR_MENTION', '@sutty@sutty.nl') - end - - # @return [Hash] - def actor_moderation_params(actor_moderation) - { remote_flag_attributes: { id: actor_moderation.remote_flag_id, message: '' } }.tap do |p| - p[:remote_flag_attributes][:site_id] = actor_moderation.site_id - p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id - - I18n.available_locales.each do |locale| - p[:remote_flag_attributes][:message].tap do |m| - m += I18n.t(locale) - m += ': ' - m += I18n.t('actor_moderations.report_message', locale: locale, panel_actor_mention: panel_actor_mention) - m += '\n\n' - end - end - end - end end diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb index 9a4f1c16..5b4c276d 100644 --- a/app/controllers/concerns/moderation_concern.rb +++ b/app/controllers/concerns/moderation_concern.rb @@ -9,5 +9,26 @@ module ModerationConcern def redirect_to_moderation_queue! redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) end + + # @return [String] + def panel_actor_mention + @panel_actor_mention ||= ENV.fetch('PANEL_ACTOR_MENTION', '@sutty@sutty.nl') + end + + def remote_flag_params(model) + { remote_flag_attributes: { id: model.remote_flag_id, message: '' } }.tap do |p| + p[:remote_flag_attributes][:site_id] = model.site_id + p[:remote_flag_attributes][:actor_id] = model.actor_id + + I18n.available_locales.each do |locale| + p[:remote_flag_attributes][:message].tap do |m| + m << I18n.t(locale) + m << ': ' + m << I18n.t('remote_flags.report_message', locale: locale, panel_actor_mention: panel_actor_mention) + m << '\n\n' + end + end + end + end end end diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 332d31ac..30796923 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -13,7 +13,7 @@ class ActivityPub self.priority = 30 def perform(remote_flag:) - client = remote_flag.site.social_inbox.client_for(remote_flag.actor.content['inbox']) + client = remote_flag.site.social_inbox.client_for(remote_flag.actor&.content['inbox']) response = client.post(endpoint: '', body: remote_flag.content) raise 'No se pudo enviar el reporte' unless response.ok? diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 6f0d884c..23f4324f 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -18,12 +18,15 @@ class ActivityPub < ApplicationRecord belongs_to :site belongs_to :object, polymorphic: true belongs_to :actor + belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' has_many :activities validates :site_id, presence: true validates :object_id, presence: true validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported removed] } + accepts_nested_attributes_for :remote_flag + # Encuentra la URI de un objeto # # @return [String, nil] @@ -83,6 +86,10 @@ class ActivityPub < ApplicationRecord # Solo podemos reportarla luego de rechazarla event :report do transitions from: :rejected, to: :reported + + before do + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + end end end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index b790c4b1..a302503b 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -5,6 +5,11 @@ class ActivityPub belongs_to :actor belongs_to :site + has_one :actor_moderation + has_many :activity_pubs + # XXX: source_type es obligatorio para el `through` + has_many :objects, through: :activity_pubs, source_type: 'ActivityPub::Object::Note' + # Genera la actividad a enviar def content { @@ -13,7 +18,7 @@ class ActivityPub 'type' => 'Flag', 'actor' => ENV.fetch('PANEL_ACTOR_ID') { "https://#{ENV['SUTTY']}/about.jsonld" }, 'content' => message.to_s, - 'object' => [ actor.uri ] + 'object' => [ actor.uri ] + objects.pluck(:uri) } end end diff --git a/config/locales/en.yml b/config/locales/en.yml index fe8798f4..0ca90aa7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -116,6 +116,7 @@ en: profile_id: ID profile_published: Published profile_summary: Summary + remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." moderation_queue: everything: 'Select all' diff --git a/config/locales/es.yml b/config/locales/es.yml index e22fdf57..40a1a18c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -115,6 +115,7 @@ es: profile_id: ID profile_published: Publicada profile_summary: Presentación + remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." moderation_queue: everything: 'Seleccionar todo' diff --git a/db/migrate/20240305164653_change_remote_flags.rb b/db/migrate/20240305164653_change_remote_flags.rb new file mode 100644 index 00000000..258f3335 --- /dev/null +++ b/db/migrate/20240305164653_change_remote_flags.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Agrega relaciones en las remote flags +class ChangeRemoteFlags < ActiveRecord::Migration[6.1] + def up + add_column :activity_pubs, :remote_flag_id, :uuid, index: true, null: true + end + + def down + remove_column :activity_pubs, :remote_flag_id + end +end diff --git a/db/structure.sql b/db/structure.sql index ff6cf895..55a5ecb0 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -573,7 +573,8 @@ CREATE TABLE public.activity_pubs ( object_type character varying NOT NULL, aasm_state character varying NOT NULL, instance_id uuid, - actor_id uuid + actor_id uuid, + remote_flag_id uuid ); @@ -2695,6 +2696,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240229201155'), ('20240301181224'), ('20240301194154'), -('20240301202955'); +('20240301202955'), +('20240305164653'); From 054dbc31e03bb7df899e978b988b46a59e41ad18 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 14:19:33 -0300 Subject: [PATCH 589/814] =?UTF-8?q?fix:=20no=20fallar=20si=20la=20activida?= =?UTF-8?q?d=20ya=20hab=C3=ADa=20cambiado=20de=20estado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 464a0ffe..548781fa 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -53,7 +53,7 @@ module Api instance.present? object.present? activity.present? - activity_pub.approve! + activity_pub.approve! if activity_pub.may_approve? end head :accepted @@ -69,7 +69,7 @@ module Api instance.present? object.present? activity.present? - activity_pub.reject! + activity_pub.reject! if activity_pub.may_reject? end head :accepted From 30fd6c28eec100ba8205f468d4fcf5f4f7e2cfea Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 15:46:33 -0300 Subject: [PATCH 590/814] feat: enviar un reporte por actore --- app/controllers/activity_pubs_controller.rb | 14 ++++++++++++++ app/controllers/concerns/moderation_concern.rb | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 37702d96..2b54cacd 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -28,6 +28,20 @@ class ActivityPubsController < ApplicationController return unless ActivityPub.events.include? action + # Crear una sola remote flag por autore + if action == :report + message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message) + + activity_pubs.distinct.pluck(:actor_id).each do |actor_id| + remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id) + remote_flag.message = message + remote_flag.save + # XXX: Idealmente todas las ActivityPub que enviamos pueden + # cambiar de estado, pero chequeamos de todas formas. + remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) }) + end + end + ActivityPub.transaction do activity_pubs.find_each do |activity_pub| next unless activity_pub.public_send(may) diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb index 5b4c276d..3b9d818f 100644 --- a/app/controllers/concerns/moderation_concern.rb +++ b/app/controllers/concerns/moderation_concern.rb @@ -16,7 +16,7 @@ module ModerationConcern end def remote_flag_params(model) - { remote_flag_attributes: { id: model.remote_flag_id, message: '' } }.tap do |p| + { remote_flag_attributes: { id: model.remote_flag_id, message: ''.dup } }.tap do |p| p[:remote_flag_attributes][:site_id] = model.site_id p[:remote_flag_attributes][:actor_id] = model.actor_id From 5b53a9813f163ecffe592be15f5c146eca1fca61 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:00:47 -0300 Subject: [PATCH 591/814] feat: enviar una sola vez el reporte remoto y volver a enviarlo si le agregamos reportes --- app/controllers/activity_pubs_controller.rb | 2 ++ app/jobs/activity_pub/remote_flag_job.rb | 6 ++++++ app/models/activity_pub.rb | 2 +- app/models/activity_pub/remote_flag.rb | 21 +++++++++++++++++++ app/models/actor_moderation.rb | 2 +- ...0240305184854_add_state_to_remote_flags.rb | 8 +++++++ db/structure.sql | 6 ++++-- 7 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20240305184854_add_state_to_remote_flags.rb diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 2b54cacd..c8f86ef0 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -35,6 +35,8 @@ class ActivityPubsController < ApplicationController activity_pubs.distinct.pluck(:actor_id).each do |actor_id| remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id) remote_flag.message = message + # Lo estamos actualizando, con lo que lo vamos a volver a enviar + remote_flag.requeue if remote_flag.persisted? remote_flag.save # XXX: Idealmente todas las ActivityPub que enviamos pueden # cambiar de estado, pero chequeamos de todas formas. diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 30796923..7d8131db 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -13,10 +13,16 @@ class ActivityPub self.priority = 30 def perform(remote_flag:) + return if remote_flag.can_queue? + + remote_flag.queue! + client = remote_flag.site.social_inbox.client_for(remote_flag.actor&.content['inbox']) response = client.post(endpoint: '', body: remote_flag.content) raise 'No se pudo enviar el reporte' unless response.ok? + + remote_flag.send! rescue Exception => e ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response }) raise diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 23f4324f..b07fe790 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -88,7 +88,7 @@ class ActivityPub < ApplicationRecord transitions from: :rejected, to: :reported before do - ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index a302503b..25f1b743 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -2,6 +2,27 @@ class ActivityPub class RemoteFlag < ApplicationRecord + include AASM + include AasmEventsConcern + + aasm do + state :waiting, initial: true + state :queued + state :sent + + event :queue do + transitions from: :waiting, to: :queued + end + + event :send do + transitions from: :queued, to: :sent + end + + event :resend do + transitions from: :sent, to: :waiting + end + end + belongs_to :actor belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 421d4c6e..d7eea709 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -59,7 +59,7 @@ class ActorModeration < ApplicationRecord transitions from: %i[blocked], to: :reported before do - ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end end diff --git a/db/migrate/20240305184854_add_state_to_remote_flags.rb b/db/migrate/20240305184854_add_state_to_remote_flags.rb new file mode 100644 index 00000000..7ff78dfb --- /dev/null +++ b/db/migrate/20240305184854_add_state_to_remote_flags.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Estado de los reportes remotos +class AddStateToRemoteFlags < ActiveRecord::Migration[6.1] + def change + add_column :activity_pub_remote_flags, :aasm_state, :string, null: false, default: 'waiting' + end +end diff --git a/db/structure.sql b/db/structure.sql index 55a5ecb0..97bd372e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -556,7 +556,8 @@ CREATE TABLE public.activity_pub_remote_flags ( updated_at timestamp(6) without time zone NOT NULL, site_id bigint, actor_id uuid, - message text + message text, + aasm_state character varying DEFAULT 'waiting'::character varying NOT NULL ); @@ -2697,6 +2698,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240301181224'), ('20240301194154'), ('20240301202955'), -('20240305164653'); +('20240305164653'), +('20240305184854'); From b1dee5d5676954610fd54e52ab00c0cfd9bb90e4 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:10:06 -0300 Subject: [PATCH 592/814] fix: dejar de cargar datos de prueba --- app/controllers/application_controller.rb | 10 - .../moderation_queue_controller.rb | 8 - config/routes.rb | 1 - db/seeds/blocklists.yml | 7 - db/seeds/instances.yaml | 285 ------------------ db/seeds/moderation_queue.yaml | 153 ---------- db/seeds/remote_profile.yaml | 106 ------- 7 files changed, 570 deletions(-) delete mode 100644 db/seeds/blocklists.yml delete mode 100644 db/seeds/instances.yaml delete mode 100644 db/seeds/moderation_queue.yaml delete mode 100644 db/seeds/remote_profile.yaml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b55176ec..05fa98e9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,16 +27,6 @@ class ApplicationController < ActionController::Base end private - # Traer datos de muestra de la cola de moderación - def dummy_data - @moderation_queue = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'moderation_queue.yaml'))) - @remote_profile = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'remote_profile.yaml'))) - @instances = YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'instances.yaml'))) - @blocklists= YAML.safe_load(File.read(Rails.root.join('db', 'seeds', 'blocklists.yml'))) - @moderation_queue.each do |activity| - activity['attributedTo'] = @remote_profile - end - end def notify_unconfirmed_email return unless current_usuarie diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 6a628aaa..0df62499 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -4,8 +4,6 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index - dummy_data - session[:moderation_queue_filters] = params.permit(:state, :actor_state, :activity_pub_state) # @todo cambiar el estado por query @@ -14,10 +12,4 @@ class ModerationQueueController < ApplicationController @actor_moderations = rubanok_process(site.actor_moderations, with: ActorModerationProcessor) @moderation_queue = rubanok_process(site.activity_pubs, with: ActivityPubProcessor) end - - # todon.nl está usando /api/v2/instance - # mauve.moe usa /api/v1/instance - def instances - dummy_data - end end diff --git a/config/routes.rb b/config/routes.rb index 8809767b..054b7f4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -63,7 +63,6 @@ Rails.application.routes.draw do post 'collaborate', to: 'collaborations#accept_collaboration' get 'moderation_queue', to: 'moderation_queue#index' - get 'instances', to: 'moderation_queue#instances' resources :instance_moderations, only: [] do patch :pause, to: 'instance_moderations#pause' diff --git a/db/seeds/blocklists.yml b/db/seeds/blocklists.yml deleted file mode 100644 index 54dfe6c9..00000000 --- a/db/seeds/blocklists.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- id: gardenfence - title: Gardenfence - link: 'https://gardenfence.github.io/' -- id: lista - title: Lista - link: '#' diff --git a/db/seeds/instances.yaml b/db/seeds/instances.yaml deleted file mode 100644 index bf326832..00000000 --- a/db/seeds/instances.yaml +++ /dev/null @@ -1,285 +0,0 @@ ---- -- domain: todon.nl - title: Todon.nl - version: 4.2.3 - source_url: https://github.com/mastodon/mastodon - description: Radicaal linkse anti-autoritaire server. Voor anarchisten, socialisten, - (klimaat)activisten, LHBTQIA+, antiracisten, antifascisten, antikapitalisten, - intersectionelen, veganisten, mensenrechten, enz. - usage: - users: - active_month: 372 - thumbnail: - url: https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png - blurhash: UXAw3zN4M|xsoga#WBay9DxntQRmITocofWE - versions: - "@1x": https://todon.nl/system/site_uploads/files/000/000/004/@1x/297e509bc8a81f62.png - "@2x": https://todon.nl/system/site_uploads/files/000/000/004/@2x/297e509bc8a81f62.png - languages: - - en - configuration: - urls: - streaming: wss://todon.nl - status: https://status.todon.eu - accounts: - max_featured_tags: 10 - statuses: - max_characters: 1312 - max_media_attachments: 4 - characters_reserved_per_url: 23 - media_attachments: - supported_mime_types: - - image/jpeg - - image/png - - image/gif - - image/heic - - image/heif - - image/webp - - image/avif - - video/webm - - video/mp4 - - video/quicktime - - video/ogg - - audio/wave - - audio/wav - - audio/x-wav - - audio/x-pn-wave - - audio/vnd.wave - - audio/ogg - - audio/vorbis - - audio/mpeg - - audio/mp3 - - audio/webm - - audio/flac - - audio/aac - - audio/m4a - - audio/x-m4a - - audio/mp4 - - audio/3gpp - - video/x-ms-asf - image_size_limit: 16777216 - image_matrix_limit: 33177600 - video_size_limit: 103809024 - video_frame_rate_limit: 120 - video_matrix_limit: 8294400 - polls: - max_options: 4 - max_characters_per_option: 50 - min_expiration: 300 - max_expiration: 2629746 - translation: - enabled: true - registrations: - enabled: false - approval_required: false - message: | -

      ¡No pasarán!

      - -

      Je kunt tijdelijk geen nieuw account op Todon.nl aanvragen.

      - - - -

      Ga naar joinmastodon.org of FediDB Network om een andere server te vinden.

      - -

      It is temporary not possible to request on account on Todon.nl.

      - - - -

      Go to joinmastodon.org or FediDB Network to find another server.

      - url: - max_toot_chars: 1312 - contact: - email: todon@posteo.eu - account: - id: '1' - username: admin - acct: admin - display_name: "Admin \U0001F913 Todon.nl (mod)" - locked: false - bot: false - discoverable: false - group: false - created_at: '2017-04-28T00:00:00.000Z' - note: "

      This account is used for \U0001F399 Todon.nl announcements and ⚖️ - moderation.

      \U0001F6AB Don't follow this account when you are not - on Todon.nl.

      New? First read our \U0001F469‍\U0001F3EB Todon 101 \U0001F469‍\U0001F393 - at https://wiki.todon.eu/todon/101

      ⚖️ - For all our moderators go to https://wiki.todon.nl/todon/moderators

      \U0001F4DD Public toots from this account - are in English.

      \U0001F515 Criticism is fine, but people who do false - accusations are muted.

      ✉ todon@posteo.eu

      #nobot

      " - url: https://todon.nl/@admin - uri: https://todon.nl/users/admin - avatar: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png - avatar_static: https://todon.nl/system/accounts/avatars/000/000/001/original/2db61726225ed3e6.png - header: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png - header_static: https://todon.nl/system/accounts/headers/000/000/001/original/fb3a846cbc20aa09.png - followers_count: 3164 - following_count: 8 - statuses_count: 724 - last_status_at: '2024-01-12' - noindex: true - emojis: [] - roles: - - id: '3' - name: Admin - color: "#595aff" - fields: - - name: "\U0001F4DC Terms of Service" - value: wiki.todon.nl/todon/terms_en - verified_at: '2018-11-01T14:39:45.465+00:00' - - name: ℹ️ Wiki - value: wiki.todon.nl/todon/informatio - verified_at: '2018-11-01T14:40:54.679+00:00' - - name: "\U0001F4CA Status" - value: status.todon.eu - verified_at: '2023-10-26T20:38:30.185+00:00' - - name: "\U0001F4B3️ Donations" - value: wiki.todon.eu/todon/donations - verified_at: '2022-11-02T00:06:31.865+00:00' - rules: - - id: '1' - text: We do not accept racism (in all its forms, incl. hate against Muslims, antisemitism, - apartheid and casteism - see our Terms of Service for our complete definition). - - id: '2' - text: We do not accept hate against lesbians, gays, bisexuals, pansexuals, transgenders, - non-binary people, intersexual people, queer people in general, etc. - - id: '4' - text: Sexism, misogyny and hate against black women (misogynoir). - - id: '6' - text: We do not accept ableism (incl. COVID-19 denial/downplaying and anti-vax) - and body-shaming. - - id: '8' - text: We do not accept harassment and trolling. - - id: '10' - text: We also do not accept other forms of hate speech. - - id: '11' - text: We do not accept (sexual) abuse of minors, adults and animals (also not - virtual). - - id: '13' - text: We do not accept glorification of violence, calls for murder, death threats, - terrorism and militarism. - - id: '15' - text: We do not accept (neo)colonialism (incl. Zionism), imperialism in all forms - and nationalism (above all nationalism of nation states, incl. flags/symbols - of those on Todon.*, see our Terms of Service). - - id: '16' - text: We do not accept fascism, right-wing populism, and right-wing and religious - extremism. - - id: '17' - text: We do not accept evangelisation and other forms of religious propaganda - [local only], and extreme sects and cults. - - id: '19' - text: We do not accept Marxist-Leninists, Stalinists, Maoists or other followers - of extreme authoritarian (so called) communist/socialist ideologies/regimes - (aka tankies). - - id: '20' - text: We do not accept capitalists, including so called 'anarcho-capitalists' - (aka ancaps) and neoliberals. - - id: '21' - text: We do not accept anthropogenic climate change denial, downplaying the climate - crisis, greenwashing and deceptive climate solutions (like nuclear energy). - - id: '27' - text: We do not accept (right-wing) conspiracy 'theories', hoaxes, fake news and - other forms of disinformation. - - id: '28' - text: Another rule in our terms of service at wiki.todon.eu/todon/terms_en. Explain - in the final step. -- uri: mastodon.mauve.moe - title: Mauvestodon - short_description: Escape ship from centralized social media run by Mauve. - description: Chat about random techie and anarchist stuff. - email: contact@mauve.moe - version: 3.5.10 - urls: - streaming_api: wss://mastodon.mauve.moe - stats: - user_count: 12 - status_count: 3287 - domain_count: 11625 - thumbnail: https://mastodon.mauve.moe/system/site_uploads/files/000/000/001/original/mauvesoftwareinc.png - languages: - - en - registrations: false - approval_required: false - invites_enabled: true - configuration: - statuses: - max_characters: 500 - max_media_attachments: 4 - characters_reserved_per_url: 23 - media_attachments: - supported_mime_types: - - image/jpeg - - image/png - - image/gif - - video/webm - - video/mp4 - - video/quicktime - - video/ogg - - audio/wave - - audio/wav - - audio/x-wav - - audio/x-pn-wave - - audio/ogg - - audio/vorbis - - audio/mpeg - - audio/mp3 - - audio/webm - - audio/flac - - audio/aac - - audio/m4a - - audio/x-m4a - - audio/mp4 - - audio/3gpp - - video/x-ms-asf - image_size_limit: 10485760 - image_matrix_limit: 16777216 - video_size_limit: 41943040 - video_frame_rate_limit: 60 - video_matrix_limit: 2304000 - polls: - max_options: 4 - max_characters_per_option: 50 - min_expiration: 300 - max_expiration: 2629746 - contact_account: - id: '1' - username: admin - acct: admin - display_name: '' - locked: false - bot: false - discoverable: true - group: false - created_at: '2022-04-25T00:00:00.000Z' - note: '' - url: https://mastodon.mauve.moe/@admin - avatar: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png - avatar_static: https://mastodon.mauve.moe/system/accounts/avatars/000/000/001/original/8c21e71667b48a95.png - header: https://mastodon.mauve.moe/headers/original/missing.png - header_static: https://mastodon.mauve.moe/headers/original/missing.png - followers_count: 0 - following_count: 0 - statuses_count: 0 - last_status_at: '2023-01-30' - emojis: [] - fields: - - name: Alternatel Contact - value: @mauve - verified_at: - rules: [] diff --git a/db/seeds/moderation_queue.yaml b/db/seeds/moderation_queue.yaml deleted file mode 100644 index c7075c7e..00000000 --- a/db/seeds/moderation_queue.yaml +++ /dev/null @@ -1,153 +0,0 @@ ---- -- "@context": - - https://www.w3.org/ns/activitystreams - - ostatus: http://ostatus.org# - atomUri: ostatus:atomUri - inReplyToAtomUri: ostatus:inReplyToAtomUri - conversation: ostatus:conversation - sensitive: as:sensitive - toot: http://joinmastodon.org/ns# - votersCount: toot:votersCount - Hashtag: as:Hashtag - id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 - type: Note - summary: - inReplyTo: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 - published: '2023-11-23T22:50:10Z' - url: https://mastodon.mauve.moe/@mauve/111462305634770041 - attributedTo: https://mastodon.mauve.moe/users/mauve - to: - - https://www.w3.org/ns/activitystreams#Public - cc: - - https://mastodon.mauve.moe/users/mauve/followers - - https://hypha.coop/about.jsonld - sensitive: false - atomUri: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041 - inReplyToAtomUri: https://mastodon.mauve.moe/users/mauve/statuses/111461923538534886 - conversation: tag:mastodon.mauve.moe,2023-11-23:objectId=551471:objectType=Conversation - content:

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      -

      - contentMap: - en:

      Follow @HyphaCoop@hypha.coop for our announcement post on the 5th!

      -

      - attachment: [] - tag: - - type: Mention - href: https://hypha.coop/about.jsonld - name: "@dripline@hypha.coop" - - type: Hashtag - href: https://mastodon.mauve.moe/tags/p2p - name: "#p2p" - - type: Hashtag - href: https://mastodon.mauve.moe/tags/activitypub - name: "#activitypub" - - type: Hashtag - href: https://mastodon.mauve.moe/tags/fediverse - name: "#fediverse" - replies: - id: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies - type: Collection - first: - type: CollectionPage - next: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies?only_other_accounts=true&page=true - partOf: https://mastodon.mauve.moe/users/mauve/statuses/111462305634770041/replies - items: [] -- "@context": - - https://www.w3.org/ns/activitystreams - - "@language": es - sensitive: as:sensitive - type: Note - id: https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/ - summary: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty - published: '2023-12-04T21:53:05+00:00' - updated: '2023-12-05T20:41:34+00:00' - attributedTo: https://sutty.nl/about.jsonld - to: - - https://www.w3.org/ns/activitystreams#Public - cc: - - https://social.distributed.press/v1/@sutty@sutty.nl/followers - inReplyTo: https://hypha.coop/dripline/announcing-dp-social-inbox/ - sensitive: true - content: | -

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        -
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. -
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. -

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        -
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • -
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • -
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • -
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • -
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • -
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • -

      Qué permite hacer

        -
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • -
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • -
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • -
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • -
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • -

      Qué se viene

        -
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • -
      • Incorporación de menciones desde el panel de Sutty.

      • -
      • Mejoras en la interfaz general del panel.

      • -
      • Nuevas implementaciones para una mejor moderación.

      • -
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • -
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • -
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • -
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • -
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • -
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • -

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      - name: Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty - contentMap: - es: | -

      Estamos felices y orgulloses de anunciar el lanzamiento de la funcionalidad que permite la publicación en el Fediverso de los artículos de todos los sitios creados a través de Sutty.

      Gracias al trabajo conjunto con Distributed Press, Hypha y apoyado por la Filecoin Foundation for the Distributed Web, Sutty hace posible que la seguridad de tu sitio estático se combine con la rápida difusión de tu contenido a través de las redes sociales libres y descentralizadas que constituyen el Fediverso.

      Esto se logró a través del desarollo y la integración de dos componentes, trabajados en forma conjunta y colaborativa:

        -
      1. Social Inbox, desarrollado principalmente Distributed Press. Aporta la funcionalidad de recibir artículos, responder y mencionar otras cuentas en el Fediverso.

      2. -
      3. Jekyll Activity Pub Plugin, desarrollado principalmente por Sutty. Permite integrar Social Inbox en todos los sitios estáticos generados en Jekyll, admitiendo así la publicación automática de contenido del sitio en el Fediverso.

      4. -

      Sutty integra la funcionalidad completa en su CMS para sitios estáticos en Jekyll, permitiendo gestionarla desde una interfaz en continua mejora de su usabilidad.

      Si todavía no estás familiarizade con estos nombres y conceptos, te invitamos a conocer más a continuación, en la sección “Para tecno-curioses”.

      Qué significa

        -
      • Que si creás tu sitio web a través de Sutty, tenés nuevas posibilidades de difundir tus contenidos e interactuar en redes digitales.

      • -
      • Que tus artículos pueden ser publicados en las redes del Fediverso.

      • -
      • Que tu sitio tendrá un perfil o usuarie personalizable desde el panel en una instancia de Sutty propia.

      • -
      • Que les usuaries del Fediverso pueden seguir tus publicaciones.

      • -
      • Que les usuaries del Fediverso que te sigan podrán leer tus publicaciones, mencionarte y responderte.

      • -
      • Que podrás interactuar con les usuaries del Fediverse con las opciones de responderles y mencionarles.

      • -

      Qué permite hacer

        -
      • Activar la publicación en el Fediverso para todos los sitios de Sutty.

      • -
      • Activar la publicación de los artículos que quieras en el Fediverso.

      • -
      • Responder comentarios desde los artículos de tu sitio en Sutty.

      • -
      • Personalizar la cuenta que Sutty crea automáticamente de tu sitio en el Fediverso.

      • -
      • Reportar o informar de usuaries o instancias abusivos mediante nuestro formulario de contacto.

      • -

      Qué se viene

        -
      • Mejoras en la integración de las respuestas como comentarios en el sitio.

      • -
      • Incorporación de menciones desde el panel de Sutty.

      • -
      • Mejoras en la interfaz general del panel.

      • -
      • Nuevas implementaciones para una mejor moderación.

      • -
      • Mejor compatibilidad con diversas redes en el Fediverso (Mastodon+Glitch, Pleroma, Ktistec).

      • -
      • Mejoras que permitirán diferenciar el contenido a publicar en el Fediverso y en el sitio de Sutty.

      • -
      • La posibilidad de exportar tu cuenta a una instancia del Fediverso desde tu panel.

      • -
      • La posibilidad de que Sutty anuncie tu contenido y/o usuarie del Fediverse en forma automática para atraer seguidorxs. (Ahora, podés hacerlo a través de un formulario).

      • -
      • Acceder a la lista de seguidorxs y seguides desde tu panel.

      • -
      • Seguir, dejar de seguir, bloquear usuaries y/o instancias del Fediverso desde el panel.

      • -

      ¡Quiero usarlo!

      Te invitamos a dar tus primeros pasos de la mano de nuestro tutorial.

      Para tecno-curioses

      Cómo funciona

      Los sitios web y las redes sociales parecen ser especies distintas dentro del Universo de Internet. Al mismo tiempo, las redes sociales corporativas y concentradas como Instagram, Facebook, X (ex Twitter), entre otras, demostraron ser hostiles con algunos grupos o colectivos sociales en particular (censurando contenido, persiguiendo pezones, ocultando publicaciones por color de piel y de pelo, etc.) y con todes sus usuaries en general (vendiendo data en forma masiva, violando acuerdos de privacidad, eligiendo diseños de interfaz y uso que generan ansiedad y adicción, etc.). Pese a esto, siguen funcionando como espacios obligados a la hora de publicitar un emprendimiento o difundir noticias urgentes.

      El Fediverso es una red federada, descentralizada y distribuida de redes sociales libres, cada una con sus características, preferencias, grupos de usuaries. Están diseñadas para facilitar el diálogo entre todas ellas. Es decir, para que los contenidos puedan ser visibles y se puedan generar respuestas entre usuaries, fomentando una cultura de participación y pluralidad de voces, basadas en estándares de desarrollo libre y que buscan ser éticos antes que con fines de lucro sin fin.

      Los sitios web siguen siendo formatos para medios de comunicación que, debido a sus características, favorecen la difusión de contenidos como artículos multimedia. Permiten adecuar un estilo a una identidad visual del medio, mantener secciones y contenido institucional variado, entre otras cosas.

      Las redes sociales se destacan por sus características de inmediatez, favoreciendo un flujo dialógico en tiempo real con otros tiempos de atención y características de navegación que lo hacen más breve, rápido, a veces efímero. Los medios de comunicación (personas o emprendimientos mediáticos) suelen utilizarlos para llamar la atención sobre contenidos publicados en sus sitios, apostando a la divulgación rápida y las discusiones que puedan darse entre usuaries.

      La funcionalidad que desarrollamos en Sutty contempla los casos de uso en los que un contenido quiera ser compartido a más personas, en menor tiempo, con la posibilidad de generar diálogos. Las particularidades de nuestros sitios y redes sociales libres generan condiciones favorables para la libertad de expresión, que preferimos llamar Derecho a la Comunicación, evadiendo las variadas y cada vez más sofisticadas formas de censura de las plataformas corporativas tradicionales. Un contenido reproducido en varios lugares al mismo tiempo ayuda a su divulgación y es ideal para aquellas voces y discursos contrahegemónicos en la web y su supervivencia al paso del tiempo, preservando la memoria popular.

      Cómo funciona el Fediverso en la moderación

      El Fediverso intenta funcionar como comunidades en línea interconectadas que se autogobiernan en las formas de cuidados colectivos. Así, cada instancia podría ser algo así como un municipio que aloja diferentes cuentas/usuaries bajo unas reglas consensuadas y que pueden ser puestas en discusión si fuera necesario. De esta forma, es posible regular la circulación de contenidos fascistas y discursos de odio que puedan dañar no solamente la participación de diverses usuaries sino también su salud.

      Para ello, cada instancia elige sus formas de moderación y puede excluir otras instancias con denuncias previas de contenidos antidemocráticos, odiantes o contrarios a los valores y cuidados de sus habitantes.

      En Sutty en particular, nos interesan las estrategias y los mecanismos de cuidados colectivos, por lo que seguimos diseñando modelos que permitan sostenerlos en nuestras tecnologías. Podés revisar nuestros términos y condiciones, política de privacidad y acuerdos de convivencia para más información.

      ¿Te interesa participar?

      Si sos parte de una organización social, grupo de activismo o colectivo social que pensás que podría beneficiarse de estas características, te invitamos a contactarnos a través de nuestro formulario. Estamos busando mejorar los usos de las tecnologías para ustedes y valoramos sus experiencias.

      Otras posibilidades de integración de Social Inbox en sitios estáticos

      Si te interesa incorporar esta funcionalidad para otros gestores de sitios estáticos, no dudes en contactarnos. Además, mantenete al tanto de las novedades que compartimos en https://dweb.sutty.nl y en nuestro blog https://sutty.nl/blog

      Recomendado para saber más

      - attachment: - - type: Document - mediaType: image/png - url: https://sutty.nl/public/8r7b6ohqy6xzgngxbol6337q8jj9/milestone_2_activity_pub_2.png - name: Botones de colores para activar la "Web Disribuida" y el "Fediverso". diff --git a/db/seeds/remote_profile.yaml b/db/seeds/remote_profile.yaml deleted file mode 100644 index 1a670d6b..00000000 --- a/db/seeds/remote_profile.yaml +++ /dev/null @@ -1,106 +0,0 @@ ---- -"@context": -- https://www.w3.org/ns/activitystreams -- https://w3id.org/security/v1 -- manuallyApprovesFollowers: as:manuallyApprovesFollowers - toot: http://joinmastodon.org/ns# - featured: - "@id": toot:featured - "@type": "@id" - featuredTags: - "@id": toot:featuredTags - "@type": "@id" - alsoKnownAs: - "@id": as:alsoKnownAs - "@type": "@id" - movedTo: - "@id": as:movedTo - "@type": "@id" - schema: http://schema.org# - PropertyValue: schema:PropertyValue - value: schema:value - discoverable: toot:discoverable - Device: toot:Device - Ed25519Signature: toot:Ed25519Signature - Ed25519Key: toot:Ed25519Key - Curve25519Key: toot:Curve25519Key - EncryptedMessage: toot:EncryptedMessage - publicKeyBase64: toot:publicKeyBase64 - deviceId: toot:deviceId - claim: - "@type": "@id" - "@id": toot:claim - fingerprintKey: - "@type": "@id" - "@id": toot:fingerprintKey - identityKey: - "@type": "@id" - "@id": toot:identityKey - devices: - "@type": "@id" - "@id": toot:devices - messageFranking: toot:messageFranking - messageType: toot:messageType - cipherText: toot:cipherText - suspended: toot:suspended - focalPoint: - "@container": "@list" - "@id": toot:focalPoint -id: https://mastodon.mauve.moe/users/mauve -type: Person -following: https://mastodon.mauve.moe/users/mauve/following -followers: https://mastodon.mauve.moe/users/mauve/followers -inbox: https://mastodon.mauve.moe/users/mauve/inbox -outbox: https://mastodon.mauve.moe/users/mauve/outbox -featured: https://mastodon.mauve.moe/users/mauve/collections/featured -featuredTags: https://mastodon.mauve.moe/users/mauve/collections/tags -preferredUsername: mauve -name: "Mauve \U0001F441\U0001F49C" -summary: "

      Occult Enby that's making local-first software with peer to peer - protocols, mesh networks, and the web.

      Also exploring what a local-first - cyberspace might look like in my spare time.

      " -url: https://mastodon.mauve.moe/@mauve -manuallyApprovesFollowers: false -discoverable: true -published: '2022-04-25T00:00:00Z' -devices: https://mastodon.mauve.moe/users/mauve/collections/devices -alsoKnownAs: -- https://infosec.exchange/users/RangerMauve -publicKey: - id: https://mastodon.mauve.moe/users/mauve#main-key - owner: https://mastodon.mauve.moe/users/mauve - publicKeyPem: | - -----BEGIN PUBLIC KEY----- - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjxu6bRQOjH4caQu7JgZ - umIWFeX0ZdbVnofElev2d9JByqcDoWhmaks3RYdW71RDPNrr0JxqZvUbIw9kQBng - 7iQ9YTcXTdJ/N9CQoB22msffYkEIw4ilehCDXdchNs4aoVAUwI8IhkM0p/itz6gK - 75C3CQv74Y7rHUJC8ob2p4KUwRUyhgzyhp8QWwCAn/RZ28wP8EbjWF9IskMRo9vq - WUX+Io6hpADRkSwZGoOSW2zxCEBVco6tRmABTte8I0WcAucLyMEyfGMlUvxRew4D - zAWoEBS8SyqM68vUabbZYLns6kya34tvsf1NkvajDGrfgU3D0LlGX++tOa6N9Pkf - XwIDAQAB - -----END PUBLIC KEY----- -tag: [] -attachment: -- type: PropertyValue - name: Pronouns - value: they/them/it -- type: PropertyValue - name: Email - value: mauve@mauve.moe -- type: PropertyValue - name: Matrix - value: @mauve:mauve.moe -- type: PropertyValue - name: Github/Twitter - value: "@RangerMauve" -endpoints: - sharedInbox: https://mastodon.mauve.moe/inbox -icon: - type: Image - mediaType: image/png - url: https://mastodon.mauve.moe/system/accounts/avatars/000/000/002/original/e4b910cee121b1b8.png -image: - type: Image - mediaType: image/png - url: https://mastodon.mauve.moe/system/accounts/headers/000/000/002/original/a96f990025091662.png From 2df9f721cd4b9f6831f8f891aad1f4c08785f295 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:10:53 -0300 Subject: [PATCH 593/814] =?UTF-8?q?feat:=20ver=20los=20art=C3=ADculos=20de?= =?UTF-8?q?=20le=20actore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/actor_moderations_controller.rb | 1 + app/views/actor_moderations/show.haml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 56adda4a..00874321 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -20,6 +20,7 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show @remote_profile = actor_moderation.actor.content + @moderation_queue = site.activity_pubs.where(actor_id: actor_moderation.actor_id) end def action_on_several diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml index 7b62f672..633c1be5 100644 --- a/app/views/actor_moderations/show.haml +++ b/app/views/actor_moderations/show.haml @@ -4,5 +4,5 @@ = render 'components/actor', remote_profile: @remote_profile .col-12.col-md-8 = render 'components/profiles_btn_box', actor_moderation: @actor_moderation - -# - = render 'moderation_queue/comments', moderation_queue: @moderation_queue + .col-12.col-md-8 + = render 'moderation_queue/comments', moderation_queue: @moderation_queue From 0da69de6a73543d90c032b09bd04b74be5c8cbef Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Mar 2024 16:24:16 -0300 Subject: [PATCH 594/814] feat: filtros comunes --- app/controllers/actor_moderations_controller.rb | 3 ++- .../concerns/moderation_filters_concern.rb | 15 +++++++++++++++ app/controllers/moderation_queue_controller.rb | 4 ++-- app/processors/instance_moderation_processor.rb | 4 ++-- app/views/components/_comments_show_submenu.haml | 2 +- app/views/components/_dropdown_item.haml | 2 +- app/views/components/_instances_filters.haml | 2 +- app/views/components/_instances_show_submenu.haml | 7 ++++--- app/views/components/_profiles_show_submenu.haml | 2 +- app/views/moderation_queue/_instances.haml | 2 +- 10 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 app/controllers/concerns/moderation_filters_concern.rb diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 00874321..6b924677 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -3,6 +3,7 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController include ModerationConcern + include ModerationFiltersConcern ActorModeration.events.each do |actor_event| define_method(actor_event) do @@ -20,7 +21,7 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show @remote_profile = actor_moderation.actor.content - @moderation_queue = site.activity_pubs.where(actor_id: actor_moderation.actor_id) + @moderation_queue = rubanok_process(site.activity_pubs.where(actor_id: actor_moderation.actor_id), with: ActivityPubProcessor) end def action_on_several diff --git a/app/controllers/concerns/moderation_filters_concern.rb b/app/controllers/concerns/moderation_filters_concern.rb new file mode 100644 index 00000000..25293a4f --- /dev/null +++ b/app/controllers/concerns/moderation_filters_concern.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ModerationFiltersConcern + extend ActiveSupport::Concern + + included do + before_action :store_filters_in_session!, only: %i[index show] + + private + + def store_filters_in_session! + session[:moderation_queue_filters] = params.permit(:instance_state, :actor_state, :activity_pub_state) + end + end +end diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 0df62499..eebd9eae 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -2,10 +2,10 @@ # Cola de moderación de ActivityPub class ModerationQueueController < ApplicationController + include ModerationFiltersConcern + # Cola de moderación viendo todo el sitio def index - session[:moderation_queue_filters] = params.permit(:state, :actor_state, :activity_pub_state) - # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) diff --git a/app/processors/instance_moderation_processor.rb b/app/processors/instance_moderation_processor.rb index 908beaf7..eb9a7c8b 100644 --- a/app/processors/instance_moderation_processor.rb +++ b/app/processors/instance_moderation_processor.rb @@ -6,7 +6,7 @@ class InstanceModerationProcessor < Rubanok::Processor raw.includes(:instance).order('activity_pub_instances.hostname') end - map :state, activate_always: true do |state: 'paused'| - raw.where(aasm_state: state) + map :instance_state, activate_always: true do |instance_state: 'paused'| + raw.where(aasm_state: instance_state) end end diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml index eb037975..60c02501 100644 --- a/app/views/components/_comments_show_submenu.haml +++ b/app/views/components/_comments_show_submenu.haml @@ -1,4 +1,4 @@ - ActivityPub.states.each do |state| = render 'components/dropdown_item', text: t(".submenu_#{state}", count: activity_pubs.unscope(where: :aasm_state).public_send(state).count), - path: site_moderation_queue_path(filter_states(activity_pub_state: state)) + path: filter_states(activity_pub_state: state) diff --git a/app/views/components/_dropdown_item.haml b/app/views/components/_dropdown_item.haml index 3f79403d..e5b16950 100644 --- a/app/views/components/_dropdown_item.haml +++ b/app/views/components/_dropdown_item.haml @@ -1,4 +1,4 @@ -# @param :text [String] Contenido del link - @param :path [String] Link + @param :path [String,Hash] Link = link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' } diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 9e8509c4..2c23fd72 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -6,4 +6,4 @@ = render 'components/instances_checked_submenu', form_id: form_id, current_state: current_state = render 'components/dropdown', text: t('.text_show') do - = render 'components/instances_show_submenu', site: site + = render 'components/instances_show_submenu', instance_moderations: instance_moderations diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index 811d65c7..c56df547 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,3 +1,4 @@ -= render 'components/dropdown_item', text: t('.submenu_paused', count: site.instance_moderations.paused.count), path: site_moderation_queue_path(state: 'paused') -= render 'components/dropdown_item', text: t('.submenu_allowed', count: site.instance_moderations.allowed.count), path: site_moderation_queue_path(state: 'allowed') -= render 'components/dropdown_item', text: t('.submenu_blocked', count: site.instance_moderations.blocked.count), path: site_moderation_queue_path(state: 'blocked') +- InstanceModeration.states.each do |state| + = render 'components/dropdown_item', + text: t(".submenu_#{state}", count: instance_moderations.unscope(where: :aasm_state).public_send(state).count), + path: filter_states(instance_state: state) diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 0209ef2f..99694698 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,4 +1,4 @@ - ActorModeration.states.each do |actor_state| = render 'components/dropdown_item', text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), - path: site_moderation_queue_path(filter_states(actor_state: actor_state)) + path: filter_states(actor_state: actor_state) diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index d9db967f..3954ce65 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -7,7 +7,7 @@ = render 'components/select_all', id: 'instances', form_id: form_id .col-11 -# Filtros - = render 'components/instances_filters', site: site, form_id: form_id + = render 'components/instances_filters', instance_moderations: instance_moderations, form_id: form_id .col-12 - if instance_moderations.count.zero? From 053ec5674fc5af393a0cceb0a4ca21f2d93c4f98 Mon Sep 17 00:00:00 2001 From: Sutty Date: Wed, 6 Mar 2024 15:30:50 +0000 Subject: [PATCH 595/814] =?UTF-8?q?fix:=20no=20cambiar=20el=20hostname=20s?= =?UTF-8?q?i=20se=20lo=20asign=C3=B3=20manualmente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 48defa9058a5b8980ad89c7e53afffd63416ca83) --- app/models/deploy_distributed_press.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index da8fe209..f80024e8 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -128,6 +128,8 @@ class DeployDistributedPress < Deploy # # @return [nil] def create_remote_site! + self.hostname ||= site.hostname + created_site = site_client.create(create_site) self.remote_site_id = created_site[:id] From 4081f62ad104706b37c21fc0c46a36ce8360f660 Mon Sep 17 00:00:00 2001 From: Sutty Date: Wed, 6 Mar 2024 15:31:40 +0000 Subject: [PATCH 596/814] =?UTF-8?q?fix:=20gitlab=20solo=20acepta=20200=20c?= =?UTF-8?q?aracteres=20en=20el=20t=C3=ADtulo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 6ea20a4d55ed6b52bc7321e2f0f18e851c97aa45) --- app/jobs/gitlab_notifier_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/gitlab_notifier_job.rb b/app/jobs/gitlab_notifier_job.rb index 308adfc7..77e865a3 100644 --- a/app/jobs/gitlab_notifier_job.rb +++ b/app/jobs/gitlab_notifier_job.rb @@ -105,7 +105,7 @@ class GitlabNotifierJob < ApplicationJob def title @title ||= ''.dup.tap do |t| t << "[#{exception.class}] " unless javascript? - t << exception.message + t << exception.message[0..200] t << " [#{issue_data[:count]}]" end end From 44ef583a23dcc2ac29b728ef7990c605bf1c1355 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 14:12:04 -0300 Subject: [PATCH 597/814] fix: send es un nombre reservado --- app/jobs/activity_pub/remote_flag_job.rb | 2 +- app/models/activity_pub/remote_flag.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 7d8131db..26db937a 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -22,7 +22,7 @@ class ActivityPub raise 'No se pudo enviar el reporte' unless response.ok? - remote_flag.send! + remote_flag.report! rescue Exception => e ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response }) raise diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index 25f1b743..76143414 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -14,7 +14,7 @@ class ActivityPub transitions from: :waiting, to: :queued end - event :send do + event :report do transitions from: :queued, to: :sent end From 19d998086c0f7e1d2813b68f3f8d4c31c16d75d3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 14:31:32 -0300 Subject: [PATCH 598/814] fix: raise --- app/models/activity_pub.rb | 6 ++---- app/models/actor_moderation.rb | 6 +++--- app/models/fediblock_state.rb | 4 ++-- app/models/instance_moderation.rb | 6 +++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index b07fe790..3887d512 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -68,8 +68,7 @@ class ActivityPub < ApplicationRecord transitions from: %i[paused], to: :approved before do - raise AASM::InvalidTransition unless - site.social_inbox.inbox.accept(id: object.uri).ok? + raise unless site.social_inbox.inbox.accept(id: object.uri).ok? end end @@ -78,8 +77,7 @@ class ActivityPub < ApplicationRecord transitions from: %i[paused approved], to: :rejected before do - raise AASM::InvalidTransition unless - site.social_inbox.inbox.reject(id: object.uri).ok? + raise unless site.social_inbox.inbox.reject(id: object.uri).ok? end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index d7eea709..5d44a021 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -65,21 +65,21 @@ class ActorModeration < ApplicationRecord end def pause_remotely! - raise AASM::InvalidTransition unless + raise unless actor.mention && site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && site.social_inbox.blocklist.delete(list: [actor.mention]).ok? end def allow_remotely! - raise AASM::InvalidTransition unless + raise unless actor.mention && site.social_inbox.allowlist.post(list: [actor.mention]).ok? && site.social_inbox.blocklist.delete(list: [actor.mention]).ok? end def block_remotely! - raise AASM::InvalidTransition unless + raise unless actor.mention && site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && site.social_inbox.blocklist.post(list: [actor.mention]).ok? diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 180a45b5..214e2f5e 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -89,14 +89,14 @@ class FediblockState < ApplicationRecord # Al deshabilitar, las instancias pasan a ser analizadas caso por caso def disable_remotely! - raise AASM::InvalidTransition unless + raise unless site.social_inbox.blocklist.delete(list: list_names).ok? && site.social_inbox.allowlist.delete(list: list_names).ok? end # Al habilitar, se bloquean todas las instancias de la lista def enable_remotely! - raise AASM::InvalidTransition unless + raise unless site.social_inbox.blocklist.post(list: list_names).ok? && site.social_inbox.allowlist.delete(list: list_names).ok? end diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 7447cc89..ef04b7ff 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -60,7 +60,7 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def pause_remotely! - raise AASM::InvalidTransition unless + raise unless site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? end @@ -69,7 +69,7 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def block_remotely! - raise AASM::InvalidTransition unless + raise unless site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && site.social_inbox.blocklist.post(list: [instance.list_name]).ok? end @@ -78,7 +78,7 @@ class InstanceModeration < ApplicationRecord # # @return [Boolean] def allow_remotely! - raise AASM::InvalidTransition unless + raise unless site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && site.social_inbox.allowlist.post(list: [instance.list_name]).ok? end From fbd741960bd178b473d194980f16e63f1e190e8f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 14:42:08 -0300 Subject: [PATCH 599/814] =?UTF-8?q?fix:=20crear=20hooks=20y=20blocklists?= =?UTF-8?q?=20despu=C3=A9s=20de=20publicar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_social_distributed_press.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index eec8189b..b7525dca 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -7,9 +7,6 @@ class DeploySocialDistributedPress < Deploy # Solo luego de publicar remotamente DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync].freeze - after_save :create_hooks! - after_create :enable_fediblocks! - # Envía las notificaciones def deploy(output: false) with_tempfile(site.private_key_pem) do |file| @@ -18,6 +15,10 @@ class DeploySocialDistributedPress < Deploy run %(bundle exec jekyll notify --trace --key #{key} --destination "#{dest}"), output: output end + + + create_hooks! + enable_fediblocks! end # Igual que DeployLocal From ea34b2c676e079948cbf51a05a039d9383f2f828 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 15:03:17 -0300 Subject: [PATCH 600/814] fix: hostnames --- app/models/fediblock_state.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 214e2f5e..b5258fb6 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -82,8 +82,8 @@ class FediblockState < ApplicationRecord # @return [Array] def list_names - @list_names ||= fediblock.instances.map do |instance| - "@*@#{instance}" + @list_names ||= fediblock.hostnames.map do |hostname| + "@*@#{hostname}" end end From 38ba8795debf571c1e6173116f56d4c594f2ba7d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 15:36:00 -0300 Subject: [PATCH 601/814] fix: el reporte remoto es opcional --- app/models/activity_pub.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 3887d512..33cd4d45 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -18,7 +18,7 @@ class ActivityPub < ApplicationRecord belongs_to :site belongs_to :object, polymorphic: true belongs_to :actor - belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' + belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag' has_many :activities validates :site_id, presence: true From b334d49654a295b439de085ef0cd0352c7f47645 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 15:41:46 -0300 Subject: [PATCH 602/814] fix: actualizar al estado remoto --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 548781fa..c40857e0 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -53,7 +53,8 @@ module Api instance.present? object.present? activity.present? - activity_pub.approve! if activity_pub.may_approve? + activity_pub.update(aasm_state: 'approved') + activity.update_activity_pub_state! end head :accepted @@ -69,7 +70,7 @@ module Api instance.present? object.present? activity.present? - activity_pub.reject! if activity_pub.may_reject? + activity_pub.update(aasm_state: 'rejected') end head :accepted From 5c22015fe2d7ca3c418005ba4e8a989560270640 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 15:47:27 -0300 Subject: [PATCH 603/814] fix: el reporte remoto es opcional --- app/models/actor_moderation.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 5d44a021..e06ffbb1 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -9,7 +9,7 @@ class ActorModeration < ApplicationRecord IGNORED_STATES = [] belongs_to :site - belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' + belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag' belongs_to :actor, class_name: 'ActivityPub::Actor' accepts_nested_attributes_for :remote_flag From 019101ba1e07448eceec8e390070f632420d72bc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 15:54:47 -0300 Subject: [PATCH 604/814] feat: almacenar el perfil de le actore en la base de datos --- app/jobs/activity_pub/actor_fetch_job.rb | 2 +- app/models/activity_pub/actor.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb index 71107151..1190e936 100644 --- a/app/jobs/activity_pub/actor_fetch_job.rb +++ b/app/jobs/activity_pub/actor_fetch_job.rb @@ -19,7 +19,7 @@ class ActivityPub return unless response.ok? return if response.miss? && actor.content.present? - actor.update(content: FastJsonparser.parse(response.body)) + actor.object.update(content: FastJsonparser.parse(response.body)) end end end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index fe6052bf..0a39dcde 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -25,5 +25,13 @@ class ActivityPub @mention ||= "@#{content['preferredUsername']}@#{instance.hostname}" end + + def object + @object ||= ActivityPub::Object::Person.find_or_initialize_by(uri: uri) + end + + def content + object.content + end end end From 5f5b929aa89098726ddb55098756d01e060fd9dc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 15:59:48 -0300 Subject: [PATCH 605/814] fix: traducciones --- config/locales/en.yml | 17 ++++++++--------- config/locales/es.yml | 17 ++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 0ca90aa7..0f010c89 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -50,6 +50,14 @@ en: pm: pm format: '%-I:%M %p' components: + actor: + user: Username + profile: Profile + profile_name: Profile name + preferred_name: Name in Fediverse + profile_id: ID + profile_published: Published + profile_summary: Summary block_list: know_more: Know more instances_blocked: Instances blocked @@ -107,15 +115,6 @@ en: text_allow: Always approve text_block: Block text_report: Report - actor_moderations: - show: - user: Username - profile: Profile - profile_name: Profile name - preferred_name: Name in Fediverse - profile_id: ID - profile_published: Published - profile_summary: Summary remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." moderation_queue: diff --git a/config/locales/es.yml b/config/locales/es.yml index 40a1a18c..0a2538a7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -50,6 +50,14 @@ es: pm: pm format: '%-H:%M' components: + actor: + user: Nombre de usuarie + profile: Cuenta de Origen + profile_name: Nombre de la cuenta + preferred_name: Nombre en el Fediverso + profile_id: ID + profile_published: Publicada + profile_summary: Presentación block_list: know_more: Saber más (en inglés) instances_blocked: Instancias bloqueadas @@ -106,15 +114,6 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar - actor_moderations: - show: - user: Nombre de usuarie - profile: Cuenta de Origen - profile_name: Nombre de la cuenta - preferred_name: Nombre en el Fediverso - profile_id: ID - profile_published: Publicada - profile_summary: Presentación remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." moderation_queue: From 2e04bc8eac09bcfc4929ca9670971fcf5da35056 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 17:15:21 -0300 Subject: [PATCH 606/814] =?UTF-8?q?fix:=20las=20actividades=20est=C3=A1n?= =?UTF-8?q?=20duplicadas=20con=20respecto=20a=20su=20estado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit por ejemplo, el borrado de une actore puede estar dirigido a todos los sitios, con lo que se crea varias veces (aunque se ejecuta solo una) --- app/models/activity_pub/activity.rb | 2 ++ app/models/activity_pub/actor.rb | 3 +++ app/models/activity_pub/concerns/json_ld_concern.rb | 2 -- app/models/activity_pub/object.rb | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index 1147c5b8..ee555474 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -20,6 +20,8 @@ class ActivityPub has_one :object, through: :activity_pub validates :activity_pub_id, presence: true + # Las actividades son únicas con respecto a su estado + validates :uri, presence: true, uniqueness: { scope: :activity_pub_id, message: 'estado duplicado' } # Siempre en orden descendiente para saber el último estado default_scope -> { order(created_at: :desc) } diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 0a39dcde..919bc5e0 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -15,6 +15,9 @@ class ActivityPub has_many :activities has_many :remote_flags + # Les actores son únicxs a toda la base de datos + validates :uri, presence: true, uniqueness: true + # Obtiene el nombre de la Actor como mención, solo si obtuvimos el # contenido de antemano. # diff --git a/app/models/activity_pub/concerns/json_ld_concern.rb b/app/models/activity_pub/concerns/json_ld_concern.rb index bc30330c..282027df 100644 --- a/app/models/activity_pub/concerns/json_ld_concern.rb +++ b/app/models/activity_pub/concerns/json_ld_concern.rb @@ -6,8 +6,6 @@ class ActivityPub extend ActiveSupport::Concern included do - validates :uri, presence: true, uniqueness: true - # Cuando asignamos contenido, obtener la URI si no lo hicimos ya before_save :uri_from_content!, unless: :uri? diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index c196160f..15b07bee 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -5,6 +5,9 @@ class ActivityPub class Object < ApplicationRecord include ActivityPub::Concerns::JsonLdConcern + # Los objetos son únicos a toda la base de datos + validates :uri, presence: true, uniqueness: true + has_many :activity_pubs, as: :object # Encontrar le Actor por su relación con el objeto From 00f865f31542a15496355ea878954656323941f4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 17:22:01 -0300 Subject: [PATCH 607/814] fix: comentario en perfil de actore --- app/models/activity_pub/activity/delete.rb | 10 ++++++++-- app/views/moderation_queue/_comments.haml | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index f6ff6536..5de20478 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -14,9 +14,15 @@ class ActivityPub # @see {https://docs.joinmastodon.org/spec/security/#ld} def update_activity_pub_state! ActivityPub.transaction do - ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object']))&.activity_pubs&.find_each(&:remove!) + object = ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object'])) - activity_pub.remove! + if object + object.activity_pubs.find_each do |activity_pub| + activity_pub.remove! if activity_pub.may_remove? + end + end + + activity_pub.remove! if activity_pub.may_remove? end end end diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 436777db..316b097f 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -14,4 +14,4 @@ - moderation_queue.each do |activity_pub| -# cache [activity_pub, activity_pub.object, activity_pub.actor] do %hr - = render 'comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form_id: form_id + = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form_id: form_id From 7aa14bd292bafbee9fd0a4dea874ae639e0a9737 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 17:36:13 -0300 Subject: [PATCH 608/814] fix: poder ir al perfil --- app/views/components/_actor.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/components/_actor.haml b/app/views/components/_actor.haml index 3983d617..c58beae0 100644 --- a/app/views/components/_actor.haml +++ b/app/views/components/_actor.haml @@ -1,5 +1,7 @@ -# Componente Remote_Profile +- uri = text_plain(remote_profile['id']) + .py-2 %dl %dt= t('.profile_name') @@ -10,7 +12,7 @@ %dt= t('.profile_id') %dd - = link_to text_plain(remote_profile['id']) + = link_to uri, uri - if remote_profile['published'].present? %dt= t('.profile_published') From a8f184ecbf80b91336a7ee6a2ce5d4177f4e044e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Mar 2024 17:45:21 -0300 Subject: [PATCH 609/814] feat: validar que las uris sean uris --- app/models/activity_pub/activity.rb | 2 +- app/models/activity_pub/actor.rb | 2 +- app/models/activity_pub/object.rb | 2 +- app/validators/url_validator.rb | 21 +++++++++++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 app/validators/url_validator.rb diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index ee555474..af005ff3 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -21,7 +21,7 @@ class ActivityPub validates :activity_pub_id, presence: true # Las actividades son únicas con respecto a su estado - validates :uri, presence: true, uniqueness: { scope: :activity_pub_id, message: 'estado duplicado' } + validates :uri, presence: true, url: true, uniqueness: { scope: :activity_pub_id, message: 'estado duplicado' } # Siempre en orden descendiente para saber el último estado default_scope -> { order(created_at: :desc) } diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 919bc5e0..b03145e7 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -16,7 +16,7 @@ class ActivityPub has_many :remote_flags # Les actores son únicxs a toda la base de datos - validates :uri, presence: true, uniqueness: true + validates :uri, presence: true, url: true, uniqueness: true # Obtiene el nombre de la Actor como mención, solo si obtuvimos el # contenido de antemano. diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 15b07bee..3fde326b 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -6,7 +6,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern # Los objetos son únicos a toda la base de datos - validates :uri, presence: true, uniqueness: true + validates :uri, presence: true, url: true, uniqueness: true has_many :activity_pubs, as: :object diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb new file mode 100644 index 00000000..291f9288 --- /dev/null +++ b/app/validators/url_validator.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Valida URLs +# +# @see {https://storck.io/posts/better-http-url-validation-in-ruby-on-rails/} +class UrlValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + if value.blank? + record.errors.add(attribute, :url_missing) + return + end + + uri = URI.parse(value) + + record.errors.add(attribute, :scheme_missing) if uri.scheme.blank? + record.errors.add(attribute, :host_missing) if uri.host.blank? + record.errors.add(attribute, :path_missing) if uri.path.blank? + rescue URI::Error + record.errors.add(attribute, :invalid) + end +end From 453798dcc7b33cd32a27e358eef5b9cf0acf2434 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Mar 2024 16:38:26 -0300 Subject: [PATCH 610/814] =?UTF-8?q?fix:=20el=20m=C3=A9todo=20es=20p=C3=BAb?= =?UTF-8?q?lico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site/repository.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 687ced12..c7056eaa 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -169,6 +169,12 @@ class Site git_sh('git', 'lfs', 'push', remote.name, default_branch) end + # Hace limpieza de LFS + def lfs_cleanup + git_sh("git", "lfs", "prune") + git_sh("git", "lfs", "dedup") + end + private # @deprecated @@ -235,10 +241,5 @@ class Site r&.success? end - - def lfs_cleanup - git_sh("git", "lfs", "prune") - git_sh("git", "lfs", "dedup") - end end end From 66e59ee5ad8143630b07965560c3951d5cb2cac2 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Mar 2024 16:54:09 -0300 Subject: [PATCH 611/814] feat: algunos tipos son actores --- app/models/activity_pub/object.rb | 8 ++++++ app/models/activity_pub/object/application.rb | 4 ++- app/models/activity_pub/object/audio.rb | 10 +++++++ .../object/concerns/actor_type_concern.rb | 27 +++++++++++++++++++ app/models/activity_pub/object/document.rb | 10 +++++++ app/models/activity_pub/object/event.rb | 10 +++++++ app/models/activity_pub/object/group.rb | 10 +++++++ app/models/activity_pub/object/image.rb | 10 +++++++ .../activity_pub/object/organization.rb | 4 ++- app/models/activity_pub/object/page.rb | 10 +++++++ app/models/activity_pub/object/person.rb | 4 ++- app/models/activity_pub/object/place.rb | 10 +++++++ app/models/activity_pub/object/profile.rb | 10 +++++++ .../activity_pub/object/relationship.rb | 10 +++++++ app/models/activity_pub/object/service.rb | 10 +++++++ app/models/activity_pub/object/tombstone.rb | 10 +++++++ app/models/activity_pub/object/video.rb | 10 +++++++ 17 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 app/models/activity_pub/object/audio.rb create mode 100644 app/models/activity_pub/object/concerns/actor_type_concern.rb create mode 100644 app/models/activity_pub/object/document.rb create mode 100644 app/models/activity_pub/object/event.rb create mode 100644 app/models/activity_pub/object/group.rb create mode 100644 app/models/activity_pub/object/image.rb create mode 100644 app/models/activity_pub/object/page.rb create mode 100644 app/models/activity_pub/object/place.rb create mode 100644 app/models/activity_pub/object/profile.rb create mode 100644 app/models/activity_pub/object/relationship.rb create mode 100644 app/models/activity_pub/object/service.rb create mode 100644 app/models/activity_pub/object/tombstone.rb create mode 100644 app/models/activity_pub/object/video.rb diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 3fde326b..b33c1957 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -16,5 +16,13 @@ class ActivityPub def actor ActivityPub::Actor.find_by(uri: content['actor']) end + + def actor_type? + false + end + + def object_type? + true + end end end diff --git a/app/models/activity_pub/object/application.rb b/app/models/activity_pub/object/application.rb index 99ac935c..d26a7757 100644 --- a/app/models/activity_pub/object/application.rb +++ b/app/models/activity_pub/object/application.rb @@ -5,6 +5,8 @@ # Una aplicación o instancia class ActivityPub class Object - class Application < ActivityPub::Object; end + class Application < ActivityPub::Object + include Concerns::ActorTypeConcern + end end end diff --git a/app/models/activity_pub/object/audio.rb b/app/models/activity_pub/object/audio.rb new file mode 100644 index 00000000..48caea44 --- /dev/null +++ b/app/models/activity_pub/object/audio.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Audio = +# +# Representa artículos +class ActivityPub + class Object + class Audio < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/concerns/actor_type_concern.rb b/app/models/activity_pub/object/concerns/actor_type_concern.rb new file mode 100644 index 00000000..bb840601 --- /dev/null +++ b/app/models/activity_pub/object/concerns/actor_type_concern.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class ActivityPub + class Object + module Concerns + module ActorTypeConcern + extend ActiveSupport::Concern + + included do + # El objeto referencia a une Actor + # + # @see {https://www.w3.org/TR/activitystreams-vocabulary/#actor-types} + def actor_type? + true + end + + # El objeto es un objeto + # + # @see {https://www.w3.org/TR/activitystreams-vocabulary/#object-types} + def object_type? + false + end + end + end + end + end +end diff --git a/app/models/activity_pub/object/document.rb b/app/models/activity_pub/object/document.rb new file mode 100644 index 00000000..d7444514 --- /dev/null +++ b/app/models/activity_pub/object/document.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Document = +# +# Representa artículos +class ActivityPub + class Object + class Document < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/event.rb b/app/models/activity_pub/object/event.rb new file mode 100644 index 00000000..9fa1f6fc --- /dev/null +++ b/app/models/activity_pub/object/event.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Event = +# +# Representa artículos +class ActivityPub + class Object + class Event < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/group.rb b/app/models/activity_pub/object/group.rb new file mode 100644 index 00000000..08d11d0d --- /dev/null +++ b/app/models/activity_pub/object/group.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Group = +class ActivityPub + class Object + class Group < ActivityPub::Object + include Concerns::ActorTypeConcern + end + end +end diff --git a/app/models/activity_pub/object/image.rb b/app/models/activity_pub/object/image.rb new file mode 100644 index 00000000..9939a14b --- /dev/null +++ b/app/models/activity_pub/object/image.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Image = +# +# Representa artículos +class ActivityPub + class Object + class Image < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/organization.rb b/app/models/activity_pub/object/organization.rb index e3385232..e820c305 100644 --- a/app/models/activity_pub/object/organization.rb +++ b/app/models/activity_pub/object/organization.rb @@ -5,6 +5,8 @@ # Una organización class ActivityPub class Object - class Organization < ActivityPub::Object; end + class Organization < ActivityPub::Object + include Concerns::ActorTypeConcern + end end end diff --git a/app/models/activity_pub/object/page.rb b/app/models/activity_pub/object/page.rb new file mode 100644 index 00000000..f05503e2 --- /dev/null +++ b/app/models/activity_pub/object/page.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Page = +# +# Representa artículos +class ActivityPub + class Object + class Page < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/person.rb b/app/models/activity_pub/object/person.rb index a6a85d43..5bcab596 100644 --- a/app/models/activity_pub/object/person.rb +++ b/app/models/activity_pub/object/person.rb @@ -5,6 +5,8 @@ # Una persona, el perfil de une actore class ActivityPub class Object - class Person < ActivityPub::Object; end + class Person < ActivityPub::Object + include Concerns::ActorTypeConcern + end end end diff --git a/app/models/activity_pub/object/place.rb b/app/models/activity_pub/object/place.rb new file mode 100644 index 00000000..f04032ed --- /dev/null +++ b/app/models/activity_pub/object/place.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Place = +# +# Representa artículos +class ActivityPub + class Object + class Place < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/profile.rb b/app/models/activity_pub/object/profile.rb new file mode 100644 index 00000000..8f7183a2 --- /dev/null +++ b/app/models/activity_pub/object/profile.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Profile = +# +# Representa artículos +class ActivityPub + class Object + class Profile < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/relationship.rb b/app/models/activity_pub/object/relationship.rb new file mode 100644 index 00000000..ece995b4 --- /dev/null +++ b/app/models/activity_pub/object/relationship.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Relationship = +# +# Representa artículos +class ActivityPub + class Object + class Relationship < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/service.rb b/app/models/activity_pub/object/service.rb new file mode 100644 index 00000000..a276ea5b --- /dev/null +++ b/app/models/activity_pub/object/service.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Service = +class ActivityPub + class Object + class Service < ActivityPub::Object + include Concerns::ActorTypeConcern + end + end +end diff --git a/app/models/activity_pub/object/tombstone.rb b/app/models/activity_pub/object/tombstone.rb new file mode 100644 index 00000000..88f136b9 --- /dev/null +++ b/app/models/activity_pub/object/tombstone.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Tombstone = +# +# Representa artículos +class ActivityPub + class Object + class Tombstone < ActivityPub::Object; end + end +end diff --git a/app/models/activity_pub/object/video.rb b/app/models/activity_pub/object/video.rb new file mode 100644 index 00000000..fa4bbffb --- /dev/null +++ b/app/models/activity_pub/object/video.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# = Video = +# +# Representa artículos +class ActivityPub + class Object + class Video < ActivityPub::Object; end + end +end From 5a7331e00e44074bd9639d9023f707721665655b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Mar 2024 17:17:58 -0300 Subject: [PATCH 612/814] =?UTF-8?q?feat:=20cuando=20une=20actore=20es=20el?= =?UTF-8?q?iminade,=20hay=20que=20eliminar=20sus=20estados=20de=20moderaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/activity/delete.rb | 8 +++++++- app/models/activity_pub/object.rb | 7 ++++++- .../object/concerns/actor_type_concern.rb | 7 +++++++ app/models/actor_moderation.rb | 15 +++++++++++++-- .../20240307201510_remove_actor_moderations.rb | 13 +++++++++++++ 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20240307201510_remove_actor_moderations.rb diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 5de20478..6a23a8b5 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -16,10 +16,16 @@ class ActivityPub ActivityPub.transaction do object = ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object'])) - if object + if object.present? object.activity_pubs.find_each do |activity_pub| activity_pub.remove! if activity_pub.may_remove? end + + # Encontrar todas las acciones de moderación de le actore + # eliminade y moverlas a eliminar. + if object.actor_type? && object.actor.present? + ActorModeration.where(actor_id: object.actor.id).remove_all! + end end activity_pub.remove! if activity_pub.may_remove? diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index b33c1957..9061c4c5 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -14,7 +14,12 @@ class ActivityPub # # @return [ActivityPub::Actor,nil] def actor - ActivityPub::Actor.find_by(uri: content['actor']) + ActivityPub::Actor.find_by(uri: actor_uri) + end + + # @return [String] + def actor_uri + content['attributedTo'] end def actor_type? diff --git a/app/models/activity_pub/object/concerns/actor_type_concern.rb b/app/models/activity_pub/object/concerns/actor_type_concern.rb index bb840601..b2a643c7 100644 --- a/app/models/activity_pub/object/concerns/actor_type_concern.rb +++ b/app/models/activity_pub/object/concerns/actor_type_concern.rb @@ -7,6 +7,13 @@ class ActivityPub extend ActiveSupport::Concern included do + # La URI de le Actor en este caso es la misma id + # + # @return [String] + def actor_uri + uri + end + # El objeto referencia a une Actor # # @see {https://www.w3.org/TR/activitystreams-vocabulary/#actor-types} diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index e06ffbb1..01613f72 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -5,8 +5,8 @@ class ActorModeration < ApplicationRecord include AASM include AasmEventsConcern - IGNORED_EVENTS = [] - IGNORED_STATES = [] + IGNORED_EVENTS = %i[remove] + IGNORED_STATES = %i[removed] belongs_to :site belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag' @@ -23,11 +23,16 @@ class ActorModeration < ApplicationRecord self.update_all(aasm_state: 'paused', updated_at: Time.now) end + def self.remove_all! + self.update_all(aasm_state: 'removed', updated_at: Time.now) + end + aasm do state :paused, initial: true state :allowed state :blocked state :reported + state :removed event :pause do transitions from: %i[allowed blocked reported], to: :paused @@ -62,6 +67,12 @@ class ActorModeration < ApplicationRecord ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end + + # Si un perfil es eliminado remotamente, tenemos que dejar de + # mostrarlo y todas sus actividades. + event :remove do + transitions to: :removed + end end def pause_remotely! diff --git a/db/migrate/20240307201510_remove_actor_moderations.rb b/db/migrate/20240307201510_remove_actor_moderations.rb new file mode 100644 index 00000000..92c6d23a --- /dev/null +++ b/db/migrate/20240307201510_remove_actor_moderations.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Mover todes les actores eliminades +class RemoveActorModerations < ActiveRecord::Migration[6.1] + def up + actor_ids = + ActivityPub.where(aasm_state: 'removed', object_type: 'ActivityPub::Object::Person').distinct.pluck(:actor_id) + + ActorModeration.where(id: actor_ids).remove_all! + end + + def down; end +end From b0b8e6877efee116e707efea7ea05145387a7c00 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Mar 2024 17:21:03 -0300 Subject: [PATCH 613/814] =?UTF-8?q?fixup!=20feat:=20cuando=20une=20actore?= =?UTF-8?q?=20es=20eliminade,=20hay=20que=20eliminar=20sus=20estados=20de?= =?UTF-8?q?=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20240307201510_remove_actor_moderations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240307201510_remove_actor_moderations.rb b/db/migrate/20240307201510_remove_actor_moderations.rb index 92c6d23a..b451c589 100644 --- a/db/migrate/20240307201510_remove_actor_moderations.rb +++ b/db/migrate/20240307201510_remove_actor_moderations.rb @@ -6,7 +6,7 @@ class RemoveActorModerations < ActiveRecord::Migration[6.1] actor_ids = ActivityPub.where(aasm_state: 'removed', object_type: 'ActivityPub::Object::Person').distinct.pluck(:actor_id) - ActorModeration.where(id: actor_ids).remove_all! + ActorModeration.where(actor_id: actor_ids).remove_all! end def down; end From 2370cf73108b315c833f370f876209896efe7067 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Mar 2024 17:44:40 -0300 Subject: [PATCH 614/814] =?UTF-8?q?feat:=20eliminar=20m=C3=A1s=20actores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20240307203039_remove_actor_moderations2.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 db/migrate/20240307203039_remove_actor_moderations2.rb diff --git a/db/migrate/20240307203039_remove_actor_moderations2.rb b/db/migrate/20240307203039_remove_actor_moderations2.rb new file mode 100644 index 00000000..dabc7ed7 --- /dev/null +++ b/db/migrate/20240307203039_remove_actor_moderations2.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Algunes quedaron como genéricxs +class RemoveActorModerations2 < ActiveRecord::Migration[6.1] + def up + actor_uris = ActivityPub::Activity.where(type: 'ActivityPub::Activity::Delete').distinct.pluck(Arel.sql("content->>'object'")) + actor_ids = ActivityPub::Actor.where(uri: actor_uris).ids + + ActorModeration.where(actor_id: actor_ids).remove_all! + end + + def down; end +end From 21401d93b6c79a34a55e8d3d8c97cd029c96428a Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Mar 2024 17:46:32 -0300 Subject: [PATCH 615/814] =?UTF-8?q?fixup!=20feat:=20eliminar=20m=C3=A1s=20?= =?UTF-8?q?actores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20240307203039_remove_actor_moderations2.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240307203039_remove_actor_moderations2.rb b/db/migrate/20240307203039_remove_actor_moderations2.rb index dabc7ed7..555a4ffe 100644 --- a/db/migrate/20240307203039_remove_actor_moderations2.rb +++ b/db/migrate/20240307203039_remove_actor_moderations2.rb @@ -3,7 +3,7 @@ # Algunes quedaron como genéricxs class RemoveActorModerations2 < ActiveRecord::Migration[6.1] def up - actor_uris = ActivityPub::Activity.where(type: 'ActivityPub::Activity::Delete').distinct.pluck(Arel.sql("content->>'object'")) + actor_uris = ActivityPub::Activity.unscope(:order).where(type: 'ActivityPub::Activity::Delete').distinct.pluck(Arel.sql("content->>'object'")) actor_ids = ActivityPub::Actor.where(uri: actor_uris).ids ActorModeration.where(actor_id: actor_ids).remove_all! From 550dba08c5cafc9ce9aeee120177fdb0b904be62 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 11:24:57 -0300 Subject: [PATCH 616/814] fix: migraciones --- db/structure.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db/structure.sql b/db/structure.sql index 97bd372e..ed58ebec 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2699,6 +2699,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240301194154'), ('20240301202955'), ('20240305164653'), -('20240305184854'); +('20240305184854'), +('20240307201510'), +('20240307203039'); From fc77f8e9f406c854155f966e2f7b8fc869e6218c Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 13:08:24 -0300 Subject: [PATCH 617/814] fix: form es opcional #15329 --- app/views/components/_checkbox.haml | 3 ++- app/views/components/_comments_checked_submenu.haml | 5 ++++- app/views/components/_comments_filters.haml | 5 ++++- app/views/components/_dropdown_button.haml | 2 +- app/views/components/_instances_checked_submenu.haml | 5 ++++- app/views/components/_instances_filters.haml | 5 ++++- app/views/components/_profiles_checked_submenu.haml | 5 ++++- app/views/components/_profiles_filters.haml | 5 ++++- app/views/components/_select_all.haml | 2 +- app/views/components/_select_all_container.haml | 4 ++-- app/views/moderation_queue/_account.haml | 5 ++++- app/views/moderation_queue/_accounts.haml | 8 ++++---- app/views/moderation_queue/_comment.haml | 3 ++- app/views/moderation_queue/_comments.haml | 8 ++++---- app/views/moderation_queue/_instance.haml | 2 +- app/views/moderation_queue/_instances.haml | 8 ++++---- 16 files changed, 49 insertions(+), 26 deletions(-) diff --git a/app/views/components/_checkbox.haml b/app/views/components/_checkbox.haml index 68f1a663..a58c85b7 100644 --- a/app/views/components/_checkbox.haml +++ b/app/views/components/_checkbox.haml @@ -1,5 +1,6 @@ -# Componente Checkbox - local_assigns[:name] ||= id + .custom-control.custom-checkbox - %input.custom-control-input{ form: local_assigns[:form_id], type: 'checkbox', id: id, **local_assigns } + %input.custom-control-input{ type: 'checkbox', id: id, **local_assigns.compact } %label.custom-control-label{ for: id }= yield diff --git a/app/views/components/_comments_checked_submenu.haml b/app/views/components/_comments_checked_submenu.haml index a09da426..d94e12a9 100644 --- a/app/views/components/_comments_checked_submenu.haml +++ b/app/views/components/_comments_checked_submenu.haml @@ -1,6 +1,9 @@ +-# + @param form [String] + - current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first - ActivityPub.aasm.events.each do |event| - next if ActivityPub::IGNORED_EVENTS.include? event.name - next unless event.transitions_from_state?(current_state) - = render 'components/dropdown_button', form_id: form_id, text: t(".submenu_#{event.name}"), name: 'activity_pub_action', value: event.name + = render 'components/dropdown_button', form: form, text: t(".submenu_#{event.name}"), name: 'activity_pub_action', value: event.name diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index 35cd5dda..cf8c1aa2 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -1,9 +1,12 @@ +-# + @params form [String] + - current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first .d-flex.py-2 - if ActivityPub.transitionable_events(current_state).present? = render 'components/dropdown', text: t('.text_checked') do - = render 'components/comments_checked_submenu', form_id: form_id + = render 'components/comments_checked_submenu', form: form = render 'components/dropdown', text: t('.text_show') do = render 'components/comments_show_submenu', activity_pubs: activity_pubs diff --git a/app/views/components/_dropdown_button.haml b/app/views/components/_dropdown_button.haml index c8c98209..c0f12754 100644 --- a/app/views/components/_dropdown_button.haml +++ b/app/views/components/_dropdown_button.haml @@ -1,4 +1,4 @@ -# @param name [String] @param value [String] -%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value, form: local_assigns[:form_id] }= text +%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value, **local_assigns.compact } diff --git a/app/views/components/_instances_checked_submenu.haml b/app/views/components/_instances_checked_submenu.haml index 4c45b7ab..7c9dbd87 100644 --- a/app/views/components/_instances_checked_submenu.haml +++ b/app/views/components/_instances_checked_submenu.haml @@ -1,2 +1,5 @@ +-# + @params form [String] + - InstanceModeration.transitionable_events(current_state).each do |event| - = render 'components/dropdown_button', text: t(".submenu_#{event}"), name: 'instance_moderation_action', value: event, form_id: form_id + = render 'components/dropdown_button', text: t(".submenu_#{event}"), name: 'instance_moderation_action', value: event, form: form diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 2c23fd72..730184bd 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -1,9 +1,12 @@ +-# + @params form [String] + - current_state = params[:state]&.to_sym || InstanceModeration.states.first .d-flex.py-2 - if InstanceModeration.transitionable_events(current_state).present? = render 'components/dropdown', text: t('.text_checked') do - = render 'components/instances_checked_submenu', form_id: form_id, current_state: current_state + = render 'components/instances_checked_submenu', form: form, current_state: current_state = render 'components/dropdown', text: t('.text_show') do = render 'components/instances_show_submenu', instance_moderations: instance_moderations diff --git a/app/views/components/_profiles_checked_submenu.haml b/app/views/components/_profiles_checked_submenu.haml index 66a0fa78..04c86fd4 100644 --- a/app/views/components/_profiles_checked_submenu.haml +++ b/app/views/components/_profiles_checked_submenu.haml @@ -1,2 +1,5 @@ +-# + @params form [String] + - ActorModeration.transitionable_events(current_state).each do |actor_event| - = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event, form_id: form_id + = render 'components/dropdown_button', text: t(".submenu_#{actor_event}"), name: 'actor_moderation_action', value: actor_event, form: form diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index bf7fb48a..3f830ec8 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -1,9 +1,12 @@ +-# + @params form [String] + - current_state = params[:actor_state]&.to_sym || ActorModeration.states.first .d-flex.py-2 - if ActorModeration.transitionable_events(current_state).present? = render 'components/dropdown', text: t('.text_checked') do - = render 'components/profiles_checked_submenu', form_id: form_id, current_state: current_state + = render 'components/profiles_checked_submenu', form: form, current_state: current_state = render 'components/dropdown', text: t('.text_show') do = render 'components/profiles_show_submenu', actor_moderations: actor_moderations diff --git a/app/views/components/_select_all.haml b/app/views/components/_select_all.haml index 68711c4a..9778cd13 100644 --- a/app/views/components/_select_all.haml +++ b/app/views/components/_select_all.haml @@ -1,4 +1,4 @@ -# @param id [String] -= render 'components/checkbox', id: id, form: local_assigns[:form_id], data: { action: 'select-all#toggle', target: 'select-all.toggle' } do += render 'components/checkbox', id: id, data: { action: 'select-all#toggle', target: 'select-all.toggle', **local_assigns.compact } do %span.sr-only= t('.label') diff --git a/app/views/components/_select_all_container.haml b/app/views/components/_select_all_container.haml index 5fa91e2d..8c8d9426 100644 --- a/app/views/components/_select_all_container.haml +++ b/app/views/components/_select_all_container.haml @@ -7,7 +7,7 @@ navegador los va a asignar a este formulario. @param path [String] - @param form_id [String] + @param form [String] -= form_tag path, id: form_id, method: :patch do += form_tag path, id: form, method: :patch do -# nada diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index f63b6f6f..6b4c67fc 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -1,6 +1,9 @@ +-# + @params form [String] + .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: actor_moderation.id, form_id: form_id, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: actor_moderation.id, form: form, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index 65ff953f..abc02b31 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -1,17 +1,17 @@ - form_id = 'actor_moderations_action_on_several' -= render 'components/select_all_container', path: site_actor_moderations_action_on_several_path, form_id: form_id += render 'components/select_all_container', path: site_actor_moderations_action_on_several_path, form: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'actors', form_id: form_id + = render 'components/select_all', id: 'actors', form: form_id .col-11 -# Filtros - = render 'components/profiles_filters', actor_moderations: actor_moderations, form_id: form_id + = render 'components/profiles_filters', actor_moderations: actor_moderations, form: form_id .col-12 - if actor_moderations.count.zero? %h4= t('moderation_queue.nothing') - actor_moderations.find_each do |actor_moderation| - cache [actor_moderation, actor_moderation.actor] do %hr - = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form_id: form_id + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form: form_id diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 33ebc722..90579a9c 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,6 +1,7 @@ -# Componente Comentario + @param form [String] @param profile [Hash] @param comment [Hash] @param activity_pub [ActivityPub] @@ -10,7 +11,7 @@ .row.no-gutters .col-1 - = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' }, form: form_id + = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' }, form: form .col-11 .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 316b097f..72240287 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -1,17 +1,17 @@ - form_id = 'activity_pub_action_on_several' -= render 'components/select_all_container', path: site_activity_pubs_action_on_several_path, form_id: form_id += render 'components/select_all_container', path: site_activity_pubs_action_on_several_path, form: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'select-all-comments', form_id: form_id + = render 'components/select_all', id: 'select-all-comments', form: form_id .col-11 -# Filtros - = render 'components/comments_filters', activity_pubs: moderation_queue, form_id: form_id + = render 'components/comments_filters', activity_pubs: moderation_queue, form: form_id .col-12 - if moderation_queue.count.zero? %h4= t('moderation_queue.nothing') - moderation_queue.each do |activity_pub| -# cache [activity_pub, activity_pub.object, activity_pub.actor] do %hr - = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form_id: form_id + = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 05510724..7cf3b085 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -3,7 +3,7 @@ .row.no-gutters.pt-2 .col-1 - = render 'components/checkbox', id: instance.hostname, form_id: form_id, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } + = render 'components/checkbox', id: instance.hostname, form: form, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 3954ce65..9a5349ba 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -1,13 +1,13 @@ - form_id = 'instance_moderation_action_on_several' %section - = render 'components/select_all_container', path: site_instance_moderations_action_on_several_path, form_id: form_id + = render 'components/select_all_container', path: site_instance_moderations_action_on_several_path, form: form_id .row.no-gutters.pt-2{ data: { controller: 'select-all' } } .col-1.d-flex.align-items-center - = render 'components/select_all', id: 'instances', form_id: form_id + = render 'components/select_all', id: 'instances', form: form_id .col-11 -# Filtros - = render 'components/instances_filters', instance_moderations: instance_moderations, form_id: form_id + = render 'components/instances_filters', instance_moderations: instance_moderations, form: form_id .col-12 - if instance_moderations.count.zero? @@ -16,7 +16,7 @@ - instance_moderations.each do |instance_moderation| - cache [instance_moderation.aasm_state, instance_moderation.instance] do %hr - = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form_id: form_id + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form: form_id %hr %div From 4dff3180306ee4014e58aee69452b53bb0d9fc47 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 14:10:21 -0300 Subject: [PATCH 618/814] feat: al desactivar un fediblock, ignorar otros fediblocks --- app/models/fediblock_state.rb | 76 ++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index b5258fb6..e50abaef 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -27,12 +27,14 @@ class FediblockState < ApplicationRecord transitions from: :disabled, to: :enabled before do - enable_remotely! + # Bloquear todos las instancias de este Fediblock + enable_remotely! list_names(fediblock.hostnames) # Al actualizar el estado en masa garantizamos que las # instancias que ya existen queden sincronizadas con el bloqueo # en masa que acabamos de hacer. - instance_moderations.block_all! + instance_ids = fediblock.instances.ids + site.instance_moderations.where(instance_id: instance_ids).block_all! # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. @@ -41,11 +43,13 @@ class FediblockState < ApplicationRecord # Bloquear a todes les Actores de las instancias bloqueadas para # indicarle a le usuarie que les tiene que desbloquear # manualmente. + actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids ActorModeration.where(actor_id: actor_ids).paused.block_all! end end - # Al deshabilitar, las listas pasan a modo pausa. + # Al deshabilitar, las listas pasan a modo pausa, a menos que estén + # activas en otros listados. # # @todo No cambiar el estado si se habían habilitado manualmente, # pero esto implica que tenemos que encontrar las que sí y quitarlas @@ -54,12 +58,19 @@ class FediblockState < ApplicationRecord transitions from: :enabled, to: :disabled before do - disable_remotely! + # Deshabilitar todas las instancias que no estén habilitadas por + # otros fediblocks + disable_remotely! list_names(unique_hostnames) - instance_moderations.pause_all! + # Pausar todas las moderaciones de las instancias que no estén + # bloqueadas por otros fediblocks. + instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids + site.instance_moderations.where(instance_id: instance_ids).pause_all! # Volver a pausar todes les actores de esta instancia que fueron - # bloqueades. + # bloqueades, a menos que hayan sido bloqueades por otro + # fediblock. + actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids ActorModeration.where(actor_id: actor_ids).blocked.pause_all! end end @@ -67,37 +78,48 @@ class FediblockState < ApplicationRecord private - def actor_ids - ActivityPub::Actor.where(instance_id: instance_ids).pluck(:id) - end - - def instance_ids - fediblock.instances.pluck(:id) - end - - # Todas las instancias de moderación de este sitio - def instance_moderations - site.instance_moderations.where(instance_id: instance_ids) - end - + # Devuelve los hostnames únicos a esta instancia. + # # @return [Array] - def list_names - @list_names ||= fediblock.hostnames.map do |hostname| + def unique_hostnames + @unique_hostnames ||= + begin + other_enabled_fediblock_ids = + site.fediblock_states.enabled.where.not(id: id).pluck(:fediblock_id) + other_enabled_hostnames = + ActivityPub::Fediblock + .where(id: other_enabled_fediblock_ids) + .pluck(:hostnames) + .flatten + .uniq + + fediblock.hostnames - other_enabled_hostnames + end + end + + # @param hostnames [Array] + # @return [Array] + def list_names(hostnames) + hostnames.map do |hostname| "@*@#{hostname}" end end # Al deshabilitar, las instancias pasan a ser analizadas caso por caso - def disable_remotely! + # + # @param list [Array] + def disable_remotely!(list) raise unless - site.social_inbox.blocklist.delete(list: list_names).ok? && - site.social_inbox.allowlist.delete(list: list_names).ok? + site.social_inbox.blocklist.delete(list: list).ok? && + site.social_inbox.allowlist.delete(list: list).ok? end # Al habilitar, se bloquean todas las instancias de la lista - def enable_remotely! + # + # @param list [Array] + def enable_remotely!(list) raise unless - site.social_inbox.blocklist.post(list: list_names).ok? && - site.social_inbox.allowlist.delete(list: list_names).ok? + site.social_inbox.blocklist.post(list: list).ok? && + site.social_inbox.allowlist.delete(list: list).ok? end end From 995c80fed1d3eb837122e1656a41261c544aaae3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 14:42:27 -0300 Subject: [PATCH 619/814] fix: no colgar toda la cola si algo falla en la api --- app/controllers/fediblock_states_controller.rb | 13 ++++++++++++- app/jobs/activity_pub/instance_moderation_job.rb | 7 +++++++ config/locales/en.yml | 6 ++++++ config/locales/es.yml | 7 +++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/controllers/fediblock_states_controller.rb b/app/controllers/fediblock_states_controller.rb index 6d9737c3..4d9cc968 100644 --- a/app/controllers/fediblock_states_controller.rb +++ b/app/controllers/fediblock_states_controller.rb @@ -11,11 +11,22 @@ class FediblockStatesController < ApplicationController elsif fediblock_state.may_disable? fediblock_state.disable! end + + flash[:success] = I18n.t('fediblock_states.action_on_several.success') + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name }) + + flash.delete(:success) + flash[:error] = I18n.t('fediblock_states.action_on_several.error') end # Bloquear otras instancias if custom_blocklist.present? - ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: custom_blocklist) + if ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: custom_blocklist) + flash[:success] = I18n.t('fediblock_states.action_on_several.custom_blocklist_success') + else + flash[:error] = I18n.t('fediblock_states.action_on_several.custom_blocklist_error') + end end redirect_to site_moderation_queue_path diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index b205e68f..17def46e 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -14,6 +14,7 @@ class ActivityPub end instances = ActivityPub::Instance.where(hostname: hostnames) + success = true Site.transaction do # Crea todas las moderaciones de instancia con un estado por @@ -23,9 +24,15 @@ class ActivityPub # idealmente son pocas instancias las que aparecen. site.instance_moderations.find_or_create_by(instance: instance).tap do |instance_moderation| instance_moderation.block! if instance_moderation.may_block? + # Notificar todos los errores sin detener la ejecución + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, instance_moderation: instance_moderation.id }) + success = false end end end + + success end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 0f010c89..565f0218 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -117,6 +117,12 @@ en: text_report: Report remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." + fediblock_states: + action_on_several: + success: "Blocklists have been enabled, you can find their instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section." + error: "There was an error while enabling or disabling blocklists. We received a report and will be acting on it soon." + custom_blocklist_success: "Custom blocklist has been added, you can find the instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section." + custom_blocklist_error: "There was an error while adding a custom blocklist. We received a report and will be acting on it soon." moderation_queue: everything: 'Select all' nothing: "There's nothing for this filter" diff --git a/config/locales/es.yml b/config/locales/es.yml index 0a2538a7..175ca661 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -116,6 +116,13 @@ es: text_report: Reportar remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." + fediblock_states: + action_on_several: + success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés activarlas individualmente en la sección Cuentas." + error: "Hubo un error al activar o desactivar listas de bloqueo, ya recibimos el reporte y lo estaremos verificando." + custom_blocklist_success: "Se agregaron las instancias personalizadas a la lista de bloqueo, podés encontrarlas filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés aprobarlas individualmente en la sección Cuentas." + custom_blocklist_error: "Hubo un error al agregar instancias personalizadas a la lista de bloqueo, ya recibimos el reporte y lo estaremos verificando." + actor_moderations: moderation_queue: everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' From cb30a3d02c8b9f6e90faff000683951dd9e5c0ab Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 15:07:32 -0300 Subject: [PATCH 620/814] fix: ser informatives --- app/controllers/actor_moderations_controller.rb | 16 +++++++++++++++- config/locales/en.yml | 16 ++++++++++++++++ config/locales/es.yml | 17 ++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 6b924677..7c2c3d82 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -14,6 +14,12 @@ class ActorModerationsController < ApplicationController actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") + flash[:success] = I18n.t("actor_moderations.#{actor_event}.success") + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + + flash[:error] = I18n.t("actor_moderations.#{actor_event}.error") + ensure redirect_to_moderation_queue! end end @@ -21,7 +27,8 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show @remote_profile = actor_moderation.actor.content - @moderation_queue = rubanok_process(site.activity_pubs.where(actor_id: actor_moderation.actor_id), with: ActivityPubProcessor) + @moderation_queue = rubanok_process(site.activity_pubs.where(actor_id: actor_moderation.actor_id), + with: ActivityPubProcessor) end def action_on_several @@ -44,6 +51,13 @@ class ActorModerationsController < ApplicationController actor_moderation.update(actor_moderation_params(actor_moderation)) if action == :report actor_moderation.public_send(method) + + flash[:success] = I18n.t('actor_moderations.action_on_several.success') + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + + flash.delete(:success) + flash[:error] = I18n.t('actor_moderations.action_on_several.error') end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 565f0218..2ae8484b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -117,6 +117,22 @@ en: text_report: Report remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." + actor_moderations: + action_on_several: + success: "Several accounts have changed moderation state. You can find them using the filters on the Accounts section." + error: "There was an error while changing moderation state. We received a report and will be acting on it soon." + pause: + success: "Account paused. All of their comments will need to be moderated individually on the Comments section." + error: "There was an error while pausing the account. We received a report and will be acting on it soon." + allow: + success: "Account allowed. All of their comments will be approved automatically." + error: "There was an error while allowing the account. We received a report and will be acting on it soon." + block: + success: "Account blocked. All of their comments will be rejected automatically. If you want to report it anonymously to their instance, please use the Report button." + error: "There was an error while blocking the account. We received a report and will be acting on it soon." + report: + success: "Account reported." + error: "There was an error while reporting the account. We received a report and will be acting on it soon." fediblock_states: action_on_several: success: "Blocklists have been enabled, you can find their instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section." diff --git a/config/locales/es.yml b/config/locales/es.yml index 175ca661..29815a61 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -116,13 +116,28 @@ es: text_report: Reportar remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." + actor_moderations: + action_on_several: + success: "Se han modificado el estado de moderación de varias cuentas. Podés encontrarlas usando los filtros en la sección Cuentas." + error: "Hubo un error al modificar el estado de moderación de varias cuentas. Hemos recibido el reporte y lo estaremos verificando." + pause: + success: "Cuenta pausada. Todos los comentarios que haga necesitan ser aprobados manualmente en la sección Comentarios." + error: "No se pudo pausar la cuenta. Hemos recibido el reporte y lo estaremos verificando." + allow: + success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente." + error: "No se pudo permitir la cuenta. Hemos recibido el reporte y lo estaremos verificando." + block: + success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Si querés reportarla anónimamente a su instancia, podés usar el botón Reportar." + error: "No se pudo bloquear la cuenta. Hemos recibido el reporte y lo estaremos verificando." + report: + success: "Cuenta reportada a su instancia." + error: "No se pudo reportar la cuenta. Hemos recibido el reporte y lo estaremos verificando." fediblock_states: action_on_several: success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés activarlas individualmente en la sección Cuentas." error: "Hubo un error al activar o desactivar listas de bloqueo, ya recibimos el reporte y lo estaremos verificando." custom_blocklist_success: "Se agregaron las instancias personalizadas a la lista de bloqueo, podés encontrarlas filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés aprobarlas individualmente en la sección Cuentas." custom_blocklist_error: "Hubo un error al agregar instancias personalizadas a la lista de bloqueo, ya recibimos el reporte y lo estaremos verificando." - actor_moderations: moderation_queue: everything: 'Seleccionar todo' nothing: 'No hay nada para este filtro' From 8faa6d8ea8c7128f4b77987be117ddfde51d5d7e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 15:18:19 -0300 Subject: [PATCH 621/814] =?UTF-8?q?feat:=20ser=20m=C3=A1s=20informative=20?= =?UTF-8?q?con=20los=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/activity_pubs_controller.rb | 15 +++++++++++++++ config/locales/en.yml | 13 +++++++++++++ config/locales/es.yml | 13 +++++++++++++ 3 files changed, 41 insertions(+) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index c8f86ef0..1efe2b89 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -11,6 +11,12 @@ class ActivityPubsController < ApplicationController activity_pub.update(remote_flag_params(activity_pub)) if event == :report activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") + flash[:success] = I18n.t("activity_pubs.#{event}.success") + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + + flash[:error] = I18n.t("activity_pubs.#{event}.error") + ensure redirect_to_moderation_queue! end end @@ -49,6 +55,15 @@ class ActivityPubsController < ApplicationController next unless activity_pub.public_send(may) activity_pub.public_send(method) + + flash[:success] = I18n.t('activity_pubs.action_on_several.success') + rescue Exception => e + ExceptionNotifier.notify_exception(e, + data: { site: site.name, params: params.permit!.to_h, + activity_pub: activity_pub.id }) + + flash.delete(:success) + flash[:error] = I18n.t('activity_pubs.action_on_several.error') end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 2ae8484b..23df9e3c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -117,6 +117,19 @@ en: text_report: Report remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." + activity_pubs: + action_on_several: + success: "Several comments have changed moderation state. You can find them using the filters on the Comments section." + error: "There was an error while changing moderation state. We received a report and will be acting on it soon." + approve: + success: "Comment approved." + error: "There was an error while approving the comment. We received a report and will be acting on it soon." + reject: + success: "Comment rejected. You can report it using the Report button." + error: "There was an error while rejecting the comment. We received a report and will be acting on it soon." + report: + success: "Comment reported." + error: "There was an error while reporting the comment. We received a report and will be acting on it soon." actor_moderations: action_on_several: success: "Several accounts have changed moderation state. You can find them using the filters on the Accounts section." diff --git a/config/locales/es.yml b/config/locales/es.yml index 29815a61..1773a0c6 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -116,6 +116,19 @@ es: text_report: Reportar remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." + activity_pubs: + action_on_several: + success: "Se ha modificado el estado de moderación de varios comentarios. Podés encontrarlos usando los filtros en la sección Comentarios." + error: "Hubo un error al modificar el estado de moderación de varios comentarios. Hemos recibido el reporte y lo estaremos verificando." + approve: + success: "Comentario aprobado." + error: "No se puedo aprobar el comentario. Hemos recibido el reporte y lo estaremos verificando." + reject: + success: "Comentario rechazado. Podés reportarlo usando el botón Reportar." + error: "No se puedo rechazar el comentario. Hemos recibido el reporte y lo estaremos verificando." + report: + success: "Comentario reportado." + error: "No se puedo reportar el comentario. Hemos recibido el reporte y lo estaremos verificando." actor_moderations: action_on_several: success: "Se han modificado el estado de moderación de varias cuentas. Podés encontrarlas usando los filtros en la sección Cuentas." From 42be495465a0fddd2c97db8e5df263f979a48957 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 15:19:21 -0300 Subject: [PATCH 622/814] =?UTF-8?q?fix:=20no=20prometer=20que=20el=20repor?= =?UTF-8?q?te=20es=20an=C3=B3nimo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit le admin de la instancia remota siempre puede d0xear --- config/locales/en.yml | 2 +- config/locales/es.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 23df9e3c..73920b57 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -141,7 +141,7 @@ en: success: "Account allowed. All of their comments will be approved automatically." error: "There was an error while allowing the account. We received a report and will be acting on it soon." block: - success: "Account blocked. All of their comments will be rejected automatically. If you want to report it anonymously to their instance, please use the Report button." + success: "Account blocked. All of their comments will be rejected automatically. If you want to report it to their instance, please use the Report button." error: "There was an error while blocking the account. We received a report and will be acting on it soon." report: success: "Account reported." diff --git a/config/locales/es.yml b/config/locales/es.yml index 1773a0c6..467f15e8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -131,7 +131,7 @@ es: error: "No se puedo reportar el comentario. Hemos recibido el reporte y lo estaremos verificando." actor_moderations: action_on_several: - success: "Se han modificado el estado de moderación de varias cuentas. Podés encontrarlas usando los filtros en la sección Cuentas." + success: "Se ha modificado el estado de moderación de varias cuentas. Podés encontrarlas usando los filtros en la sección Cuentas." error: "Hubo un error al modificar el estado de moderación de varias cuentas. Hemos recibido el reporte y lo estaremos verificando." pause: success: "Cuenta pausada. Todos los comentarios que haga necesitan ser aprobados manualmente en la sección Comentarios." @@ -140,7 +140,7 @@ es: success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente." error: "No se pudo permitir la cuenta. Hemos recibido el reporte y lo estaremos verificando." block: - success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Si querés reportarla anónimamente a su instancia, podés usar el botón Reportar." + success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Si querés reportarla a su instancia, podés usar el botón Reportar." error: "No se pudo bloquear la cuenta. Hemos recibido el reporte y lo estaremos verificando." report: success: "Cuenta reportada a su instancia." From 6b74bc454da0a307c32c145af683297d2bc202eb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 15:20:08 -0300 Subject: [PATCH 623/814] fix: sin dummy data en posts --- app/controllers/posts_controller.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 99dc6f7d..057c3068 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -38,7 +38,6 @@ class PostsController < ApplicationController @usuarie = site.usuarie? current_usuarie @site_stat = SiteStat.new(site) - dummy_data end def show @@ -82,7 +81,6 @@ class PostsController < ApplicationController authorize post breadcrumb post.title.value, site_post_path(site, post, locale: locale), match: :exact breadcrumb 'posts.edit', '' - dummy_data end def update From 071102fa3b82247fd7601f4548c3947106b6fd63 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 15:31:41 -0300 Subject: [PATCH 624/814] =?UTF-8?q?feat:=20al=20moderar=20una=20cuenta,=20?= =?UTF-8?q?tambi=C3=A9n=20moderar=20sus=20comentarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/actor_moderation.rb | 16 ++++++++++++++++ config/locales/en.yml | 4 ++-- config/locales/es.yml | 4 ++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 01613f72..4b220a58 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -42,19 +42,35 @@ class ActorModeration < ApplicationRecord end end + # Al permitir una cuenta se permiten todos los comentarios + # pendientes de moderación que ya hizo. event :allow do transitions from: %i[paused blocked reported], to: :allowed before do allow_remotely! + + site.activity_pubs.paused.where(actor_id: self.actor_id).find_each do |activity_pub| + activity_pub.allow! if activity_pub.may_allow? + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: activity_pub_id }) + end end end + # Al bloquear una cuenta se bloquean todos los comentarios + # pendientes de moderación que hizo. event :block do transitions from: %i[paused allowed], to: :blocked before do block_remotely! + + site.activity_pubs.paused.where(actor_id: self.actor_id).find_each do |activity_pub| + activity_pub.reject! if activity_pub.may_reject? + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: activity_pub_id }) + end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 73920b57..48d9ca61 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -138,10 +138,10 @@ en: success: "Account paused. All of their comments will need to be moderated individually on the Comments section." error: "There was an error while pausing the account. We received a report and will be acting on it soon." allow: - success: "Account allowed. All of their comments will be approved automatically." + success: "Account allowed. All of their comments will be approved automatically. Any pending comments have been approved." error: "There was an error while allowing the account. We received a report and will be acting on it soon." block: - success: "Account blocked. All of their comments will be rejected automatically. If you want to report it to their instance, please use the Report button." + success: "Account blocked. All of their comments will be rejected automatically. Any pending comments have been rejected. If you want to report it to their instance, please use the Report button." error: "There was an error while blocking the account. We received a report and will be acting on it soon." report: success: "Account reported." diff --git a/config/locales/es.yml b/config/locales/es.yml index 467f15e8..3df608f5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -137,10 +137,10 @@ es: success: "Cuenta pausada. Todos los comentarios que haga necesitan ser aprobados manualmente en la sección Comentarios." error: "No se pudo pausar la cuenta. Hemos recibido el reporte y lo estaremos verificando." allow: - success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente." + success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente. Todos los comentarios pendientes de moderación fueron aprobados." error: "No se pudo permitir la cuenta. Hemos recibido el reporte y lo estaremos verificando." block: - success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Si querés reportarla a su instancia, podés usar el botón Reportar." + success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Todos los comentarios pendientes de moderación fueron rechazados. Si querés reportarla a su instancia, podés usar el botón Reportar." error: "No se pudo bloquear la cuenta. Hemos recibido el reporte y lo estaremos verificando." report: success: "Cuenta reportada a su instancia." From 522cef8c9ae99ce5cc3c2d0ae911e5611064a7d3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Mar 2024 15:55:01 -0300 Subject: [PATCH 625/814] feat: acciones en masa para actividades --- app/models/activity_pub.rb | 34 ++++++++++++++++++++-- app/models/actor_moderation.rb | 12 ++------ app/models/concerns/aasm_events_concern.rb | 8 +++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 33cd4d45..fce340db 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -38,6 +38,28 @@ class ActivityPub < ApplicationRecord end end + # Permite todos los comentarios. No podemos hacer acciones en masa + # sobre comentarios en la Social Inbox, con lo que tenemos que + # comunicarnos individualmente. + def self.allow_all! + self.find_each do |activity_pub| + activity_pub.allow! if activity_pub.may_allow? + rescue Exception => e + notify_exception!(e, activity_pub) + end + end + + # Rechaza todos los comentarios. No podemos hacer acciones en masa + # sobre comentarios en la Social Inbox, con lo que tenemos que + # comunicarnos individualmente. + def self.reject_all! + self.find_each do |activity_pub| + activity_pub.reject! if activity_pub.may_reject? + rescue Exception => e + notify_exception!(e, activity_pub) + end + end + aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true @@ -68,7 +90,7 @@ class ActivityPub < ApplicationRecord transitions from: %i[paused], to: :approved before do - raise unless site.social_inbox.inbox.accept(id: object.uri).ok? + allow_remotely! end end @@ -77,7 +99,7 @@ class ActivityPub < ApplicationRecord transitions from: %i[paused approved], to: :rejected before do - raise unless site.social_inbox.inbox.reject(id: object.uri).ok? + reject_remotely! end end @@ -90,4 +112,12 @@ class ActivityPub < ApplicationRecord end end end + + def reject_remotely! + raise unless site.social_inbox.inbox.reject(id: object.uri).ok? + end + + def allow_remotely! + raise unless site.social_inbox.inbox.accept(id: object.uri).ok? + end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 4b220a58..a510f1eb 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -50,11 +50,7 @@ class ActorModeration < ApplicationRecord before do allow_remotely! - site.activity_pubs.paused.where(actor_id: self.actor_id).find_each do |activity_pub| - activity_pub.allow! if activity_pub.may_allow? - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: activity_pub_id }) - end + site.activity_pubs.paused.where(actor_id: self.actor_id).allow_all! end end @@ -66,11 +62,7 @@ class ActorModeration < ApplicationRecord before do block_remotely! - site.activity_pubs.paused.where(actor_id: self.actor_id).find_each do |activity_pub| - activity_pub.reject! if activity_pub.may_reject? - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: activity_pub_id }) - end + site.activity_pubs.paused.where(actor_id: self.actor_id).reject_all! end end diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 418368d8..b189dbe4 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -27,5 +27,13 @@ module AasmEventsConcern def self.states aasm.states.map(&:name) - self::IGNORED_STATES end + + # Envía notificación de errores + # + # @param exception [Exception] + # @param record [ApplicationRecord] + def notify_exception!(exception, record) + ExceptionNotifier.notify_exception(exception, data: { site: site.name, record_type: record.class.name, record_id: record.id }) + end end end From bf75d50cc35d578c410a117c42b32952a1fbab69 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 13:57:31 -0300 Subject: [PATCH 626/814] =?UTF-8?q?feat:=20modificar=20el=20estado=20de=20?= =?UTF-8?q?moderaci=C3=B3n=20en=20masa=20#15328=20#15327?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/activity_pubs_controller.rb | 45 +++++++------------ .../actor_moderations_controller.rb | 23 +++++----- .../instance_moderations_controller.rb | 15 ++++--- .../activity_pub/instance_moderation_job.rb | 13 ++---- app/models/activity_pub.rb | 22 --------- app/models/actor_moderation.rb | 13 ------ app/models/concerns/aasm_events_concern.rb | 20 +++++++++ app/models/fediblock_state.rb | 12 ----- app/models/instance_moderation.rb | 30 ++++++------- config/locales/es.yml | 13 ++++++ 10 files changed, 88 insertions(+), 118 deletions(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 1efe2b89..edece8f8 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -27,7 +27,7 @@ class ActivityPubsController < ApplicationController authorize activity_pubs action = params[:activity_pub_action].to_sym - method = :"#{action}!" + method = :"#{action}_all!" may = :"may_#{action}?" redirect_to_moderation_queue! @@ -35,36 +35,25 @@ class ActivityPubsController < ApplicationController return unless ActivityPub.events.include? action # Crear una sola remote flag por autore - if action == :report - message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message) - - activity_pubs.distinct.pluck(:actor_id).each do |actor_id| - remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id) - remote_flag.message = message - # Lo estamos actualizando, con lo que lo vamos a volver a enviar - remote_flag.requeue if remote_flag.persisted? - remote_flag.save - # XXX: Idealmente todas las ActivityPub que enviamos pueden - # cambiar de estado, pero chequeamos de todas formas. - remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) }) - end - end - ActivityPub.transaction do - activity_pubs.find_each do |activity_pub| - next unless activity_pub.public_send(may) + if action == :report + message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message) - activity_pub.public_send(method) - - flash[:success] = I18n.t('activity_pubs.action_on_several.success') - rescue Exception => e - ExceptionNotifier.notify_exception(e, - data: { site: site.name, params: params.permit!.to_h, - activity_pub: activity_pub.id }) - - flash.delete(:success) - flash[:error] = I18n.t('activity_pubs.action_on_several.error') + activity_pubs.distinct.pluck(:actor_id).each do |actor_id| + remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id) + remote_flag.message = message + # Lo estamos actualizando, con lo que lo vamos a volver a enviar + remote_flag.requeue if remote_flag.persisted? + remote_flag.save + # XXX: Idealmente todas las ActivityPub que enviamos pueden + # cambiar de estado, pero chequeamos de todas formas. + remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) }) + end end + + message = activity_pubs.public_send(method) ? :success : :error + + flash[message] = I18n.t("activity_pubs.action_on_several.#{message}") end end diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 7c2c3d82..bc4a059b 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -37,7 +37,7 @@ class ActorModerationsController < ApplicationController authorize actor_moderations action = params[:actor_moderation_action].to_sym - method = :"#{action}!" + method = :"#{action}_all!" may = :"may_#{action}?" redirect_to_moderation_queue! @@ -45,20 +45,17 @@ class ActorModerationsController < ApplicationController return unless ActorModeration.events.include? action ActorModeration.transaction do - actor_moderations.find_each do |actor_moderation| - next unless actor_moderation.public_send(may) + if action == :report + actor_moderations.find_each do |actor_moderation| + next unless actor_moderation.public_send(may) - actor_moderation.update(actor_moderation_params(actor_moderation)) if action == :report - - actor_moderation.public_send(method) - - flash[:success] = I18n.t('actor_moderations.action_on_several.success') - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) - - flash.delete(:success) - flash[:error] = I18n.t('actor_moderations.action_on_several.error') + actor_moderation.update(actor_moderation_params(actor_moderation)) + end end + + message = actor_moderation.public_send(method) ? :success : :error + + flash[message] = I18n.t("actor_moderations.action_on_several.#{message}") end end diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 270f0588..06f5cfc1 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -10,6 +10,12 @@ class InstanceModerationsController < ApplicationController instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?") + flash[:success] = I18n.t("instance_moderations.#{event}.success") + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + + flash[:error] = I18n.t("instance_moderations.#{event}.error") + ensure redirect_to_moderation_queue! end end @@ -20,17 +26,16 @@ class InstanceModerationsController < ApplicationController authorize instance_moderations action = params[:instance_moderation_action].to_sym - method = :"#{action}!" - may = :"may_#{action}?" + method = :"#{action}_all!" redirect_to_moderation_queue! return unless InstanceModeration.events.include? action InstanceModeration.transaction do - instance_moderations.find_each do |instance_moderation| - instance_moderation.public_send(method) if instance_moderation.public_send(may) - end + message = instance_moderations.public_send(method) ? :success : :error + + flash[:message] = I18n.t("instance_moderations.action_on_several.#{message}") end end diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index 17def46e..e28be84e 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -14,7 +14,6 @@ class ActivityPub end instances = ActivityPub::Instance.where(hostname: hostnames) - success = true Site.transaction do # Crea todas las moderaciones de instancia con un estado por @@ -22,17 +21,11 @@ class ActivityPub instances.find_each do |instance| # Esto bloquea cada una individualmente en la Social Inbox, # idealmente son pocas instancias las que aparecen. - site.instance_moderations.find_or_create_by(instance: instance).tap do |instance_moderation| - instance_moderation.block! if instance_moderation.may_block? - # Notificar todos los errores sin detener la ejecución - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, instance_moderation: instance_moderation.id }) - success = false - end + site.instance_moderations.find_or_create_by(instance: instance) end - end - success + site.instance_moderations.where(instance_id: instances.ids).block_all! + end end end end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index fce340db..38bf3b3a 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -38,28 +38,6 @@ class ActivityPub < ApplicationRecord end end - # Permite todos los comentarios. No podemos hacer acciones en masa - # sobre comentarios en la Social Inbox, con lo que tenemos que - # comunicarnos individualmente. - def self.allow_all! - self.find_each do |activity_pub| - activity_pub.allow! if activity_pub.may_allow? - rescue Exception => e - notify_exception!(e, activity_pub) - end - end - - # Rechaza todos los comentarios. No podemos hacer acciones en masa - # sobre comentarios en la Social Inbox, con lo que tenemos que - # comunicarnos individualmente. - def self.reject_all! - self.find_each do |activity_pub| - activity_pub.reject! if activity_pub.may_reject? - rescue Exception => e - notify_exception!(e, activity_pub) - end - end - aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index a510f1eb..7cb8827d 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -14,19 +14,6 @@ class ActorModeration < ApplicationRecord accepts_nested_attributes_for :remote_flag - # Bloquea todes les Actores bloqueables - def self.block_all! - self.update_all(aasm_state: 'blocked', updated_at: Time.now) - end - - def self.pause_all! - self.update_all(aasm_state: 'paused', updated_at: Time.now) - end - - def self.remove_all! - self.update_all(aasm_state: 'removed', updated_at: Time.now) - end - aasm do state :paused, initial: true state :allowed diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index b189dbe4..967a61b3 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -28,6 +28,26 @@ module AasmEventsConcern aasm.states.map(&:name) - self::IGNORED_STATES end + # Define un método que cambia el estado para todos los objetos del + # scope actual. + # + # @return [Bool] Si hubo al menos un error, devuelve false. + self.events.each do |event| + define_singleton_method(:"#{event}_all!") do + success = true + + self.find_each do |object| + object.public_send(:"#{event}!") if object.public_send(:"may_#{event}?") + rescue Exception => e + success = false + + notify_exception! e, object + end + + success + end + end + # Envía notificación de errores # # @param exception [Exception] diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index e50abaef..dfdc4e34 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -39,12 +39,6 @@ class FediblockState < ApplicationRecord # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) - - # Bloquear a todes les Actores de las instancias bloqueadas para - # indicarle a le usuarie que les tiene que desbloquear - # manualmente. - actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids - ActorModeration.where(actor_id: actor_ids).paused.block_all! end end @@ -66,12 +60,6 @@ class FediblockState < ApplicationRecord # bloqueadas por otros fediblocks. instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids site.instance_moderations.where(instance_id: instance_ids).pause_all! - - # Volver a pausar todes les actores de esta instancia que fueron - # bloqueades, a menos que hayan sido bloqueades por otro - # fediblock. - actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids - ActorModeration.where(actor_id: actor_ids).blocked.pause_all! end end end diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index ef04b7ff..918c6ad0 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -11,26 +11,13 @@ class InstanceModeration < ApplicationRecord belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' - # Traer todas las instancias bloqueables, según la máquina de estados, - # todas las que no estén bloqueadas ya. - scope :may_block, -> { where.not(aasm_state: 'blocked') } - scope :may_pause, -> { where.not(aasm_state: 'paused') } - - # Bloquear instancias en masa - def self.block_all! - self.may_block.update_all(aasm_state: 'blocked', updated_at: Time.now) - end - - # Pausar instancias en masa - def self.pause_all! - self.may_pause.update_all(aasm_state: 'paused', updated_at: Time.now) - end - aasm do state :paused, initial: true state :allowed state :blocked + # Al volver la instancia a pausa no cambiamos el estado de + # moderación de actores pre-existente. event :pause do transitions from: %i[allowed blocked], to: :paused @@ -39,23 +26,36 @@ class InstanceModeration < ApplicationRecord end end + # Al permitir, también permitimos todes les actores que no hayan + # tenido acciones de moderación. event :allow do transitions from: %i[paused blocked], to: :allowed before do allow_remotely! + + site.actor_moderations.paused.where(actor_id: actor_ids).allow_all! end end + # Al bloquear, también bloqueamos a todes les actores que no hayan + # tenido acciones de moderación. event :block do transitions from: %i[paused allowed], to: :blocked before do block_remotely! + + site.actor_moderations.paused.where(actor_id: actor_ids).block_all! end end end + # @return [Array] + def actor_ids + ActivityPub::Actor.where(instance_id: self.instance_id).ids + end + # Elimina la instancia de todas las listas # # @return [Boolean] diff --git a/config/locales/es.yml b/config/locales/es.yml index 3df608f5..3cc6c49a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -145,6 +145,19 @@ es: report: success: "Cuenta reportada a su instancia." error: "No se pudo reportar la cuenta. Hemos recibido el reporte y lo estaremos verificando." + instance_moderations: + action_on_several: + success: "Se ha modificado el estado de moderación de varias instancias. Podés encontrarlas usando los filtros en la sección Instancias." + error: "Hubo un error al modificar el estado de moderación de varias instancias. Hemos recibido el reporte y lo estaremos verificando." + pause: + success: "Instancia pausada. Todos los comentarios y cuentas de esta instancia necesitan ser aprobados manualmente. No se ha modificado el estado de moderación de cuentas y comentarios pre-existentes." + error: "No se pudo pausar la instancia. Hemos recibido el reporte y lo estaremos verificando." + allow: + success: "Instancia permitida. Todos los comentarios y cuentas pendientes de moderación fueron aprobados y los próximos serán aprobados inmediatamente." + error: "No se pudo permitir la instancia. Hemos recibido el reporte y lo estaremos verificando." + block: + success: "Instancia bloqueada. Todos los comentarios y cuentas serán rechazados inmediatamente. Todos los comentarios y cuentas pendientes de moderación fueron rechazados." + error: "No se pudo bloquear la instancia. Hemos recibido el reporte y lo estaremos verificando." fediblock_states: action_on_several: success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés activarlas individualmente en la sección Cuentas." From d2d327dc848b6b5e4abd318d71575effe125c89e Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 14:24:38 -0300 Subject: [PATCH 627/814] =?UTF-8?q?fixup!=20feat:=20modificar=20el=20estad?= =?UTF-8?q?o=20de=20moderaci=C3=B3n=20en=20masa=20#15328=20#15327?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 6 +++--- app/models/actor_moderation.rb | 6 +++--- app/models/instance_moderation.rb | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 38bf3b3a..61120a58 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -8,12 +8,12 @@ # # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} class ActivityPub < ApplicationRecord - include AASM - include AasmEventsConcern - IGNORED_EVENTS = %i[remove] IGNORED_STATES = %i[removed] + include AASM + include AasmEventsConcern + belongs_to :instance belongs_to :site belongs_to :object, polymorphic: true diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 7cb8827d..04c96ac0 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -2,12 +2,12 @@ # Mantiene la relación entre Site y Actor class ActorModeration < ApplicationRecord - include AASM - include AasmEventsConcern - IGNORED_EVENTS = %i[remove] IGNORED_STATES = %i[removed] + include AASM + include AasmEventsConcern + belongs_to :site belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag' belongs_to :actor, class_name: 'ActivityPub::Actor' diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 918c6ad0..1ed7d2c0 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -2,12 +2,12 @@ # Mantiene el registro de relaciones entre sitios e instancias class InstanceModeration < ApplicationRecord - include AASM - include AasmEventsConcern - IGNORED_EVENTS = [] IGNORED_STATES = [] + include AASM + include AasmEventsConcern + belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' From e783390747f2ab054f4765b353ca575ea3d7b802 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 14:28:26 -0300 Subject: [PATCH 628/814] =?UTF-8?q?fixup!=20fixup!=20feat:=20modificar=20e?= =?UTF-8?q?l=20estado=20de=20moderaci=C3=B3n=20en=20masa=20#15328=20#15327?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 48d9ca61..bc6b1285 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -146,6 +146,19 @@ en: report: success: "Account reported." error: "There was an error while reporting the account. We received a report and will be acting on it soon." + instance_moderations: + action_on_several: + success: "Several instances have changed moderation state. You can find them using the filters on the Instances section." + error: "There was an error while changing moderation state. We received a report and will be acting on it soon." + pause: + success: "Instance paused. All of their comments and accounts will need to be moderated individually." + error: "There was an error while pausing the instance. We received a report and will be acting on it soon." + allow: + success: "Instance allowed. All of their comments and accounts will be approved automatically. Any pending comments and accounts have been also approved." + error: "There was an error while allowing the instance. We received a report and will be acting on it soon." + block: + success: "Instance blocked. All of their comments and accounts will be rejected automatically. Any pending comments and accounts have been also rejected." + error: "There was an error while blocking the instance. We received a report and will be acting on it soon." fediblock_states: action_on_several: success: "Blocklists have been enabled, you can find their instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section." From 20c6d6af5042360736d8ebd212da2b99e118ec41 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 14:30:43 -0300 Subject: [PATCH 629/814] feat: eliminar todos los comentarios de une actore eliminade --- app/models/actor_moderation.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 04c96ac0..783160c7 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -67,6 +67,10 @@ class ActorModeration < ApplicationRecord # mostrarlo y todas sus actividades. event :remove do transitions to: :removed + + before do + site.activity_pubs.where(actor_id: self.actor_id).remove_all! + end end end From 12f77e46581cc539fc6655f8f282c2d72147e71e Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 15:57:04 -0300 Subject: [PATCH 630/814] fix: actualizar cliente --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 366b58a5..7b19ba75 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,7 +166,7 @@ GEM devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.4.0rc3) + distributed-press-api-client (0.4.0) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema @@ -626,7 +626,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.4.0rc3) + distributed-press-api-client (~> 0.4.0) dotenv-rails down ed25519 From 3c07ddf12c946303fddb5403b166faa6905b4ea1 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 15:59:42 -0300 Subject: [PATCH 631/814] =?UTF-8?q?fixup!=20fixup!=20fixup!=20feat:=20modi?= =?UTF-8?q?ficar=20el=20estado=20de=20moderaci=C3=B3n=20en=20masa=20#15328?= =?UTF-8?q?=20#15327?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/remote_flag.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index 76143414..1b6f5c5f 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -2,6 +2,9 @@ class ActivityPub class RemoteFlag < ApplicationRecord + IGNORED_EVENTS = [] + IGNORED_STATES = [] + include AASM include AasmEventsConcern From 4fde9793d733426a50ccf86104841cbdfe3140f8 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 17:09:21 -0300 Subject: [PATCH 632/814] fix: permitir que la tarea se reporte como hecha --- app/models/deploy_social_distributed_press.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index b7525dca..c7a103a4 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -13,12 +13,11 @@ class DeploySocialDistributedPress < Deploy key = Shellwords.escape file.path dest = Shellwords.escape destination - run %(bundle exec jekyll notify --trace --key #{key} --destination "#{dest}"), output: output + run(%(bundle exec jekyll notify --trace --key #{key} --destination "#{dest}"), output: output).tap do |_| + create_hooks! + enable_fediblocks! + end end - - - create_hooks! - enable_fediblocks! end # Igual que DeployLocal From d44bcc4098d0959d78c89ac564ee78ec2d01248b Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 17:30:47 -0300 Subject: [PATCH 633/814] fix: typo --- app/jobs/activity_pub/remote_flag_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 26db937a..f5650d53 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -13,7 +13,7 @@ class ActivityPub self.priority = 30 def perform(remote_flag:) - return if remote_flag.can_queue? + return if remote_flag.may_queue? remote_flag.queue! From 45d56502c11bb9c65f5538e08173052699f845ce Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Mar 2024 17:44:40 -0300 Subject: [PATCH 634/814] fix: aprobar --- app/models/actor_moderation.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 783160c7..ad29739f 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -37,7 +37,7 @@ class ActorModeration < ApplicationRecord before do allow_remotely! - site.activity_pubs.paused.where(actor_id: self.actor_id).allow_all! + site.activity_pubs.paused.where(actor_id: self.actor_id).approve_all! end end From 32042f32e23d95bb8dcde1976eb4d7203d411753 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 11:05:28 -0300 Subject: [PATCH 635/814] =?UTF-8?q?fix:=20no=20ignorar=20ning=C3=BAn=20eve?= =?UTF-8?q?nto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15366 closes #15367 closes #15368 closes #15369 closes #15370 closes #15371 closes #15372 closes #15373 closes #15374 closes #15375 closes #15376 closes #15377 closes #15378 closes #15379 closes #15380 closes #15381 closes #15382 closes #15383 closes #15384 closes #15385 closes #15386 closes #15387 closes #15388 closes #15389 closes #15390 closes #15391 closes #15392 closes #15393 closes #15394 closes #15395 closes #15396 closes #15397 closes #15398 closes #15399 closes #15400 closes #15401 closes #15402 closes #15403 closes #15404 closes #15405 closes #15406 closes #15407 closes #15408 closes #15409 closes #15410 closes #15411 closes #15412 closes #15413 closes #15414 closes #15415 closes #15416 closes #15417 closes #15418 closes #15419 closes #15420 closes #15421 closes #15422 closes #15423 closes #15424 closes #15425 closes #15426 closes #15427 closes #15428 closes #15429 closes #15430 closes #15431 closes #15432 closes #15433 closes #15434 closes #15435 closes #15436 closes #15437 closes #15438 closes #15439 closes #15440 closes #15441 closes #15442 closes #15443 closes #15444 closes #15445 closes #15446 closes #15447 closes #15448 closes #15449 closes #15450 closes #15451 closes #15452 closes #15453 closes #15454 closes #15455 closes #15456 closes #15457 closes #15458 closes #15459 closes #15460 closes #15461 closes #15462 closes #15463 closes #15464 closes #15465 closes #15466 closes #15467 closes #15468 closes #15469 closes #15470 closes #15471 closes #15472 closes #15473 closes #15477 closes #15478 closes #15479 closes #15480 closes #15481 closes #15482 closes #15483 closes #15484 closes #15485 closes #15486 closes #15487 closes #15488 closes #15489 closes #15490 closes #15491 closes #15492 closes #15493 closes #15494 closes #15495 closes #15496 closes #15497 closes #15498 closes #15499 closes #15500 closes #15501 closes #15502 closes #15503 closes #15504 closes #15505 closes #15506 closes #15507 closes #15508 closes #15509 closes #15510 closes #15511 closes #15512 closes #15513 closes #15514 closes #15515 closes #15516 closes #15517 closes #15518 closes #15519 closes #15520 closes #15521 closes #15522 closes #15523 closes #15524 closes #15525 closes #15526 closes #15527 closes #15528 closes #15529 closes #15530 closes #15531 closes #15532 closes #15533 closes #15534 closes #15535 closes #15536 closes #15537 closes #15538 closes #15539 closes #15540 closes #15541 closes #15542 closes #15543 closes #15544 closes #15545 closes #15546 closes #15547 closes #15548 closes #15549 --- app/models/concerns/aasm_events_concern.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 967a61b3..08b4edd7 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -32,7 +32,7 @@ module AasmEventsConcern # scope actual. # # @return [Bool] Si hubo al menos un error, devuelve false. - self.events.each do |event| + self.aasm.events.map(&:name).each do |event| define_singleton_method(:"#{event}_all!") do success = true From 40edccf8bbbe9c272245a11674d9a0209ec57955 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 11:15:31 -0300 Subject: [PATCH 636/814] =?UTF-8?q?fixup!=20fix:=20no=20ignorar=20ning?= =?UTF-8?q?=C3=BAn=20evento?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 4 +++- app/models/activity_pub/remote_flag.rb | 4 +++- app/models/actor_moderation.rb | 4 +++- app/models/instance_moderation.rb | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 61120a58..a6b1401b 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -12,7 +12,6 @@ class ActivityPub < ApplicationRecord IGNORED_STATES = %i[removed] include AASM - include AasmEventsConcern belongs_to :instance belongs_to :site @@ -91,6 +90,9 @@ class ActivityPub < ApplicationRecord end end + # Definir eventos en masa + include AasmEventsConcern + def reject_remotely! raise unless site.social_inbox.inbox.reject(id: object.uri).ok? end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index 1b6f5c5f..70f09dcc 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -6,7 +6,6 @@ class ActivityPub IGNORED_STATES = [] include AASM - include AasmEventsConcern aasm do state :waiting, initial: true @@ -26,6 +25,9 @@ class ActivityPub end end + # Definir eventos en masa + include AasmEventsConcern + belongs_to :actor belongs_to :site diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index ad29739f..7e68f60b 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -6,7 +6,6 @@ class ActorModeration < ApplicationRecord IGNORED_STATES = %i[removed] include AASM - include AasmEventsConcern belongs_to :site belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag' @@ -74,6 +73,9 @@ class ActorModeration < ApplicationRecord end end + # Definir eventos en masa + include AasmEventsConcern + def pause_remotely! raise unless actor.mention && diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 1ed7d2c0..5b246cee 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -6,7 +6,6 @@ class InstanceModeration < ApplicationRecord IGNORED_STATES = [] include AASM - include AasmEventsConcern belongs_to :site belongs_to :instance, class_name: 'ActivityPub::Instance' @@ -51,6 +50,9 @@ class InstanceModeration < ApplicationRecord end end + # Definir eventos en masa + include AasmEventsConcern + # @return [Array] def actor_ids ActivityPub::Actor.where(instance_id: self.instance_id).ids From ef482aaedf2d8696408a4d40e642df8730b70447 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 11:41:04 -0300 Subject: [PATCH 637/814] =?UTF-8?q?fix:=20el=20m=C3=A9todo=20es=20de=20cla?= =?UTF-8?q?se?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15553 --- app/models/concerns/aasm_events_concern.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 08b4edd7..70fb5ed2 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -52,8 +52,8 @@ module AasmEventsConcern # # @param exception [Exception] # @param record [ApplicationRecord] - def notify_exception!(exception, record) - ExceptionNotifier.notify_exception(exception, data: { site: site.name, record_type: record.class.name, record_id: record.id }) + def self.notify_exception!(exception, record) + ExceptionNotifier.notify_exception(exception, data: { record_type: record.class.name, record_id: record.id }) end end end From f794e8057b3248dfafd1b259a0100a95db847c87 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 15:29:34 -0300 Subject: [PATCH 638/814] feat: no hacer acciones en cascada #15327 #15328 --- .../activity_pub/instance_moderation_job.rb | 13 ++++++++---- app/models/actor_moderation.rb | 8 ++------ app/models/concerns/aasm_events_concern.rb | 13 ++++++++++++ app/models/fediblock_state.rb | 16 +++++---------- app/models/instance_moderation.rb | 12 ++++------- config/locales/en.yml | 20 +++++++++---------- config/locales/es.yml | 20 +++++++++---------- 7 files changed, 53 insertions(+), 49 deletions(-) diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index e28be84e..214f8dd4 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -3,11 +3,10 @@ class ActivityPub # Bloquea varias instancias de una sola vez class InstanceModerationJob < ApplicationJob - self.priority = 50 - # @param :site [Site] # @param :hostnames [Array] - def perform(site:, hostnames:) + # @param :perform_remotely [Bool] + def perform(site:, hostnames:, perform_remotely: true) # Crear las instancias que no existan todavía hostnames.each do |hostname| ActivityPub::Instance.find_or_create_by(hostname: hostname) @@ -24,7 +23,13 @@ class ActivityPub site.instance_moderations.find_or_create_by(instance: instance) end - site.instance_moderations.where(instance_id: instances.ids).block_all! + scope = site.instance_moderations.where(instance_id: instances.ids) + + if perform_remotely + scope.block_all! + else + scope.block_all_without_callbacks! + end end end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 7e68f60b..3b183a4f 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -28,27 +28,23 @@ class ActorModeration < ApplicationRecord end end - # Al permitir una cuenta se permiten todos los comentarios + # Al permitir una cuenta no se permiten todos los comentarios # pendientes de moderación que ya hizo. event :allow do transitions from: %i[paused blocked reported], to: :allowed before do allow_remotely! - - site.activity_pubs.paused.where(actor_id: self.actor_id).approve_all! end end - # Al bloquear una cuenta se bloquean todos los comentarios + # Al bloquear una cuenta no se bloquean todos los comentarios # pendientes de moderación que hizo. event :block do transitions from: %i[paused allowed], to: :blocked before do block_remotely! - - site.activity_pubs.paused.where(actor_id: self.actor_id).reject_all! end end diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 70fb5ed2..4de5f748 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -46,6 +46,19 @@ module AasmEventsConcern success end + + # Ejecuta la transición del evento en la base de datos sin + # ejecutar los callbacks, sin modificar los items del scope que no + # pueden transicionar. + # + # @return [Integer] Registros modificados + define_singleton_method(:"#{event}_all_without_callbacks!") do + aasm_event = self.aasm.events.find { |e| e.name == event } + to_state = aasm_event.transitions.map(&:to).first + from_states = aasm_event.transitions.map(&:from) + + self.unscope(where: :aasm_state).where(aasm_state: from_states).update_all(aasm_state: to_state, updated_at: Time.now) + end end # Envía notificación de errores diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index dfdc4e34..9dde1db3 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -30,15 +30,9 @@ class FediblockState < ApplicationRecord # Bloquear todos las instancias de este Fediblock enable_remotely! list_names(fediblock.hostnames) - # Al actualizar el estado en masa garantizamos que las - # instancias que ya existen queden sincronizadas con el bloqueo - # en masa que acabamos de hacer. - instance_ids = fediblock.instances.ids - site.instance_moderations.where(instance_id: instance_ids).block_all! - # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. - ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) + ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames, perform_remotely: false) end end @@ -56,10 +50,10 @@ class FediblockState < ApplicationRecord # otros fediblocks disable_remotely! list_names(unique_hostnames) - # Pausar todas las moderaciones de las instancias que no estén - # bloqueadas por otros fediblocks. - instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids - site.instance_moderations.where(instance_id: instance_ids).pause_all! + # Pausar todas las moderaciones de las instancias que no estén + # bloqueadas por otros fediblocks. + instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids + site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks! end end end diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 5b246cee..9cb6ffdc 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -25,27 +25,23 @@ class InstanceModeration < ApplicationRecord end end - # Al permitir, también permitimos todes les actores que no hayan - # tenido acciones de moderación. + # Al permitir, solo bloqueamos la instancia, sin modificar el estado + # de les actores y comentarios retroactivamente. event :allow do transitions from: %i[paused blocked], to: :allowed before do allow_remotely! - - site.actor_moderations.paused.where(actor_id: actor_ids).allow_all! end end - # Al bloquear, también bloqueamos a todes les actores que no hayan - # tenido acciones de moderación. + # Al bloquear, solo bloqueamos la instancia, sin modificar el estado + # de les actores y comentarios retroactivamente. event :block do transitions from: %i[paused allowed], to: :blocked before do block_remotely! - - site.actor_moderations.paused.where(actor_id: actor_ids).block_all! end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index bc6b1285..d745e2d5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -132,38 +132,38 @@ en: error: "There was an error while reporting the comment. We received a report and will be acting on it soon." actor_moderations: action_on_several: - success: "Several accounts have changed moderation state. You can find them using the filters on the Accounts section." + success: "Several accounts have changed moderation state. You can find them using the filters on the Accounts section. No action was performed over existing Comments." error: "There was an error while changing moderation state. We received a report and will be acting on it soon." pause: - success: "Account paused. All of their comments will need to be moderated individually on the Comments section." + success: "Account paused. No action was performed on existing Comments." error: "There was an error while pausing the account. We received a report and will be acting on it soon." allow: - success: "Account allowed. All of their comments will be approved automatically. Any pending comments have been approved." + success: "Account allowed. All of their comments from now on will be approved automatically. No action was performed over existing Comments." error: "There was an error while allowing the account. We received a report and will be acting on it soon." block: - success: "Account blocked. All of their comments will be rejected automatically. Any pending comments have been rejected. If you want to report it to their instance, please use the Report button." + success: "Account blocked. All of their comments from now on will be rejected automatically. No action was performed over existing Comments. If you want to report it to their instance, please use the Report button." error: "There was an error while blocking the account. We received a report and will be acting on it soon." report: success: "Account reported." error: "There was an error while reporting the account. We received a report and will be acting on it soon." instance_moderations: action_on_several: - success: "Several instances have changed moderation state. You can find them using the filters on the Instances section." + success: "Several instances have changed moderation state. You can find them using the filters on the Instances section. No action was performed over existing Accounts and Comments." error: "There was an error while changing moderation state. We received a report and will be acting on it soon." pause: - success: "Instance paused. All of their comments and accounts will need to be moderated individually." + success: "Instance paused. All of their comments and accounts from now on will need to be moderated individually. No action was performed over existing Accounts and Comments." error: "There was an error while pausing the instance. We received a report and will be acting on it soon." allow: - success: "Instance allowed. All of their comments and accounts will be approved automatically. Any pending comments and accounts have been also approved." + success: "Instance allowed. All of their comments and accounts from now on will be approved automatically. No action was performed over existing Accounts and Comments." error: "There was an error while allowing the instance. We received a report and will be acting on it soon." block: - success: "Instance blocked. All of their comments and accounts will be rejected automatically. Any pending comments and accounts have been also rejected." + success: "Instance blocked. All of their comments and accounts from now on will be rejected automatically. No action was performed over existing Accounts and Comments." error: "There was an error while blocking the instance. We received a report and will be acting on it soon." fediblock_states: action_on_several: - success: "Blocklists have been enabled, you can find their instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section." + success: "Blocklists have been enabled, you can find their instances by filtering by Blocked. You can approve them individually on the Accounts section. No action was performed over existing Accounts and Comments." error: "There was an error while enabling or disabling blocklists. We received a report and will be acting on it soon." - custom_blocklist_success: "Custom blocklist has been added, you can find the instances by filtering by Blocked. Any pending account from these instances has also been blocked. You can approve them individually on the Accounts section." + custom_blocklist_success: "Custom blocklist has been added, you can find the instances by filtering by Blocked. No action was performed over existing Accounts and Comments." custom_blocklist_error: "There was an error while adding a custom blocklist. We received a report and will be acting on it soon." moderation_queue: everything: 'Select all' diff --git a/config/locales/es.yml b/config/locales/es.yml index 3cc6c49a..a7b8d452 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -131,38 +131,38 @@ es: error: "No se puedo reportar el comentario. Hemos recibido el reporte y lo estaremos verificando." actor_moderations: action_on_several: - success: "Se ha modificado el estado de moderación de varias cuentas. Podés encontrarlas usando los filtros en la sección Cuentas." + success: "Se ha modificado el estado de moderación de varias cuentas. Podés encontrarlas usando los filtros en la sección Cuentas. No se modificaron comentarios pre-existentes." error: "Hubo un error al modificar el estado de moderación de varias cuentas. Hemos recibido el reporte y lo estaremos verificando." pause: - success: "Cuenta pausada. Todos los comentarios que haga necesitan ser aprobados manualmente en la sección Comentarios." + success: "Cuenta pausada. Todos los comentarios que haga necesitan ser aprobados manualmente en la sección Comentarios. No se modificaron comentarios pre-existentes." error: "No se pudo pausar la cuenta. Hemos recibido el reporte y lo estaremos verificando." allow: - success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente. Todos los comentarios pendientes de moderación fueron aprobados." + success: "Cuenta permitida. Todos los comentarios que haga serán aprobados inmediatamente. No se modificaron comentarios pre-existentes." error: "No se pudo permitir la cuenta. Hemos recibido el reporte y lo estaremos verificando." block: - success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Todos los comentarios pendientes de moderación fueron rechazados. Si querés reportarla a su instancia, podés usar el botón Reportar." + success: "Cuenta bloqueada. Todos los comentarios que haga serán rechazados inmediatamente. Si querés reportarla a su instancia, podés usar el botón Reportar. No se modificaron comentarios pre-existentes." error: "No se pudo bloquear la cuenta. Hemos recibido el reporte y lo estaremos verificando." report: success: "Cuenta reportada a su instancia." error: "No se pudo reportar la cuenta. Hemos recibido el reporte y lo estaremos verificando." instance_moderations: action_on_several: - success: "Se ha modificado el estado de moderación de varias instancias. Podés encontrarlas usando los filtros en la sección Instancias." + success: "Se ha modificado el estado de moderación de varias instancias. Podés encontrarlas usando los filtros en la sección Instancias. No se modificaron cuentas y comentarios pre-existentes." error: "Hubo un error al modificar el estado de moderación de varias instancias. Hemos recibido el reporte y lo estaremos verificando." pause: - success: "Instancia pausada. Todos los comentarios y cuentas de esta instancia necesitan ser aprobados manualmente. No se ha modificado el estado de moderación de cuentas y comentarios pre-existentes." + success: "Instancia pausada. A partir de ahora, todos los comentarios y cuentas de esta instancia necesitan ser aprobados manualmente. No se ha modificado el estado de moderación de cuentas ni comentarios pre-existentes." error: "No se pudo pausar la instancia. Hemos recibido el reporte y lo estaremos verificando." allow: - success: "Instancia permitida. Todos los comentarios y cuentas pendientes de moderación fueron aprobados y los próximos serán aprobados inmediatamente." + success: "Instancia permitida. A partir de ahora, todos los comentarios y cuentas pendientes serán aprobados inmediatamente. No se modificaron cuentas ni comentarios pre-existentes." error: "No se pudo permitir la instancia. Hemos recibido el reporte y lo estaremos verificando." block: - success: "Instancia bloqueada. Todos los comentarios y cuentas serán rechazados inmediatamente. Todos los comentarios y cuentas pendientes de moderación fueron rechazados." + success: "Instancia bloqueada. A partir de ahora, todos los comentarios y cuentas serán rechazados inmediatamente. No se modificaron cuentas ni comentarios pre-existentes." error: "No se pudo bloquear la instancia. Hemos recibido el reporte y lo estaremos verificando." fediblock_states: action_on_several: - success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés activarlas individualmente en la sección Cuentas." + success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Podés activarlas individualmente en la sección Cuentas. No se modificaron cuentas ni comentarios pre-existentes." error: "Hubo un error al activar o desactivar listas de bloqueo, ya recibimos el reporte y lo estaremos verificando." - custom_blocklist_success: "Se agregaron las instancias personalizadas a la lista de bloqueo, podés encontrarlas filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés aprobarlas individualmente en la sección Cuentas." + custom_blocklist_success: "Se agregaron las instancias personalizadas a la lista de bloqueo, podés encontrarlas filtrando por Bloqueadas. Podés aprobarlas individualmente en la sección Cuentas. No se modificaron cuentas ni comentarios pre-existentes." custom_blocklist_error: "Hubo un error al agregar instancias personalizadas a la lista de bloqueo, ya recibimos el reporte y lo estaremos verificando." moderation_queue: everything: 'Seleccionar todo' From 882ab1679c0467929e5cfc18bbf75402143b4752 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 15:52:33 -0300 Subject: [PATCH 639/814] fix: a veces el objeto no existe (?) closes #15554 --- app/models/activity_pub.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index a6b1401b..53bb3de0 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -56,6 +56,8 @@ class ActivityPub < ApplicationRecord transitions to: :removed before do + next if object.blank? + object.update(content: {}) unless object.content.empty? end end From 56c583e0f43efab5d4ea37a725fb8cb2801c30b8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:11:40 -0300 Subject: [PATCH 640/814] fix: serializar correctamente closes #15363 --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 5 +++-- app/jobs/activity_pub/fetch_job.rb | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index c40857e0..bdf359d2 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -125,8 +125,9 @@ module Api o.save! # XXX: el objeto necesita ser guardado antes de poder - # procesarlo - ::ActivityPub::FetchJob.perform_later(site: site, object: o) unless object_embedded? + # procesarlo. No usamos GlobalID porque el tipo de objeto + # cambia y produce un error de deserialización. + ::ActivityPub::FetchJob.perform_later(site: site, object_id: o.id) unless object_embedded? end end diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index e3fef993..6a4d163b 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -11,8 +11,11 @@ class ActivityPub class FetchJob < ApplicationJob self.priority = 50 - def perform(site:, object:) + def perform(site:, object_id:) ActivityPub::Object.transaction do + object = ::ActivityPub::Object.find(object_id) + + return if object.blank? return if object.activity_pubs.where(aasm_state: 'removed').count.positive? response = site.social_inbox.dereferencer.get(uri: object.uri) From ad9f9c3d618eb7cba2834e350a03dd7c7804bd0c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:27:33 -0300 Subject: [PATCH 641/814] fixup! fix: serializar correctamente --- app/models/que_job.rb | 5 +++++ db/migrate/20240313192134_fix_fetch_jobs.rb | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 app/models/que_job.rb create mode 100644 db/migrate/20240313192134_fix_fetch_jobs.rb diff --git a/app/models/que_job.rb b/app/models/que_job.rb new file mode 100644 index 00000000..0bfffc92 --- /dev/null +++ b/app/models/que_job.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require 'que/active_record/model' + +class QueJob < Que::ActiveRecord::Model; end diff --git a/db/migrate/20240313192134_fix_fetch_jobs.rb b/db/migrate/20240313192134_fix_fetch_jobs.rb new file mode 100644 index 00000000..3b9d4ad8 --- /dev/null +++ b/db/migrate/20240313192134_fix_fetch_jobs.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class FixFetchJobs < ActiveRecord::Migration[6.1] + def up + QueJob.where("last_error_message like '%ActiveJob::DeserializationError%'").find_each do |job| + job.error_count = 0 + job.run_at = time.now + + job.args.first['arguments'].first['_aj_ruby2_keywords'].delete('object') + job.args.first['arguments'].first['_aj_ruby2_keywords'] << 'object_id' + + object = job.args.first['arguments'].first.delete('object')['_aj_globalid'] + job.args.first['arguments'].first['object_id'] = object.split('/').last + + job.save + end + end + + def down; end +end From 630f6b31fc93021d5e3ee93447f3b980f3dd1510 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:28:59 -0300 Subject: [PATCH 642/814] fixup! fixup! fix: serializar correctamente --- db/migrate/20240313192134_fix_fetch_jobs.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240313192134_fix_fetch_jobs.rb b/db/migrate/20240313192134_fix_fetch_jobs.rb index 3b9d4ad8..54ffa7e6 100644 --- a/db/migrate/20240313192134_fix_fetch_jobs.rb +++ b/db/migrate/20240313192134_fix_fetch_jobs.rb @@ -4,7 +4,7 @@ class FixFetchJobs < ActiveRecord::Migration[6.1] def up QueJob.where("last_error_message like '%ActiveJob::DeserializationError%'").find_each do |job| job.error_count = 0 - job.run_at = time.now + job.run_at = Time.now job.args.first['arguments'].first['_aj_ruby2_keywords'].delete('object') job.args.first['arguments'].first['_aj_ruby2_keywords'] << 'object_id' From 4dd75eedad7b8023a05bfb848697f71a8e575831 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:39:58 -0300 Subject: [PATCH 643/814] =?UTF-8?q?fix:=20prevenir=20doble=20renderizaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15564 --- app/controllers/application_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 05fa98e9..cfa37067 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -77,6 +77,11 @@ class ApplicationController < ActionController::Base # Muestra una página 404 def page_not_found + self.response_body = nil + @_response_body = nil + + headers.delete('Location') + render 'application/page_not_found', status: :not_found end From 061fc81cb058221cd237baa6646b8f67d0fc1843 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:44:24 -0300 Subject: [PATCH 644/814] =?UTF-8?q?fixup!=20fix:=20prevenir=20doble=20rend?= =?UTF-8?q?erizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cfa37067..b15157f7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -76,6 +76,8 @@ class ApplicationController < ActionController::Base end # Muestra una página 404 + # + # @see {https://github.com/rails/rails/issues/25106} def page_not_found self.response_body = nil @_response_body = nil From 93140f37aa6ca1436cb42523ad1cd4865abba097 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:46:04 -0300 Subject: [PATCH 645/814] fix: cachear correctamente closes #15567 --- app/views/moderation_queue/_comments.haml | 6 +++--- app/views/moderation_queue/_instances.haml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 72240287..a4bfd9bd 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -12,6 +12,6 @@ - if moderation_queue.count.zero? %h4= t('moderation_queue.nothing') - moderation_queue.each do |activity_pub| - -# cache [activity_pub, activity_pub.object, activity_pub.actor] do - %hr - = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id + - cache [activity_pub, activity_pub.object, activity_pub.actor] do + %hr + = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index 9a5349ba..dec7e6f3 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -14,7 +14,7 @@ %h4= t('moderation_queue.nothing') - instance_moderations.each do |instance_moderation| - - cache [instance_moderation.aasm_state, instance_moderation.instance] do + - cache [instance_moderation, instance_moderation.instance] do %hr = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form: form_id From ac38343a219953038540e3ecea460516f998fb54 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:55:34 -0300 Subject: [PATCH 646/814] =?UTF-8?q?fix:=20facilitar=20la=20b=C3=BAsqueda?= =?UTF-8?q?=20de=20instancias=20en=20la=20lista=20#15563?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_instance.haml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index 7cf3b085..e5121dad 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,12 +1,17 @@ - usuaries = instance.content.dig('usage', 'users', 'active_month') - usuaries ||= instance.content.dig('stats', 'user_count') +- title = sanitize(instance.content['title']) +- title ||= instance.hostname .row.no-gutters.pt-2 .col-1 = render 'components/checkbox', id: instance.hostname, form: form, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 - %a{ href: instance.uri }= sanitize(instance.content['title']) || instance.hostname + %a{ href: instance.uri } + = title + - if title.present? + = " (#{instance.hostname})".html_safe .content = sanitize instance.content['description'] - if usuaries.present? From 79e6ce787274aa928b2c726f94342597a74812bc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 16:56:51 -0300 Subject: [PATCH 647/814] =?UTF-8?q?fixup!=20fix:=20facilitar=20la=20b?= =?UTF-8?q?=C3=BAsqueda=20de=20instancias=20en=20la=20lista=20#15563?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/moderation_queue/_instance.haml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index e5121dad..d66acd83 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -1,15 +1,13 @@ - usuaries = instance.content.dig('usage', 'users', 'active_month') - usuaries ||= instance.content.dig('stats', 'user_count') -- title = sanitize(instance.content['title']) -- title ||= instance.hostname +- title = sanitize(instance.content['title']) .row.no-gutters.pt-2 .col-1 = render 'components/checkbox', id: instance.hostname, form: form, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 %h4 - %a{ href: instance.uri } - = title + %a{ href: instance.uri }= title || instance.hostname - if title.present? = " (#{instance.hostname})".html_safe .content From 97653d98b6d3f0d2d667eb153f5e70e8b9b272d1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 17:02:01 -0300 Subject: [PATCH 648/814] fix: prevenir deadlocks closes #15555 closes #15556 closes #15557 closes #15558 closes #15559 closes #15560 --- app/models/activity_pub/activity/delete.rb | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 6a23a8b5..1fbe5691 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -13,22 +13,24 @@ class ActivityPub # lo haría la Social Inbox por nosotres. # @see {https://docs.joinmastodon.org/spec/security/#ld} def update_activity_pub_state! - ActivityPub.transaction do - object = ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object'])) + ActiveRecord::Base.connection_pool.with_connection do + ActivityPub.transaction do + object = ActivityPub::Object.find_by(uri: ActivityPub.uri_from_object(content['object'])) - if object.present? - object.activity_pubs.find_each do |activity_pub| - activity_pub.remove! if activity_pub.may_remove? + if object.present? + object.activity_pubs.find_each do |activity_pub| + activity_pub.remove! if activity_pub.may_remove? + end + + # Encontrar todas las acciones de moderación de le actore + # eliminade y moverlas a eliminar. + if object.actor_type? && object.actor.present? + ActorModeration.where(actor_id: object.actor.id).remove_all! + end end - # Encontrar todas las acciones de moderación de le actore - # eliminade y moverlas a eliminar. - if object.actor_type? && object.actor.present? - ActorModeration.where(actor_id: object.actor.id).remove_all! - end + activity_pub.remove! if activity_pub.may_remove? end - - activity_pub.remove! if activity_pub.may_remove? end end end From 1b9e039fda52d2b1ee5779823b2ec7cb00873980 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 17:42:36 -0300 Subject: [PATCH 649/814] =?UTF-8?q?fix:=20errores=20de=20decompresi=C3=B3n?= =?UTF-8?q?=20#15332?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 2 +- Gemfile.lock | 2 +- ...04105_brs_decompressor_corrupted_source_error.rb | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb diff --git a/Gemfile b/Gemfile index f4125f65..e314c172 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'devise-i18n' gem 'devise_invitable' gem 'redis-client' gem 'hiredis-client' -gem 'distributed-press-api-client', '~> 0.4.0rc3' +gem 'distributed-press-api-client', '~> 0.4.1' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 7b19ba75..751fc73e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,7 +166,7 @@ GEM devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.4.0) + distributed-press-api-client (0.4.1) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema diff --git a/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb b/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb new file mode 100644 index 00000000..a0c29311 --- /dev/null +++ b/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Comprueba que se pueden volver a correr las tareas que dieron error de +# decompresión +class BrsDecompressorCorruptedSourceError < ActiveRecord::Migration[6.1] + def up + raise unless HTTParty.get("https://mas.to/api/v2/instance", headers: { "Accept-Encoding": "br;q=1.0,gzip;q=1.0,deflate;q=0.6,identity;q=0.3" }).ok? + + QueJob.where("last_error_message like '%BRS::DecompressorCorruptedSourceError%'").update_all(error_count: 0, run_at: Time.now) + end + + def down; end +end From b6ed91df11eb238d55f6aedb95e164512046bfa7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Mar 2024 17:52:45 -0300 Subject: [PATCH 650/814] fix: siempre relacionar la instancia con el sitio #15563 --- app/controllers/api/v1/webhooks/social_inbox_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index bdf359d2..7b17c47b 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -162,11 +162,11 @@ module Api unless a.instance a.instance = ::ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) - site.instance_moderations.find_or_create_by(instance: a.instance) - ::ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) end + site.instance_moderations.find_or_create_by(instance: a.instance) + a.save! site.actor_moderations.find_or_create_by(actor: a) From 9d71c5fa0cb4de8725a1b6728cbb71a0edc087e2 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 11:20:04 -0300 Subject: [PATCH 651/814] fix: eliminar actores cuando no se pudo completar el objeto #15576 --- app/models/activity_pub/activity/delete.rb | 4 ++-- ...emove_actor_moderations_for_generic_objects.rb | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240314141536_remove_actor_moderations_for_generic_objects.rb diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 1fbe5691..997b96ca 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -24,8 +24,8 @@ class ActivityPub # Encontrar todas las acciones de moderación de le actore # eliminade y moverlas a eliminar. - if object.actor_type? && object.actor.present? - ActorModeration.where(actor_id: object.actor.id).remove_all! + if (actor = ActivityPub::Actor.find_by(uri: o.uri)).present? + ActorModeration.where(actor_id: actor.id).remove_all! end end diff --git a/db/migrate/20240314141536_remove_actor_moderations_for_generic_objects.rb b/db/migrate/20240314141536_remove_actor_moderations_for_generic_objects.rb new file mode 100644 index 00000000..a60e755a --- /dev/null +++ b/db/migrate/20240314141536_remove_actor_moderations_for_generic_objects.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Elimina actores que no pudieron ser eliminades porque su perfil ya no +# existe. +class RemoveActorModerationsForGenericObjects < ActiveRecord::Migration[6.1] + def up + object_ids = ActivityPub.removed.where(object_type: 'ActivityPub::Object::Generic').distinct.pluck(:object_id) + uris = ActivityPub::Object.where(id: object_ids).pluck(:uri) + actor_ids = ActivityPub::Actor.where(uri: uris).ids + + ActorModeration.where(actor_id: actor_ids).remove_all! + end + + def down; end +end From 30f2f0a4423e623ba79ef385d3cba23e17a12edf Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 11:45:33 -0300 Subject: [PATCH 652/814] fix: gestionar las excepciones desde un solo lugar #15564 --- app/controllers/application_controller.rb | 16 --------------- app/controllers/concerns/exception_handler.rb | 20 ++++++++++++++++++- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b15157f7..bd7b8c4b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,10 +12,6 @@ class ApplicationController < ActionController::Base before_action :notify_unconfirmed_email, unless: :devise_controller? around_action :set_locale - rescue_from Pundit::NilPolicyError, with: :page_not_found - rescue_from ActionController::RoutingError, with: :page_not_found - rescue_from ActionController::ParameterMissing, with: :page_not_found - before_action do Rack::MiniProfiler.authorize_request if current_usuarie&.email&.ends_with?('@' + ENV.fetch('SUTTY', 'sutty.nl')) end @@ -75,18 +71,6 @@ class ApplicationController < ActionController::Base I18n.with_locale(current_locale, &action) end - # Muestra una página 404 - # - # @see {https://github.com/rails/rails/issues/25106} - def page_not_found - self.response_body = nil - @_response_body = nil - - headers.delete('Location') - - render 'application/page_not_found', status: :not_found - end - # Necesario para poder acceder a Blazer. Solo les usuaries de este # sitio pueden acceder al panel. def require_usuarie diff --git a/app/controllers/concerns/exception_handler.rb b/app/controllers/concerns/exception_handler.rb index 8c4f54c8..7c1cd540 100644 --- a/app/controllers/concerns/exception_handler.rb +++ b/app/controllers/concerns/exception_handler.rb @@ -12,13 +12,31 @@ module ExceptionHandler rescue_from PageNotFound, with: :page_not_found rescue_from ActionController::RoutingError, with: :page_not_found rescue_from Pundit::NilPolicyError, with: :page_not_found + rescue_from Pundit::NilPolicyError, with: :page_not_found + rescue_from ActionController::RoutingError, with: :page_not_found + rescue_from ActionController::ParameterMissing, with: :page_not_found end def site_not_found + reset_response! + + flash[:error] = I18n.t('errors.site_not_found') + redirect_to sites_path end def page_not_found - send_file Rails.root.join('public', '404.html') + reset_response! + + render 'application/page_not_found', status: :not_found + end + + private + + def reset_response! + self.response_body = nil + @_response_body = nil + + headers.delete('Location') end end diff --git a/config/locales/en.yml b/config/locales/en.yml index d745e2d5..d67fe7d3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -390,6 +390,7 @@ en: lang: not_available: "This language is not yet available, would you help us by translating Sutty into it?" errors: + site_not_found: "Site not found, or maybe you don't have access to it." argument_error: 'Argument `%{argument}` must be an instance of %{class}' unknown_locale: 'Unknown %{locale} locale' posts: diff --git a/config/locales/es.yml b/config/locales/es.yml index a7b8d452..192b3298 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -389,6 +389,7 @@ es: lang: not_available: "Este idioma todavía no está disponible, ¿nos ayudas a agregarlo y mantenerlo?" errors: + site_not_found: "No encontramos ese sitio o quizás no tengas acceso." argument_error: 'El argumento `%{argument}` debe ser una instancia de %{class}' unknown_locale: 'El idioma %{locale} es desconocido' posts: From cfe70e3a899f136a2a2e004c5ae7ef91681fd4a2 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 11:57:06 -0300 Subject: [PATCH 653/814] fix: no cachear formularios #15570 --- app/views/moderation_queue/_account.haml | 14 ++++----- app/views/moderation_queue/_accounts.haml | 5 ++-- app/views/moderation_queue/_comment.haml | 35 +++++++++++----------- app/views/moderation_queue/_comments.haml | 5 ++-- app/views/moderation_queue/_instance.haml | 21 ++++++------- app/views/moderation_queue/_instances.haml | 5 ++-- 6 files changed, 42 insertions(+), 43 deletions(-) diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index 6b4c67fc..498d78f4 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -5,12 +5,12 @@ .col-1 = render 'components/checkbox', id: actor_moderation.id, form: form, name: 'actor_moderation[]', value: actor_moderation.id, data: { target: 'select-all.input' } .col-11 - %h4 - = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) - .mb-3 - = sanitize profile['summary'] + - cache [actor_moderation, profile] do + %h4 + = link_to text_plain(profile['name']), site_actor_moderation_path(id: actor_moderation) + .mb-3 + = sanitize profile['summary'] -# Botones de Moderación - - cache actor_moderation do - .d-flex.pb-4 - = render 'components/profiles_btn_box', actor_moderation: actor_moderation + .d-flex.pb-4 + = render 'components/profiles_btn_box', actor_moderation: actor_moderation diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index abc02b31..d8d76f0d 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -12,6 +12,5 @@ - if actor_moderations.count.zero? %h4= t('moderation_queue.nothing') - actor_moderations.find_each do |actor_moderation| - - cache [actor_moderation, actor_moderation.actor] do - %hr - = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form: form_id + %hr + = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form: form_id diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 90579a9c..c6f6fd5c 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -13,22 +13,23 @@ .col-1 = render 'components/checkbox', id: activity_pub.id, name: 'activity_pub[]', value: activity_pub.id, data: { target: 'select-all.input' }, form: form .col-11 - .d-flex.flex-row.align-items-center.justify-content-between - %h4.mb-0 - %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] - %small - = render 'layouts/time', time: text_plain(comment['published']) - - if in_reply_to.present? - %dl - %dt.d-inline - %small= t('.reply_to') - %dd.d-inline - %small - %a{ href: in_reply_to }= in_reply_to - .content - - if summary.present? - = render 'layouts/details', summary: summary, summary_class: 'h5' do + - cache [activity_pub, comment] do + .d-flex.flex-row.align-items-center.justify-content-between + %h4.mb-0 + %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] + %small + = render 'layouts/time', time: text_plain(comment['published']) + - if in_reply_to.present? + %dl + %dt.d-inline + %small= t('.reply_to') + %dd.d-inline + %small + %a{ href: in_reply_to }= in_reply_to + .content + - if summary.present? + = render 'layouts/details', summary: summary, summary_class: 'h5' do + = sanitize comment['content'] + - else = sanitize comment['content'] - - else - = sanitize comment['content'] = render 'components/comments_btn_box', activity_pub: activity_pub diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index a4bfd9bd..68671f9e 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -12,6 +12,5 @@ - if moderation_queue.count.zero? %h4= t('moderation_queue.nothing') - moderation_queue.each do |activity_pub| - - cache [activity_pub, activity_pub.object, activity_pub.actor] do - %hr - = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id + %hr + = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id diff --git a/app/views/moderation_queue/_instance.haml b/app/views/moderation_queue/_instance.haml index d66acd83..c380089a 100644 --- a/app/views/moderation_queue/_instance.haml +++ b/app/views/moderation_queue/_instance.haml @@ -6,16 +6,17 @@ .col-1 = render 'components/checkbox', id: instance.hostname, form: form, name: 'instance_moderation[]', value: instance_moderation.id, data: { target: 'select-all.input' } .col-11 - %h4 - %a{ href: instance.uri }= title || instance.hostname - - if title.present? - = " (#{instance.hostname})".html_safe - .content - = sanitize instance.content['description'] - - if usuaries.present? - %dl - %dt.d-inline= t('.users') - %dd.d-inline= text_plain usuaries.to_s + - cache [instance_moderation, instance] do + %h4 + %a{ href: instance.uri }= title || instance.hostname + - if title.present? + = " (#{instance.hostname})".html_safe + .content + = sanitize instance.content['description'] + - if usuaries.present? + %dl + %dt.d-inline= t('.users') + %dd.d-inline= text_plain usuaries.to_s -# Botones moderación .d-flex.pb-4 diff --git a/app/views/moderation_queue/_instances.haml b/app/views/moderation_queue/_instances.haml index dec7e6f3..6bc08b95 100644 --- a/app/views/moderation_queue/_instances.haml +++ b/app/views/moderation_queue/_instances.haml @@ -14,9 +14,8 @@ %h4= t('moderation_queue.nothing') - instance_moderations.each do |instance_moderation| - - cache [instance_moderation, instance_moderation.instance] do - %hr - = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form: form_id + %hr + = render 'moderation_queue/instance', instance_moderation: instance_moderation, instance: instance_moderation.instance, form: form_id %hr %div From c57794b54e92cb6eed8dd42944b320aa9c513d7f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 11:58:13 -0300 Subject: [PATCH 654/814] fixup! fix: eliminar actores cuando no se pudo completar el objeto #15576 --- app/models/activity_pub/activity/delete.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity/delete.rb b/app/models/activity_pub/activity/delete.rb index 997b96ca..640c7ce9 100644 --- a/app/models/activity_pub/activity/delete.rb +++ b/app/models/activity_pub/activity/delete.rb @@ -24,7 +24,7 @@ class ActivityPub # Encontrar todas las acciones de moderación de le actore # eliminade y moverlas a eliminar. - if (actor = ActivityPub::Actor.find_by(uri: o.uri)).present? + if (actor = ActivityPub::Actor.find_by(uri: object.uri)).present? ActorModeration.where(actor_id: actor.id).remove_all! end end From 1de9d1a12695d97679c64b403c32256a4abf6ec1 Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 14 Mar 2024 12:02:37 -0300 Subject: [PATCH 655/814] =?UTF-8?q?feat:=20breadcrumbs=20en=20Actividades?= =?UTF-8?q?=20de=20Moderaci=C3=B3n=20#15578?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/moderation_queue_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index eec0c70f..ca99d95b 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -2,6 +2,11 @@ # Cola de moderación de ActivityPub class ModerationQueueController < ApplicationController + before_action :authenticate_usuarie! + + breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path + breadcrumb 'sites.index', :sites_path, match: :exact + # Cola de moderación viendo todo el sitio def index dummy_data From 33cfdd199513221c8b4bf30f64fbe0b454c4be7a Mon Sep 17 00:00:00 2001 From: maki Date: Thu, 14 Mar 2024 12:21:50 -0300 Subject: [PATCH 656/814] fix: breadcrumbs en todas las acciones --- app/controllers/moderation_queue_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index ca99d95b..cbf2cec5 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -6,7 +6,7 @@ class ModerationQueueController < ApplicationController breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path breadcrumb 'sites.index', :sites_path, match: :exact - + # Cola de moderación viendo todo el sitio def index dummy_data @@ -15,11 +15,13 @@ class ModerationQueueController < ApplicationController # Perfil remoto de usuarie def remote_profile dummy_data + breadcrumb post.title.value, '' end # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances dummy_data + breadcrumb post.title.value, '' end end From 5bf26a7fb2f7b7fb73efd11f110ea8ec6bb44383 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 12:27:59 -0300 Subject: [PATCH 657/814] fix: arreglar las relaciones entre actividades y objetos --- app/jobs/activity_pub/fetch_job.rb | 4 ++++ ...0240314153017_fix_object_type_on_activity_pubs.rb | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 6a4d163b..d7003c11 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -24,9 +24,13 @@ class ActivityPub return unless response.ok? return if response.miss? && object.content.present? + current_type = object.type content = FastJsonparser.parse(response.body) object.update(content: content, type: ActivityPub::Object.type_from(content).name) + + # Arreglar las relaciones con actividades también + ActivityPub.where(object_id: object.id).update_all(object_type: object.type) unless current_type == object.type end end end diff --git a/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb b/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb new file mode 100644 index 00000000..81149ad4 --- /dev/null +++ b/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Arregla la relación rota entre ActivityPub y Objects +class FixObjectTypeOnActivityPubs < ActiveRecord::Migration[6.1] + def up + ActivityPub::Object.where.not(type: 'ActivityPub::Object::Generic').find_each do |object| + ActivityPub.where(object_id: object.id).update_all(type: object.type, updated_at: Time.now) + end + end + + def down; end +end From 5969662a7d679836c1936a178ee097641fdfeec6 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 15:42:44 -0300 Subject: [PATCH 658/814] fixup! fix: arreglar las relaciones entre actividades y objetos --- db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb b/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb index 81149ad4..d5475f71 100644 --- a/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb +++ b/db/migrate/20240314153017_fix_object_type_on_activity_pubs.rb @@ -4,7 +4,7 @@ class FixObjectTypeOnActivityPubs < ActiveRecord::Migration[6.1] def up ActivityPub::Object.where.not(type: 'ActivityPub::Object::Generic').find_each do |object| - ActivityPub.where(object_id: object.id).update_all(type: object.type, updated_at: Time.now) + ActivityPub.where(object_id: object.id).update_all(object_type: object.type, updated_at: Time.now) end end From 96d70100e46ad536d5e017b215f559a7a0615380 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 17:07:58 -0300 Subject: [PATCH 659/814] feat: auto-aprobar solicitudes de seguimiento --- app/models/activity_pub/activity/follow.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity/follow.rb b/app/models/activity_pub/activity/follow.rb index e383490a..393eb3b4 100644 --- a/app/models/activity_pub/activity/follow.rb +++ b/app/models/activity_pub/activity/follow.rb @@ -4,8 +4,17 @@ # # Una actividad de seguimiento se refiere siempre a une actore (el # sitio) y proviene de otre actore. +# +# Por ahora las solicitudes de seguimiento se auto-aprueban. class ActivityPub class Activity - class Follow < ActivityPub::Activity; end + class Follow < ActivityPub::Activity + # Auto-aprobar la solicitud de seguimiento + def update_activity_pub_state! + activity_pub.approve! + rescue Exception => e + ExceptionNotifier.notify_exception(e, { site: activity_pub.site.name, activity: self.id }) + end + end end end From d92953e5fa3acb9bc1e065dcd5f25d31b326e781 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 17:08:38 -0300 Subject: [PATCH 660/814] fix: poder volver a pausa si se edita el comentario --- app/models/activity_pub.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 53bb3de0..7453a8c3 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -49,6 +49,12 @@ class ActivityPub < ApplicationRecord # Le actore eliminó el objeto state :removed + # Se puede volver a pausa en caso de actualización remota, para + # revisar los cambios. + event :pause do + transitions to: :paused + end + # Recibir una acción de eliminación, eliminar el contenido de la # base de datos. Esto elimina el contenido para todos los sitios # porque estamos respetando lo que pidió le actore. From 1e44fba4b3b70a033bf7026d12ea2da9c3329be8 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 17:08:55 -0300 Subject: [PATCH 661/814] fix: aprobar la actividad, no el objeto --- app/models/activity_pub.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 7453a8c3..bd6c816e 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -101,11 +101,14 @@ class ActivityPub < ApplicationRecord # Definir eventos en masa include AasmEventsConcern + # Lo que tenemos que aprobar o rechazar es la última actividad + # disponible, que según el scope por defecto, va a ser la primera de + # la lista. def reject_remotely! - raise unless site.social_inbox.inbox.reject(id: object.uri).ok? + raise unless site.social_inbox.inbox.reject(id: activities.first.uri).ok? end def allow_remotely! - raise unless site.social_inbox.inbox.accept(id: object.uri).ok? + raise unless site.social_inbox.inbox.accept(id: activities.first.uri).ok? end end From f4379b45c27583c757dd9b1683e705fdbaf382d8 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 14 Mar 2024 17:58:41 -0300 Subject: [PATCH 662/814] feat: announce y like --- app/models/activity_pub/activity/announce.rb | 8 ++++++++ app/models/activity_pub/activity/like.rb | 8 ++++++++ db/migrate/20240314205923_fix_activity_type.rb | 12 ++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 app/models/activity_pub/activity/announce.rb create mode 100644 app/models/activity_pub/activity/like.rb create mode 100644 db/migrate/20240314205923_fix_activity_type.rb diff --git a/app/models/activity_pub/activity/announce.rb b/app/models/activity_pub/activity/announce.rb new file mode 100644 index 00000000..8ca58906 --- /dev/null +++ b/app/models/activity_pub/activity/announce.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class ActivityPub + class Activity + # Boost + class Announce < ActivityPub::Activity; end + end +end diff --git a/app/models/activity_pub/activity/like.rb b/app/models/activity_pub/activity/like.rb new file mode 100644 index 00000000..531cc32c --- /dev/null +++ b/app/models/activity_pub/activity/like.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class ActivityPub + class Activity + # Like + class Like < ActivityPub::Activity; end + end +end diff --git a/db/migrate/20240314205923_fix_activity_type.rb b/db/migrate/20240314205923_fix_activity_type.rb new file mode 100644 index 00000000..042de8eb --- /dev/null +++ b/db/migrate/20240314205923_fix_activity_type.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Soportar nuevos tipos +class FixActivityType < ActiveRecord::Migration[6.1] + def up + %w[Like Announce].each do |type| + ActivityPub::Activity.where(Arel.sql("content->>'type' = '#{type}'")).update_all(type: "ActivityPub::Activity::#{type}", updated_at: Time.now) + end + end + + def down; end +end From 8473927ceed6ea7dc8d01c30856499fcd200e998 Mon Sep 17 00:00:00 2001 From: maki Date: Fri, 15 Mar 2024 12:23:04 -0300 Subject: [PATCH 663/814] fix: breadcrumbs --- app/controllers/moderation_queue_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index cbf2cec5..5e501329 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -10,18 +10,17 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index dummy_data + breadcrumb I18n.t('moderation_queue.index.title'), '' end # Perfil remoto de usuarie def remote_profile dummy_data - breadcrumb post.title.value, '' end # todon.nl está usando /api/v2/instance # mauve.moe usa /api/v1/instance def instances dummy_data - breadcrumb post.title.value, '' end end From 30d32a6e3be6e3fd27ddfe81fa3eeda935f29211 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 13:43:00 -0300 Subject: [PATCH 664/814] feat: confirmar el reporte remoto #15604 --- app/views/components/_btn_base.haml | 2 +- app/views/components/_comments_btn_box.haml | 5 ++++- app/views/components/_instances_btn_box.haml | 12 ++++++++---- app/views/components/_profiles_btn_box.haml | 7 ++++--- config/locales/en.yml | 6 ++++-- config/locales/es.yml | 4 +++- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index 4d8566d3..f9227482 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -5,5 +5,5 @@ - local_assigns[:class] = "btn #{local_assigns[:class]}" -# @todo path es obligatorio -= button_to local_assigns[:path], **local_assigns do += button_to local_assigns[:path], **local_assigns.compact do = text diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 285eefdb..1993e5cb 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,8 +1,11 @@ -# Componente Botonera de Comentarios +- local_data = { report: { confirm: t('.confirm_report') } } + .d-flex.flex-row - ActivityPub.events.each do |event| = render 'components/btn_base', text: t(".text_#{event}"), path: public_send(:"site_activity_pub_#{event}_path", activity_pub_id: activity_pub), - disabled: !activity_pub.public_send(:"may_#{event}?") + disabled: !activity_pub.public_send(:"may_#{event}?"), + data: local_data[event] diff --git a/app/views/components/_instances_btn_box.haml b/app/views/components/_instances_btn_box.haml index 74cad4a4..15c6c040 100644 --- a/app/views/components/_instances_btn_box.haml +++ b/app/views/components/_instances_btn_box.haml @@ -1,6 +1,10 @@ -# Componente botonera de moderación de Instancias -- btn_class = 'btn btn-secondary' -= render 'components/btn_base', path: site_instance_moderation_pause_path(instance_moderation_id: instance_moderation), text: t('.text_check'), class: btn_class, disabled: !instance_moderation.may_pause? -= render 'components/btn_base', path: site_instance_moderation_allow_path(instance_moderation_id: instance_moderation), text: t('.text_allow'), class: btn_class, disabled: !instance_moderation.may_allow? -= render 'components/btn_base', path: site_instance_moderation_block_path(instance_moderation_id: instance_moderation), text: t('.text_deny'), class: btn_class, disabled: !instance_moderation.may_block? +- local_data = {} +- InstanceModeration.events.each do |event| + = render 'components/btn_base', + path: public_send(:"site_instance_moderation_#{event}_path", instance_moderation_id: instance_moderation), + text: t(".text_#{event}"), + class: 'btn btn-secondary', + disabled: !instance_moderation.public_send(:"may_#{event}?"), + data: local_data[event] diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 073c142e..488373b9 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,9 +1,10 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) .d-flex.flex-row - - btn_class = 'btn-secondary' + - local_data = { report: { confirm: t('.confirm_report') } } - ActorModeration.events.each do |actor_event| = render 'components/btn_base', text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), - class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?") + class: 'btn-secondary', + disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), + data: local_data[actor_event] diff --git a/config/locales/en.yml b/config/locales/en.yml index d67fe7d3..6f76fe57 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,15 +106,17 @@ en: text_reject: Reject text_reply: Reply text_report: Report + confirm_report: "Send report to the remote instance?" instances_btn_box: - text_check: Check case by case + text_pause: Check case by case text_allow: Allow everything - text_deny: Block instance + text_block: Block instance profiles_btn_box: text_pause: Always check text_allow: Always approve text_block: Block text_report: Report + confirm_report: "Send report to the remote instance?" remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." activity_pubs: diff --git a/config/locales/es.yml b/config/locales/es.yml index 192b3298..7f71781c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -105,8 +105,9 @@ es: text_approve: Aceptar text_reject: Rechazar text_report: Reportar + confirm_report: "¿Enviar el reporte a la instancia remota?" instances_btn_box: - text_check: Moderar caso por caso + text_pause: Moderar caso por caso text_allow: Permitir todo text_deny: Bloquear instancia profiles_btn_box: @@ -114,6 +115,7 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar + confirm_report: "¿Enviar el reporte a la instancia remota?" remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." activity_pubs: From 86ba17328db4823140766bdf0dc82d7b5f6f01ed Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 14:01:00 -0300 Subject: [PATCH 665/814] feat: migas de pan para actores --- app/controllers/actor_moderations_controller.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index bc4a059b..769be1fa 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -5,6 +5,11 @@ class ActorModerationsController < ApplicationController include ModerationConcern include ModerationFiltersConcern + before_action :authenticate_usuarie! + + breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path + breadcrumb 'sites.index', :sites_path, match: :exact + ActorModeration.events.each do |actor_event| define_method(actor_event) do authorize actor_moderation @@ -26,9 +31,13 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show + breadcrumb I18n.t('moderation_queue.index.title'), site_moderation_queue_path(site) + @remote_profile = actor_moderation.actor.content @moderation_queue = rubanok_process(site.activity_pubs.where(actor_id: actor_moderation.actor_id), with: ActivityPubProcessor) + + breadcrumb @remote_profile['name'], '' end def action_on_several From 0fe043dd791dd30342f2f2197da4882e0aacfffb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 14:14:27 -0300 Subject: [PATCH 666/814] fix: informar errores de json closes #15593 --- app/jobs/activity_pub/fetch_job.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index d7003c11..129908d3 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -31,6 +31,8 @@ class ActivityPub # Arreglar las relaciones con actividades también ActivityPub.where(object_id: object.id).update_all(object_type: object.type) unless current_type == object.type + rescue FastJsonparser::ParseError => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, body: response.body }) end end end From 5db750675217ab5226a5955745e0736d805695eb Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 14:26:12 -0300 Subject: [PATCH 667/814] =?UTF-8?q?fix:=20no=20se=20puede=20pausar=20todav?= =?UTF-8?q?=C3=ADa=20#15600?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index bd6c816e..840cf3b1 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -8,8 +8,8 @@ # # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} class ActivityPub < ApplicationRecord - IGNORED_EVENTS = %i[remove] - IGNORED_STATES = %i[removed] + IGNORED_EVENTS = %i[pause remove].freeze + IGNORED_STATES = %i[removed].freeze include AASM From 6412fc108efd2279582f88997f79fc19790f727d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 14:31:54 -0300 Subject: [PATCH 668/814] =?UTF-8?q?fix:=20no=20se=20puede=20rechazar=20lue?= =?UTF-8?q?go=20de=20aprobar=20todav=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 840cf3b1..73006d1d 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -81,7 +81,7 @@ class ActivityPub < ApplicationRecord # La actividad fue rechazada event :reject do - transitions from: %i[paused approved], to: :rejected + transitions from: %i[paused], to: :rejected before do reject_remotely! From fcbff3e1c13a5b8500fd898e9bd2753ca070c853 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 16:52:42 -0300 Subject: [PATCH 669/814] fix: enviar el reporte firmado por el sitio #15605 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pasaban dos cosas: 1. para firmar correctamente, el cliente necesita recibir el path completo por su parámetro `endpoint` 2. la petición tiene que ser hecha por le misme actore que hace el reporte, como estábamos firmando con el sitio, mastodon creía que era un relay y esperaba que se envíen firmas ld --- .env | 2 ++ app/jobs/activity_pub/remote_flag_job.rb | 9 +++++++-- app/models/activity_pub/remote_flag.rb | 16 ++++++++++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.env b/.env index 480175f8..fe503b11 100644 --- a/.env +++ b/.env @@ -39,3 +39,5 @@ GITLAB_PROJECT= GITLAB_TOKEN= PGVER=15 PGPID=/run/postgresql.pid +PANEL_ACTOR_MENTION=@sutty@sutty.nl +PANEL_ACTOR_SITE_ID=1 diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index f5650d53..20833bd4 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -15,10 +15,15 @@ class ActivityPub def perform(remote_flag:) return if remote_flag.may_queue? + inbox = remote_flag.actor&.content&.[]('inbox') + + raise 'Inbox is missing for actor' if inbox.blank? + remote_flag.queue! - client = remote_flag.site.social_inbox.client_for(remote_flag.actor&.content['inbox']) - response = client.post(endpoint: '', body: remote_flag.content) + uri = URI.parse(inbox) + client = remote_flag.main_site.social_inbox.client_for(uri.origin) + response = client.post(endpoint: uri.path, body: remote_flag.content) raise 'No se pudo enviar el reporte' unless response.ok? diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index 70f09dcc..c3cc0fb0 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -2,8 +2,8 @@ class ActivityPub class RemoteFlag < ApplicationRecord - IGNORED_EVENTS = [] - IGNORED_STATES = [] + IGNORED_EVENTS = [].freeze + IGNORED_STATES = [].freeze include AASM @@ -42,10 +42,18 @@ class ActivityPub '@context' => 'https://www.w3.org/ns/activitystreams', 'id' => Rails.application.routes.url_helpers.v1_activity_pub_remote_flag_url(self, host: site.social_inbox_hostname), 'type' => 'Flag', - 'actor' => ENV.fetch('PANEL_ACTOR_ID') { "https://#{ENV['SUTTY']}/about.jsonld" }, + 'actor' => main_site.social_inbox.actor_id, 'content' => message.to_s, - 'object' => [ actor.uri ] + objects.pluck(:uri) + 'object' => [actor.uri] + objects.pluck(:uri) } end + + # Este es el sitio principal que actúa como origen del reporte. + # Tiene que tener la Social Inbox habilitada al mismo tiempo. + # + # @return [Site] + def main_site + @main_site ||= Site.find(ENV.fetch('PANEL_ACTOR_SITE_ID') { 1 }) + end end end From 364b63a075b141a01e429d30b0030e149d86d67f Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 17:57:21 -0300 Subject: [PATCH 670/814] =?UTF-8?q?fix:=20notificar=20correctamente=20la?= =?UTF-8?q?=20excepci=C3=B3n=20#15608?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/activity/follow.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub/activity/follow.rb b/app/models/activity_pub/activity/follow.rb index 393eb3b4..37dc9d26 100644 --- a/app/models/activity_pub/activity/follow.rb +++ b/app/models/activity_pub/activity/follow.rb @@ -13,7 +13,7 @@ class ActivityPub def update_activity_pub_state! activity_pub.approve! rescue Exception => e - ExceptionNotifier.notify_exception(e, { site: activity_pub.site.name, activity: self.id }) + ExceptionNotifier.notify_exception(e, data: { site: activity_pub.site.name, activity: self.id }) end end end From 00270b7829266120fa2e3beaa87ffde118cae38a Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 18:05:05 -0300 Subject: [PATCH 671/814] fix: no mostrar likes #15596 --- app/models/activity_pub.rb | 16 ++++++++++++++-- app/processors/activity_pub_processor.rb | 9 ++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 73006d1d..3671000c 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -6,6 +6,12 @@ # una actividad, puede estar destinada a varies actores dentro de Sutty, # con lo que generamos una cola para cada une. # +# +# @todo Ya que une actore puede hacer varias actividades sobre el mismo +# objeto, lo correcto sería que la actividad a moderar sea una sola en +# lugar de una lista acumulativa. Es decir cada ActivityPub representa +# el estado del conjunto (Actor, Object, Activity) +# # @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions} class ActivityPub < ApplicationRecord IGNORED_EVENTS = %i[pause remove].freeze @@ -105,10 +111,16 @@ class ActivityPub < ApplicationRecord # disponible, que según el scope por defecto, va a ser la primera de # la lista. def reject_remotely! - raise unless site.social_inbox.inbox.reject(id: activities.first.uri).ok? + fail! unless site.social_inbox.inbox.reject(id: activities.first.uri).ok? end def allow_remotely! - raise unless site.social_inbox.inbox.accept(id: activities.first.uri).ok? + with_failure_handling(activity: activities.first.uri) do + fail! unless site.social_inbox.inbox.accept(id: activities.first.uri).ok? + end + end + + def fail_message + activities.first&.uri || 'Activity missing' end end diff --git a/app/processors/activity_pub_processor.rb b/app/processors/activity_pub_processor.rb index 52cdb6d3..501b73a5 100644 --- a/app/processors/activity_pub_processor.rb +++ b/app/processors/activity_pub_processor.rb @@ -6,7 +6,14 @@ class ActivityPubProcessor < Rubanok::Processor # # Por ahora solo queremos moderar comentarios. prepare do - raw.where(object_type: %w[ActivityPub::Object::Note ActivityPub::Object::Article]).order(updated_at: :desc) + raw + .joins(:activities) + .where( + activity_pub_activities: { + type: %w[ActivityPub::Activity::Create ActivityPub::Activity::Update] + }, + object_type: %w[ActivityPub::Object::Note ActivityPub::Object::Article] + ).order(updated_at: :desc) end map :activity_pub_state, activate_always: true do |activity_pub_state: 'paused'| From 26e865661638e9af84acaf6dd0f331433603e89c Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Mar 2024 18:08:34 -0300 Subject: [PATCH 672/814] fixup! fix: no mostrar likes #15596 --- app/models/activity_pub.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 3671000c..cae054cd 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -111,16 +111,10 @@ class ActivityPub < ApplicationRecord # disponible, que según el scope por defecto, va a ser la primera de # la lista. def reject_remotely! - fail! unless site.social_inbox.inbox.reject(id: activities.first.uri).ok? + raise unless site.social_inbox.inbox.reject(id: activities.first.uri).ok? end def allow_remotely! - with_failure_handling(activity: activities.first.uri) do - fail! unless site.social_inbox.inbox.accept(id: activities.first.uri).ok? - end - end - - def fail_message - activities.first&.uri || 'Activity missing' + raise unless site.social_inbox.inbox.accept(id: activities.first.uri).ok? end end From 3a0f1584c1d292997bc850e8bbd7810810bfc6b6 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 11:32:16 -0300 Subject: [PATCH 673/814] fix: poder volver al sitio --- app/controllers/actor_moderations_controller.rb | 1 + app/controllers/moderation_queue_controller.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 769be1fa..6316a4cf 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -31,6 +31,7 @@ class ActorModerationsController < ApplicationController # Ver el perfil remoto def show + breadcrumb site.title, site_posts_path(site) breadcrumb I18n.t('moderation_queue.index.title'), site_moderation_queue_path(site) @remote_profile = actor_moderation.actor.content diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 3536dc95..4bd61e38 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -11,6 +11,7 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index + breadcrumb site.title, site_posts_path(site) breadcrumb I18n.t('moderation_queue.index.title'), '' # @todo cambiar el estado por query From adfd6c78bbb583ea0dc8936358152d771771fded Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 14:15:32 -0300 Subject: [PATCH 674/814] feat: procesar actividades en segundo plano MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit en lugar de hacerlo en el momento, respondemos lo más rápido posible a la social inbox, ya que un webhook fallado genera un error en la social inbox, que genera un error en la instancia remota, que va a volver a intentar muchas veces. ahora recibimos una vez, si falla el procesamiento, lo detenemos para que alguien humane actúe al respecto. --- .../v1/webhooks/social_inbox_controller.rb | 171 ++---------------- app/jobs/activity_pub/process_job.rb | 154 ++++++++++++++++ 2 files changed, 167 insertions(+), 158 deletions(-) create mode 100644 app/jobs/activity_pub/process_job.rb diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 7b17c47b..6ac91a51 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -5,196 +5,51 @@ module Api module Webhooks # Recibe webhooks de la Social Inbox # - # @todo Mover todo a un Job que obtenga el objeto remoto antes de - # instanciar el objeto localmente en lugar de arreglarlo después y - # poder responder lo más rápido posible el webhook. # @see {https://www.w3.org/TR/activitypub/} class SocialInboxController < BaseController include Api::V1::Webhooks::Concerns::WebhookConcern + # Validar que el token sea correcto + before_action :usuarie + # Cuando una actividad ingresa en la cola de moderación, la # recibimos por acá # - # Vamos a recibir Create, Update, Delete, Follow, Undo y obtener - # el objeto dentro de cada una para guardar un estado asociado - # al sitio. + # Vamos a recibir Create, Update, Delete, Follow, Undo, + # Announce, Like y obtener el objeto dentro de cada una para + # guardar un estado asociado al sitio. # # El objeto del estado puede ser un objeto o une actore, # dependiendo de la actividad. def moderationqueued - # Devuelve un error si el token no es válido - usuarie.present? + process! :paused - ::ActivityPub.transaction do - - # Crea todos los registros necesarios y actualiza el estado - actor.present? - instance.present? - object.present? - activity_pub.present? - - activity.update_activity_pub_state! - end - rescue ActiveRecord::RecordInvalid => e - ExceptionNotifier.notify_exception(e, - data: { site: site.name, usuarie: usuarie.email, - activity: original_activity }) - ensure head :accepted end # Cuando la Social Inbox acepta una actividad, la recibimos # igual y la guardamos por si cambiamos de idea. - # - # @todo DRY def onapproved - ::ActivityPub.transaction do - actor.present? - instance.present? - object.present? - activity.present? - activity_pub.update(aasm_state: 'approved') - activity.update_activity_pub_state! - end + process! :approved head :accepted end # Cuando la Social Inbox rechaza una actividad, la recibimos # igual y la guardamos por si cambiamos de idea. - # - # @todo DRY def onrejected - ::ActivityPub.transaction do - actor.present? - instance.present? - object.present? - activity.present? - activity_pub.update(aasm_state: 'rejected') - end + process! :rejected head :accepted end private - # Si el objeto ya viene incorporado en la actividad o lo tenemos - # que traer remotamente. + # Envía la actividad para procesamiento por separado. # - # @return [Bool] - def object_embedded? - @object_embedded ||= original_activity[:object].is_a?(Hash) - end - - # Encuentra la URI del objeto o falla si no la encuentra. - # - # @return [String] - def object_uri - @object_uri ||= ::ActivityPub.uri_from_object(original_activity[:object]) - ensure - raise ActiveRecord::RecordNotFound, 'object id missing' if @object_uri.blank? - end - - # Atajo a la instancia - # - # @return [ActivityPub::Instance] - def instance - actor.instance - end - - # Genera un objeto a partir de la actividad. Si el objeto ya - # existe, actualiza su contenido. Si el objeto no viene - # incorporado, obtenemos el contenido más tarde. - # - # @return [ActivityPub::Object] - def object - @object ||= ::ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| - # XXX: Si el objeto es una actividad, esto siempre va a ser - # Generic - o.type ||= 'ActivityPub::Object::Generic' - - if object_embedded? - o.content = original_object - begin - type = original_object[:type].presence - o.type = "ActivityPub::Object::#{type}".constantize if type - rescue NameError - end - end - - o.save! - - # XXX: el objeto necesita ser guardado antes de poder - # procesarlo. No usamos GlobalID porque el tipo de objeto - # cambia y produce un error de deserialización. - ::ActivityPub::FetchJob.perform_later(site: site, object_id: o.id) unless object_embedded? - end - end - - # Genera el seguimiento del estado del objeto con respecto al - # sitio. - # - # @return [ActivityPub] - def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, actor: actor, instance: instance, object_id: object.id, object_type: object.type) - end - - # Crea la actividad y la vincula con el estado - # - # @return [ActivityPub::Activity] - def activity - @activity ||= - ::ActivityPub::Activity - .type_from(original_activity) - .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| - a.content = original_activity.dup - a.content[:object] = object.uri - a.save! - end - end - - # Actor, si no hay instancia, la crea en el momento, junto con - # su estado de moderación. - # - # @return [Actor] - def actor - @actor ||= ::ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| - unless a.instance - a.instance = ::ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) - - ::ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) - end - - site.instance_moderations.find_or_create_by(instance: a.instance) - - a.save! - - site.actor_moderations.find_or_create_by(actor: a) - - ::ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) - end - end - - # Descubre la actividad recibida, generando un error si la - # actividad no está dirigida a nosotres. - # - # @todo Validar formato - # @return [Hash] - def original_activity - @original_activity ||= FastJsonparser.parse(request.raw_post).tap do |activity| - raise '@context missing' unless activity[:@context].presence - raise 'id missing' unless activity[:id].presence - raise 'object missing' unless activity[:object].presence - rescue RuntimeError => e - raise ActiveRecord::RecordNotFound, e.message - end - end - - # @return [Hash,String] - def original_object - @original_object ||= original_activity[:object].dup.tap do |o| - o[:@context] = original_activity[:@context].dup - end + # @param initial_state [Symbol] + def process!(initial_state) + ::ActivityPub::ProcessJob.perform_later(site: site, body: request.raw_post, initial_state: initial_state) end end end diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb new file mode 100644 index 00000000..6554b44d --- /dev/null +++ b/app/jobs/activity_pub/process_job.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +class ActivityPub + # Procesar las actividades a medida que llegan + class ProcessJob < ApplicationJob + attr_reader :body + + # Procesa la actividad en segundo plano + # + # @param :body [String] + # @param :initial_state [Symbol,String] + def perform(site:, body:, initial_state: :paused) + @body = body + @site = site + + ActiveRecord::Base.connection_pool.with_connection do + ::ActivityPub.transaction do + # Crea todos los registros necesarios y actualiza el estado + actor.present? + instance.present? + object.present? + activity_pub.present? + activity_pub.update(aasm_state: initial_state) + + activity.update_activity_pub_state! + end + end + # Al generar una excepción, en lugar de seguir intentando, enviamos + # el reporte. + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, activity: original_activity }) + end + + private + + # Si el objeto ya viene incorporado en la actividad o lo tenemos + # que traer remotamente. + # + # @return [Bool] + def object_embedded? + @object_embedded ||= original_activity[:object].is_a?(Hash) + end + + # Encuentra la URI del objeto o falla si no la encuentra. + # + # @return [String] + def object_uri + @object_uri ||= ::ActivityPub.uri_from_object(original_activity[:object]) + ensure + raise ActiveRecord::RecordNotFound, 'object id missing' if @object_uri.blank? + end + + # Atajo a la instancia + # + # @return [ActivityPub::Instance] + def instance + actor.instance + end + + # Genera un objeto a partir de la actividad. Si el objeto ya + # existe, actualiza su contenido. Si el objeto no viene + # incorporado, obtenemos el contenido más tarde. + # + # @return [ActivityPub::Object] + def object + @object ||= ::ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| + # XXX: Si el objeto es una actividad, esto siempre va a ser + # Generic + o.type ||= 'ActivityPub::Object::Generic' + + if object_embedded? + o.content = original_object + begin + type = original_object[:type].presence + o.type = "ActivityPub::Object::#{type}".constantize if type + rescue NameError + end + end + + o.save! + + # XXX: el objeto necesita ser guardado antes de poder + # procesarlo. No usamos GlobalID porque el tipo de objeto + # cambia y produce un error de deserialización. + ::ActivityPub::FetchJob.perform_later(site: site, object_id: o.id) unless object_embedded? + end + end + + # Genera el seguimiento del estado del objeto con respecto al + # sitio. + # + # @return [ActivityPub] + def activity_pub + @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, actor: actor, instance: instance, + object_id: object.id, object_type: object.type) + end + + # Crea la actividad y la vincula con el estado + # + # @return [ActivityPub::Activity] + def activity + @activity ||= + ::ActivityPub::Activity + .type_from(original_activity) + .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| + a.content = original_activity.dup + a.content[:object] = object.uri + a.save! + end + end + + # Actor, si no hay instancia, la crea en el momento, junto con + # su estado de moderación. + # + # @return [Actor] + def actor + @actor ||= ::ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| + unless a.instance + a.instance = ::ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + + ::ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) + end + + site.instance_moderations.find_or_create_by(instance: a.instance) + + a.save! + + site.actor_moderations.find_or_create_by(actor: a) + + ::ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) + end + end + + # @return [Hash,String] + def original_object + @original_object ||= original_activity[:object].dup.tap do |o| + o[:@context] = original_activity[:@context].dup + end + end + + # Descubre la actividad recibida, generando un error si la + # actividad no está dirigida a nosotres. + # + # @todo Validar formato con Dry::Schema + # @return [Hash] + def original_activity + @original_activity ||= FastJsonparser.parse(body).tap do |activity| + raise '@context missing' unless activity[:@context].present? + raise 'id missing' unless activity[:id].present? + raise 'object missing' unless activity[:object].present? + end + end + end +end From 1dae918a179ecca3f18edfe286e16d58b7546398 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 14:17:28 -0300 Subject: [PATCH 675/814] feat: poder gestionar la cola de tareas --- Gemfile | 1 + Gemfile.lock | 18 +++++++++++++++++- config/initializers/que_web.rb | 5 +++++ config/routes.rb | 3 +++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 config/initializers/que_web.rb diff --git a/Gemfile b/Gemfile index e314c172..e5e6ed10 100644 --- a/Gemfile +++ b/Gemfile @@ -83,6 +83,7 @@ gem 'rubanok' gem 'after_commit_everywhere', '~> 1.0' gem 'aasm' +gem 'que-web' # database gem 'hairtrigger' diff --git a/Gemfile.lock b/Gemfile.lock index 751fc73e..7087e013 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,6 +97,7 @@ GEM ast (2.4.2) autoprefixer-rails (10.4.13.0) execjs (~> 2) + base64 (0.2.0) bcrypt (3.1.20-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl) benchmark-ips (2.12.0) @@ -370,6 +371,8 @@ GEM i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) net-imap (0.4.9) date net-protocol @@ -409,12 +412,18 @@ GEM pundit (2.3.1) activesupport (>= 3.0.0) que (2.2.1) + que-web (0.10.0) + que (>= 1) + sinatra racc (1.7.3-x86_64-linux-musl) rack (2.2.8) rack-cors (2.0.1) rack (>= 2.0.0) rack-mini-profiler (3.1.0) rack (>= 1.2.0) + rack-protection (3.2.0) + base64 (>= 0.1.0) + rack (~> 2.2, >= 2.2.4) rack-proxy (0.7.7) rack rack-test (2.1.0) @@ -513,6 +522,7 @@ GEM ruby-statistics (3.0.2) ruby-vips (2.2.0) ffi (~> 1.12) + ruby2_keywords (0.0.5) ruby2ruby (2.5.0) ruby_parser (~> 3.1) sexp_processor (~> 4.6) @@ -539,6 +549,11 @@ GEM sexp_processor (4.17.0) simpleidn (0.2.1) unf (~> 0.1.4) + sinatra (3.2.0) + mustermann (~> 3.0) + rack (~> 2.2, >= 2.2.4) + rack-protection (= 3.2.0) + tilt (~> 2.0) sourcemap (0.1.1) spring (4.1.1) spring-watcher-listen (2.1.0) @@ -626,7 +641,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.4.0) + distributed-press-api-client (~> 0.4.1) dotenv-rails down ed25519 @@ -670,6 +685,7 @@ DEPENDENCIES puma pundit que + que-web rack-cors rack-mini-profiler rails (~> 6.1.0) diff --git a/config/initializers/que_web.rb b/config/initializers/que_web.rb new file mode 100644 index 00000000..192256db --- /dev/null +++ b/config/initializers/que_web.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Que::Web.use(Rack::Auth::Basic) do |user, password| + [user, password] == [ENV['HTTP_BASIC_USER'], ENV['HTTP_BASIC_PASSWORD']] +end diff --git a/config/routes.rb b/config/routes.rb index 054b7f4d..4d43d66a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,9 @@ Rails.application.routes.draw do devise_for :usuaries get '/.well-known/change-password', to: redirect('/usuaries/edit') + require 'que/web' + mount Que::Web => '/que' + root 'application#index' constraints(Constraints::ApiSubdomain.new) do From 8f91b748ff6ed9536d13093efd72e228bb66de3f Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 14:27:28 -0300 Subject: [PATCH 676/814] =?UTF-8?q?fix:=20mostrar=20botones=20de=20acci?= =?UTF-8?q?=C3=B3n=20en=20masa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_btn_base.haml | 4 ++-- app/views/components/_dropdown_button.haml | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index f9227482..faa5c85f 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -3,7 +3,7 @@ - local_assigns[:method] ||= 'patch' - local_assigns[:class] ||= 'btn-secondary' - local_assigns[:class] = "btn #{local_assigns[:class]}" +- local_assigns.delete(:text) --# @todo path es obligatorio -= button_to local_assigns[:path], **local_assigns.compact do += button_to(path, **local_assigns.compact) do = text diff --git a/app/views/components/_dropdown_button.haml b/app/views/components/_dropdown_button.haml index c0f12754..d6de6c8e 100644 --- a/app/views/components/_dropdown_button.haml +++ b/app/views/components/_dropdown_button.haml @@ -1,4 +1,6 @@ -# @param name [String] @param value [String] -%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value, **local_assigns.compact } + @param text [String] +- local_assigns.delete(:text) +%button.dropdown-item{type: 'submit', data: { target: 'dropdown.item' }, name: name, value: value, **local_assigns.compact }= text From 8ff5626e9968407d5b12f5e9a77fd3cb739ff77d Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 15:12:55 -0300 Subject: [PATCH 677/814] feat: no permitir entrar al evento si falla la request --- app/controllers/activity_pubs_controller.rb | 14 +++--- .../actor_moderations_controller.rb | 13 ++--- .../instance_moderations_controller.rb | 13 ++--- app/models/activity_pub.rb | 21 ++++---- app/models/actor_moderation.rb | 32 +++++-------- app/models/concerns/aasm_events_concern.rb | 29 ++++------- app/models/fediblock_state.rb | 48 ++++++++++--------- app/models/instance_moderation.rb | 28 ++++------- 8 files changed, 88 insertions(+), 110 deletions(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index edece8f8..225311c2 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -9,14 +9,16 @@ class ActivityPubsController < ApplicationController authorize activity_pub activity_pub.update(remote_flag_params(activity_pub)) if event == :report - activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?") - flash[:success] = I18n.t("activity_pubs.#{event}.success") - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + message = + if activity_pub.public_send(:"may_#{event}?") && activity_pub.public_send(:"#{event}!") + :success + else + :error + end + + flash[message] = I18n.t("activity_pubs.#{event}.#{message}") - flash[:error] = I18n.t("activity_pubs.#{event}.error") - ensure redirect_to_moderation_queue! end end diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 6316a4cf..cb7a63a9 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -17,14 +17,15 @@ class ActorModerationsController < ApplicationController # Crea una RemoteFlag si se envían los parámetros adecuados actor_moderation.update(remote_flag_params(actor_moderation)) if actor_event == :report - actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") + message = + if actor_moderation.public_send(:"may_#{actor_event}?") && actor_moderation.public_send(:"#{actor_event}!") + :success + else + :error + end - flash[:success] = I18n.t("actor_moderations.#{actor_event}.success") - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + flash[message] = I18n.t("actor_moderations.#{actor_event}.#{message}") - flash[:error] = I18n.t("actor_moderations.#{actor_event}.error") - ensure redirect_to_moderation_queue! end end diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 06f5cfc1..13d7f428 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -8,14 +8,15 @@ class InstanceModerationsController < ApplicationController define_method(event) do authorize instance_moderation - instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?") + message = + if instance_moderation.public_send(:"may_#{event}?") && instance_moderation.public_send(:"#{event}!") + :success + else + :error + end - flash[:success] = I18n.t("instance_moderations.#{event}.success") - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h }) + flash[message] = I18n.t("instance_moderations.#{event}.#{message}") - flash[:error] = I18n.t("instance_moderations.#{event}.error") - ensure redirect_to_moderation_queue! end end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index cae054cd..8142ecfb 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -47,14 +47,19 @@ class ActivityPub < ApplicationRecord # Todavía no hay una decisión sobre el objeto state :paused, initial: true # Le usuarie aprobó el objeto - state :approved + state :approved, before_enter: :allow_remotely! # Le usuarie rechazó el objeto - state :rejected + state :rejected, before_enter: :reject_remotely! # Le usuarie reportó el objeto state :reported # Le actore eliminó el objeto state :removed + # Gestionar todos los errores + error_on_all_events do |e| + ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: self.id, activity: activities.first.uri }) + end + # Se puede volver a pausa en caso de actualización remota, para # revisar los cambios. event :pause do @@ -67,7 +72,7 @@ class ActivityPub < ApplicationRecord event :remove do transitions to: :removed - before do + after do next if object.blank? object.update(content: {}) unless object.content.empty? @@ -79,26 +84,18 @@ class ActivityPub < ApplicationRecord # webhook a modo de confirmación. event :approve do transitions from: %i[paused], to: :approved - - before do - allow_remotely! - end end # La actividad fue rechazada event :reject do transitions from: %i[paused], to: :rejected - - before do - reject_remotely! - end end # Solo podemos reportarla luego de rechazarla event :report do transitions from: :rejected, to: :reported - before do + after do ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 3b183a4f..c566b844 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -2,8 +2,8 @@ # Mantiene la relación entre Site y Actor class ActorModeration < ApplicationRecord - IGNORED_EVENTS = %i[remove] - IGNORED_STATES = %i[removed] + IGNORED_EVENTS = %i[remove].freeze + IGNORED_STATES = %i[removed].freeze include AASM @@ -14,38 +14,30 @@ class ActorModeration < ApplicationRecord accepts_nested_attributes_for :remote_flag aasm do - state :paused, initial: true - state :allowed - state :blocked + state :paused, initial: true, before_enter: :pause_remotely! + state :allowed, before_enter: :allow_remotely! + state :blocked, before_enter: :block_remotely! state :reported state :removed + error_on_all_events do |e| + ExceptionNotifier.notify_exception(e, data: { site: site.name, actor: actor.uri, actor_moderation: id }) + end + event :pause do transitions from: %i[allowed blocked reported], to: :paused - - before do - pause_remotely! - end end # Al permitir una cuenta no se permiten todos los comentarios # pendientes de moderación que ya hizo. event :allow do transitions from: %i[paused blocked reported], to: :allowed - - before do - allow_remotely! - end end # Al bloquear una cuenta no se bloquean todos los comentarios # pendientes de moderación que hizo. event :block do transitions from: %i[paused allowed], to: :blocked - - before do - block_remotely! - end end # Al reportar, necesitamos asociar una RemoteFlag para poder @@ -53,7 +45,7 @@ class ActorModeration < ApplicationRecord event :report do transitions from: %i[blocked], to: :reported - before do + after do ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end @@ -63,8 +55,8 @@ class ActorModeration < ApplicationRecord event :remove do transitions to: :removed - before do - site.activity_pubs.where(actor_id: self.actor_id).remove_all! + after do + site.activity_pubs.where(actor_id: actor_id).remove_all! end end end diff --git a/app/models/concerns/aasm_events_concern.rb b/app/models/concerns/aasm_events_concern.rb index 4de5f748..788e9e1a 100644 --- a/app/models/concerns/aasm_events_concern.rb +++ b/app/models/concerns/aasm_events_concern.rb @@ -16,7 +16,7 @@ module AasmEventsConcern # # @return [Array] def self.transitionable_events(current_state) - self.events.select do |event| + events.select do |event| aasm.events.find { |x| x.name == event }.transitions_from_state? current_state end end @@ -32,19 +32,15 @@ module AasmEventsConcern # scope actual. # # @return [Bool] Si hubo al menos un error, devuelve false. - self.aasm.events.map(&:name).each do |event| + aasm.events.map(&:name).each do |event| define_singleton_method(:"#{event}_all!") do - success = true + successes = [] - self.find_each do |object| - object.public_send(:"#{event}!") if object.public_send(:"may_#{event}?") - rescue Exception => e - success = false - - notify_exception! e, object + find_each do |object| + successes << (object.public_send(:"may_#{event}?") && object.public_send(:"#{event}!")) end - success + successes.all? end # Ejecuta la transición del evento en la base de datos sin @@ -53,20 +49,13 @@ module AasmEventsConcern # # @return [Integer] Registros modificados define_singleton_method(:"#{event}_all_without_callbacks!") do - aasm_event = self.aasm.events.find { |e| e.name == event } + aasm_event = aasm.events.find { |e| e.name == event } to_state = aasm_event.transitions.map(&:to).first from_states = aasm_event.transitions.map(&:from) - self.unscope(where: :aasm_state).where(aasm_state: from_states).update_all(aasm_state: to_state, updated_at: Time.now) + unscope(where: :aasm_state).where(aasm_state: from_states).update_all(aasm_state: to_state, + updated_at: Time.now) end end - - # Envía notificación de errores - # - # @param exception [Exception] - # @param record [ApplicationRecord] - def self.notify_exception!(exception, record) - ExceptionNotifier.notify_exception(exception, data: { record_type: record.class.name, record_id: record.id }) - end end end diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 9dde1db3..a6faa14f 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -20,20 +20,15 @@ class FediblockState < ApplicationRecord # Aunque queramos las listas habilitadas por defecto, tenemos que # habilitarlas luego de crearlas para poder generar la lista de # bloqueo en la Social Inbox. - state :disabled, initial: true - state :enabled + state :disabled, initial: true, before_enter: :disable_remotely_and_pause_instances! + state :enabled, before_enter: :enable_remotely_and_block_instances! + + error_on_all_events do |e| + ExceptionNotifier.notify_exception(e, data: { site: site.name, fediblock: id }) + end event :enable do transitions from: :disabled, to: :enabled - - before do - # Bloquear todos las instancias de este Fediblock - enable_remotely! list_names(fediblock.hostnames) - - # Luego esta tarea crea las que falten e ignora las que ya se - # bloquearon. - ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames, perform_remotely: false) - end end # Al deshabilitar, las listas pasan a modo pausa, a menos que estén @@ -44,22 +39,31 @@ class FediblockState < ApplicationRecord # de list_names event :disable do transitions from: :enabled, to: :disabled - - before do - # Deshabilitar todas las instancias que no estén habilitadas por - # otros fediblocks - disable_remotely! list_names(unique_hostnames) - - # Pausar todas las moderaciones de las instancias que no estén - # bloqueadas por otros fediblocks. - instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids - site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks! - end end end private + def enable_remotely_and_block_instances! + # Bloquear todos las instancias de este Fediblock + enable_remotely! list_names(fediblock.hostnames) + + # Luego esta tarea crea las que falten e ignora las que ya se + # bloquearon. + ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames, perform_remotely: false) + end + + def disable_remotely_and_pause_instances! + # Deshabilitar todas las instancias que no estén habilitadas por + # otros fediblocks + disable_remotely! list_names(unique_hostnames) + + # Pausar todas las moderaciones de las instancias que no estén + # bloqueadas por otros fediblocks. + instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids + site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks! + end + # Devuelve los hostnames únicos a esta instancia. # # @return [Array] diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 9cb6ffdc..7c76262e 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -2,8 +2,8 @@ # Mantiene el registro de relaciones entre sitios e instancias class InstanceModeration < ApplicationRecord - IGNORED_EVENTS = [] - IGNORED_STATES = [] + IGNORED_EVENTS = [].freeze + IGNORED_STATES = [].freeze include AASM @@ -11,38 +11,30 @@ class InstanceModeration < ApplicationRecord belongs_to :instance, class_name: 'ActivityPub::Instance' aasm do - state :paused, initial: true - state :allowed - state :blocked + state :paused, initial: true, before_enter: :pause_remotely! + state :allowed, before_enter: :allow_remotely! + state :blocked, before_enter: :block_remotely! + + error_on_all_events do |e| + ExceptionNotifier.notify_exception(e, data: { site: site.name, instance: instance.hostname, instance_moderation: id }) + end # Al volver la instancia a pausa no cambiamos el estado de # moderación de actores pre-existente. event :pause do transitions from: %i[allowed blocked], to: :paused - - before do - pause_remotely! - end end # Al permitir, solo bloqueamos la instancia, sin modificar el estado # de les actores y comentarios retroactivamente. event :allow do transitions from: %i[paused blocked], to: :allowed - - before do - allow_remotely! - end end # Al bloquear, solo bloqueamos la instancia, sin modificar el estado # de les actores y comentarios retroactivamente. event :block do transitions from: %i[paused allowed], to: :blocked - - before do - block_remotely! - end end end @@ -51,7 +43,7 @@ class InstanceModeration < ApplicationRecord # @return [Array] def actor_ids - ActivityPub::Actor.where(instance_id: self.instance_id).ids + ActivityPub::Actor.where(instance_id: instance_id).ids end # Elimina la instancia de todas las listas From f6b2895b58a0f9bf2cd8cc19e52f112afe01e9d4 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 16:36:00 -0300 Subject: [PATCH 678/814] =?UTF-8?q?fix:=20aprobar=20las=20peticiones=20de?= =?UTF-8?q?=20seguimiento=20autom=C3=A1ticamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/activity_pub/activity/follow.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/models/activity_pub/activity/follow.rb b/app/models/activity_pub/activity/follow.rb index 37dc9d26..b4c34d7a 100644 --- a/app/models/activity_pub/activity/follow.rb +++ b/app/models/activity_pub/activity/follow.rb @@ -11,9 +11,7 @@ class ActivityPub class Follow < ActivityPub::Activity # Auto-aprobar la solicitud de seguimiento def update_activity_pub_state! - activity_pub.approve! - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: activity_pub.site.name, activity: self.id }) + activity_pub.approve! if activity_pub.may_approve? end end end From b972e53e4821c563eaebabb5e1cbcb899ea063f8 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 17:53:29 -0300 Subject: [PATCH 679/814] =?UTF-8?q?feat:=20guardar=20la=20menci=C3=B3n=20d?= =?UTF-8?q?e=20le=20autore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 7 +++++- app/models/activity_pub/actor.rb | 9 ++++--- .../20240316203721_add_mention_to_actors.rb | 24 +++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20240316203721_add_mention_to_actors.rb diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 129908d3..e9220bfc 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -29,8 +29,13 @@ class ActivityPub object.update(content: content, type: ActivityPub::Object.type_from(content).name) + return if current_type == object.type + + object = ::ActivityPub::Object.find(object_id) + object.actor.save if object.actor_type? + # Arreglar las relaciones con actividades también - ActivityPub.where(object_id: object.id).update_all(object_type: object.type) unless current_type == object.type + ActivityPub.where(object_id: object.id).update_all(object_type: object.type) rescue FastJsonparser::ParseError => e ExceptionNotifier.notify_exception(e, data: { site: site.name, body: response.body }) end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index b03145e7..a8cc0d5d 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -18,19 +18,22 @@ class ActivityPub # Les actores son únicxs a toda la base de datos validates :uri, presence: true, url: true, uniqueness: true + before_save :mentionize! + # Obtiene el nombre de la Actor como mención, solo si obtuvimos el # contenido de antemano. # # @return [String, nil] - def mention + def mentionize! + return if mention.present? return if content['preferredUsername'].blank? return if instance.blank? - @mention ||= "@#{content['preferredUsername']}@#{instance.hostname}" + self.mention ||= "@#{content['preferredUsername']}@#{instance.hostname}" end def object - @object ||= ActivityPub::Object::Person.find_or_initialize_by(uri: uri) + @object ||= ActivityPub::Object.find_or_initialize_by(uri: uri) end def content diff --git a/db/migrate/20240316203721_add_mention_to_actors.rb b/db/migrate/20240316203721_add_mention_to_actors.rb new file mode 100644 index 00000000..caa4f526 --- /dev/null +++ b/db/migrate/20240316203721_add_mention_to_actors.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Guarda la mención en la tabla de actores +class AddMentionToActors < ActiveRecord::Migration[6.1] + def up + add_column :activity_pub_actors, :mention, :string, null: true + + actor_types = %w[ + ActivityPub::Object::Application + ActivityPub::Object::Group + ActivityPub::Object::Organization + ActivityPub::Object::Person + ActivityPub::Object::Service + ] + + ActivityPub::Object.where(type: actor_types).where.not(content: {}).find_each do |object| + ActivityPub::Actor.find_by_uri(object.uri)&.save + end + end + + def down + remove_column :activity_pub_actors, :mention + end +end From 769eae61574e859c0bfc6078785f7fb28ef6aadf Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 19:05:12 -0300 Subject: [PATCH 680/814] feat: sincronizar en segundo plano --- .../actor_moderations_controller.rb | 2 +- .../activity_pub/instance_moderation_job.rb | 2 + app/jobs/activity_pub/sync_lists_job.rb | 70 +++++++++++++++++++ app/models/actor_moderation.rb | 33 +++------ app/models/fediblock_state.rb | 55 ++++----------- app/models/instance_moderation.rb | 42 ++--------- 6 files changed, 100 insertions(+), 104 deletions(-) create mode 100644 app/jobs/activity_pub/sync_lists_job.rb diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index cb7a63a9..cd81e441 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -64,7 +64,7 @@ class ActorModerationsController < ApplicationController end end - message = actor_moderation.public_send(method) ? :success : :error + message = actor_moderations.public_send(method) ? :success : :error flash[message] = I18n.t("actor_moderations.action_on_several.#{message}") end diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index 214f8dd4..00100abf 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -30,6 +30,8 @@ class ActivityPub else scope.block_all_without_callbacks! end + + ActivityPub::SyncListsJob.perform_later(site: site) end end end diff --git a/app/jobs/activity_pub/sync_lists_job.rb b/app/jobs/activity_pub/sync_lists_job.rb new file mode 100644 index 00000000..39f6bdc9 --- /dev/null +++ b/app/jobs/activity_pub/sync_lists_job.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +class ActivityPub + # Sincroniza las listas de bloqueo y permitidas con el estado actual + # de la base de datos. + class SyncListsJob < ApplicationJob + # Siempre correr al final + self.priority = 100 + + attr_reader :logs + + # Ejecuta todas las requests y consolida los posibles errores. + # + # @param site [Site] + def run(site:) + @logs = {} + + instance_scope = site.instance_moderations.joins(:instance) + actor_scope = site.actor_moderations.joins(:actor) + + blocklist = wildcardize(instance_scope.blocked.pluck(:hostname)) + actor_scope.blocked.distinct.pluck(:mention).compact + allowlist = wildcardize(instance_scope.allowed.pluck(:hostname)) + actor_scope.allowed.distinct.pluck(:mention).compact + pauselist = wildcardize(instance_scope.paused.pluck(:hostname)) + actor_scope.paused.distinct.pluck(:mention).compact + + if blocklist.present? + Rails.logger.info "Bloqueando: #{blocklist.join(', ')}" + process(:blocked) { site.social_inbox.allowlist.delete(list: blocklist) } + process(:blocked) { site.social_inbox.blocklist.post(list: blocklist) } + end + + if allowlist.present? + Rails.logger.info "Permitiendo: #{allowlist.join(', ')}" + process(:allowed) { site.social_inbox.blocklist.delete(list: allowlist) } + process(:allowed) { site.social_inbox.allowlist.post(list: allowlist) } + end + + if pauselist.present? + Rails.logger.info "Pausando: #{pauselist.join(', ')}" + process(:paused) { site.social_inbox.blocklist.delete(list: pauselist) } + process(:paused) { site.social_inbox.allowlist.delete(list: pauselist) } + end + + # Si alguna falló, reintentar + raise if logs.present? + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, logs: logs, blocklist: blocklist, allowlist: allowlist, pauselist: pauselist }) + + raise + end + + private + + def process(stage) + response = yield + + return if response.ok? + + logs[stage] ||= [] + logs[stage] << { body: response.body, code: response.code } + end + + # @params hostnames [Array] + # @return [Array] + def wildcardize(hostnames) + hostnames.map do |hostname| + "@*@#{hostname}" + end + end + end +end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index c566b844..18149be4 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -14,9 +14,9 @@ class ActorModeration < ApplicationRecord accepts_nested_attributes_for :remote_flag aasm do - state :paused, initial: true, before_enter: :pause_remotely! - state :allowed, before_enter: :allow_remotely! - state :blocked, before_enter: :block_remotely! + state :paused, initial: true + state :allowed + state :blocked state :reported state :removed @@ -25,19 +25,19 @@ class ActorModeration < ApplicationRecord end event :pause do - transitions from: %i[allowed blocked reported], to: :paused + transitions from: %i[allowed blocked reported], to: :paused, after: :synchronize! end # Al permitir una cuenta no se permiten todos los comentarios # pendientes de moderación que ya hizo. event :allow do - transitions from: %i[paused blocked reported], to: :allowed + transitions from: %i[paused blocked reported], to: :allowed, after: :synchronize! end # Al bloquear una cuenta no se bloquean todos los comentarios # pendientes de moderación que hizo. event :block do - transitions from: %i[paused allowed], to: :blocked + transitions from: %i[paused allowed], to: :blocked, after: :synchronize! end # Al reportar, necesitamos asociar una RemoteFlag para poder @@ -64,24 +64,7 @@ class ActorModeration < ApplicationRecord # Definir eventos en masa include AasmEventsConcern - def pause_remotely! - raise unless - actor.mention && - site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && - site.social_inbox.blocklist.delete(list: [actor.mention]).ok? - end - - def allow_remotely! - raise unless - actor.mention && - site.social_inbox.allowlist.post(list: [actor.mention]).ok? && - site.social_inbox.blocklist.delete(list: [actor.mention]).ok? - end - - def block_remotely! - raise unless - actor.mention && - site.social_inbox.allowlist.delete(list: [actor.mention]).ok? && - site.social_inbox.blocklist.post(list: [actor.mention]).ok? + def synchronize! + ActivityPub::SyncListsJob.perform_later(site: site) end end diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index a6faa14f..82912f76 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -20,8 +20,8 @@ class FediblockState < ApplicationRecord # Aunque queramos las listas habilitadas por defecto, tenemos que # habilitarlas luego de crearlas para poder generar la lista de # bloqueo en la Social Inbox. - state :disabled, initial: true, before_enter: :disable_remotely_and_pause_instances! - state :enabled, before_enter: :enable_remotely_and_block_instances! + state :disabled, initial: true, before_enter: :pause_unique_instances! + state :enabled, before_enter: :block_instances! error_on_all_events do |e| ExceptionNotifier.notify_exception(e, data: { site: site.name, fediblock: id }) @@ -38,32 +38,27 @@ class FediblockState < ApplicationRecord # pero esto implica que tenemos que encontrar las que sí y quitarlas # de list_names event :disable do - transitions from: :enabled, to: :disabled + transitions from: :enabled, to: :disabled, after: :synchronize! end end private - def enable_remotely_and_block_instances! - # Bloquear todos las instancias de este Fediblock - enable_remotely! list_names(fediblock.hostnames) - - # Luego esta tarea crea las que falten e ignora las que ya se - # bloquearon. - ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames, perform_remotely: false) + def block_instances! + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames, perform_remotely: false) end - def disable_remotely_and_pause_instances! - # Deshabilitar todas las instancias que no estén habilitadas por - # otros fediblocks - disable_remotely! list_names(unique_hostnames) - - # Pausar todas las moderaciones de las instancias que no estén - # bloqueadas por otros fediblocks. + # Pausar todas las moderaciones de las instancias que no estén + # bloqueadas por otros fediblocks. + def pause_unique_instances! instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks! end + def synchronize! + ActivityPub::SyncListsJob.perform_later(site: site) + end + # Devuelve los hostnames únicos a esta instancia. # # @return [Array] @@ -82,30 +77,4 @@ class FediblockState < ApplicationRecord fediblock.hostnames - other_enabled_hostnames end end - - # @param hostnames [Array] - # @return [Array] - def list_names(hostnames) - hostnames.map do |hostname| - "@*@#{hostname}" - end - end - - # Al deshabilitar, las instancias pasan a ser analizadas caso por caso - # - # @param list [Array] - def disable_remotely!(list) - raise unless - site.social_inbox.blocklist.delete(list: list).ok? && - site.social_inbox.allowlist.delete(list: list).ok? - end - - # Al habilitar, se bloquean todas las instancias de la lista - # - # @param list [Array] - def enable_remotely!(list) - raise unless - site.social_inbox.blocklist.post(list: list).ok? && - site.social_inbox.allowlist.delete(list: list).ok? - end end diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 7c76262e..5a1a5ed6 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -11,14 +11,18 @@ class InstanceModeration < ApplicationRecord belongs_to :instance, class_name: 'ActivityPub::Instance' aasm do - state :paused, initial: true, before_enter: :pause_remotely! - state :allowed, before_enter: :allow_remotely! - state :blocked, before_enter: :block_remotely! + state :paused, initial: true + state :allowed + state :blocked error_on_all_events do |e| ExceptionNotifier.notify_exception(e, data: { site: site.name, instance: instance.hostname, instance_moderation: id }) end + after_all_events do + ActivityPub::SyncListsJob.perform_later(site: site) + end + # Al volver la instancia a pausa no cambiamos el estado de # moderación de actores pre-existente. event :pause do @@ -40,36 +44,4 @@ class InstanceModeration < ApplicationRecord # Definir eventos en masa include AasmEventsConcern - - # @return [Array] - def actor_ids - ActivityPub::Actor.where(instance_id: instance_id).ids - end - - # Elimina la instancia de todas las listas - # - # @return [Boolean] - def pause_remotely! - raise unless - site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && - site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? - end - - # Deja de permitir la instancia - # - # @return [Boolean] - def block_remotely! - raise unless - site.social_inbox.allowlist.delete(list: [instance.list_name]).ok? && - site.social_inbox.blocklist.post(list: [instance.list_name]).ok? - end - - # Permite la instancia - # - # @return [Boolean] - def allow_remotely! - raise unless - site.social_inbox.blocklist.delete(list: [instance.list_name]).ok? && - site.social_inbox.allowlist.post(list: [instance.list_name]).ok? - end end From a65a9f2f504969755529bd51efc03934c4c51a81 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 19:16:30 -0300 Subject: [PATCH 681/814] feat: aprobar o rechazar en segundo plano --- app/jobs/activity_pub/inbox_job.rb | 16 ++++++++++++++++ app/models/activity_pub.rb | 23 ++++++++++------------- 2 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 app/jobs/activity_pub/inbox_job.rb diff --git a/app/jobs/activity_pub/inbox_job.rb b/app/jobs/activity_pub/inbox_job.rb new file mode 100644 index 00000000..93216d44 --- /dev/null +++ b/app/jobs/activity_pub/inbox_job.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class ActivityPub + class InboxJob < ApplicationJob + self.priority = 10 + + # @param :site [Site] + # @param :activity [String] + # @param :action [Symbol] + def perform(site:, activity:, action:) + response = site.social_inbox.inbox.public_send(action, id: activity) + + raise response.body unless response.ok? + end + end +end diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 8142ecfb..55b48cd7 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -47,9 +47,9 @@ class ActivityPub < ApplicationRecord # Todavía no hay una decisión sobre el objeto state :paused, initial: true # Le usuarie aprobó el objeto - state :approved, before_enter: :allow_remotely! + state :approved # Le usuarie rechazó el objeto - state :rejected, before_enter: :reject_remotely! + state :rejected # Le usuarie reportó el objeto state :reported # Le actore eliminó el objeto @@ -84,11 +84,19 @@ class ActivityPub < ApplicationRecord # webhook a modo de confirmación. event :approve do transitions from: %i[paused], to: :approved + + after do + ActivityPub::InboxJob.perform_later(site: site, activity: activities.first.uri, action: :accept) + end end # La actividad fue rechazada event :reject do transitions from: %i[paused], to: :rejected + + after do + ActivityPub::InboxJob.perform_later(site: site, activity: activities.first.uri, action: :reject) + end end # Solo podemos reportarla luego de rechazarla @@ -103,15 +111,4 @@ class ActivityPub < ApplicationRecord # Definir eventos en masa include AasmEventsConcern - - # Lo que tenemos que aprobar o rechazar es la última actividad - # disponible, que según el scope por defecto, va a ser la primera de - # la lista. - def reject_remotely! - raise unless site.social_inbox.inbox.reject(id: activities.first.uri).ok? - end - - def allow_remotely! - raise unless site.social_inbox.inbox.accept(id: activities.first.uri).ok? - end end From e8ce721af02e4aade19dc92a2047def267fcb4fe Mon Sep 17 00:00:00 2001 From: f Date: Sat, 16 Mar 2024 19:20:32 -0300 Subject: [PATCH 682/814] =?UTF-8?q?fix:=20traducci=C3=B3n=20faltante?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index 7f71781c..39d35afe 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -109,7 +109,7 @@ es: instances_btn_box: text_pause: Moderar caso por caso text_allow: Permitir todo - text_deny: Bloquear instancia + text_block: Bloquear instancia profiles_btn_box: text_pause: Revisar siempre text_allow: Aprobar siempre From 883da8d881fc1480cc40370ffdcedf9e6556bdf4 Mon Sep 17 00:00:00 2001 From: f Date: Sun, 17 Mar 2024 12:06:55 -0300 Subject: [PATCH 683/814] =?UTF-8?q?fix:=20quiz=C3=A1s=20no=20hay=20actor?= =?UTF-8?q?=20aun=20(=3F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index e9220bfc..42b2cb27 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -9,6 +9,8 @@ # autenticación. class ActivityPub class FetchJob < ApplicationJob + include Que::Unique + self.priority = 50 def perform(site:, object_id:) @@ -32,7 +34,7 @@ class ActivityPub return if current_type == object.type object = ::ActivityPub::Object.find(object_id) - object.actor.save if object.actor_type? + object.actor&.save if object.actor_type? # Arreglar las relaciones con actividades también ActivityPub.where(object_id: object.id).update_all(object_type: object.type) From bdb5175fcd96c02816bee1be498ccdd80d733486 Mon Sep 17 00:00:00 2001 From: f Date: Sun, 17 Mar 2024 12:10:07 -0300 Subject: [PATCH 684/814] =?UTF-8?q?fixup!=20fix:=20quiz=C3=A1s=20no=20hay?= =?UTF-8?q?=20actor=20aun=20(=3F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 42b2cb27..bdb98e66 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -9,8 +9,6 @@ # autenticación. class ActivityPub class FetchJob < ApplicationJob - include Que::Unique - self.priority = 50 def perform(site:, object_id:) From 1623d618ee8743ada8d91d6c2ba2a670d20a5b53 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 11:21:13 -0300 Subject: [PATCH 685/814] fix: mostrar link externo al comentario #15638 --- app/models/activity_pub.rb | 36 ++++++++++++++++++++++++ app/views/moderation_queue/_comment.haml | 7 +++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 55b48cd7..913ac67d 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -43,6 +43,42 @@ class ActivityPub < ApplicationRecord end end + # Obtiene el campo `url` de diversas formas. Si es una String, asumir + # que es una URL, si es un Hash, asumir que es un Link, si es un + # Array de Strings, obtener la primera, si es de Hash, obtener el + # primer link con rel=canonical y mediaType=text/html + # + # De lo contrario devolver el ID. + # + # @todo Refactorizar + # @param object [Hash] + # @return [String] + def self.url_from_object(object) + raise unless object.respond_to?(:[]) + + url = + case object['url'] + when String then object['url'] + when Hash then object['href'] + # Esto es un lío porque queremos saber si es un Array o + # Array o mezcla y obtener el que más nos convenga o + # adivinar uno. + when Array + links = object['url'].map.with_index do |link, i| + case link + when Hash then link + else { 'href' => link.to_s } + end + end + + links.find do |link| + link['rel'] == 'canonical' && link['mediaType'] == 'text/html' + end&.[]('href') || links.first&.[]('href') + end + + url || object['id'] + end + aasm do # Todavía no hay una decisión sobre el objeto state :paused, initial: true diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index c6f6fd5c..787ae7c2 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -8,6 +8,8 @@ - in_reply_to = text_plain comment['inReplyTo'] - summary = text_plain comment['summary'] +-# @todo Generar un desplegable con todas las opciones +- url = text_plain ActivityPub.url_from_object(comment) .row.no-gutters .col-1 @@ -17,8 +19,9 @@ .d-flex.flex-row.align-items-center.justify-content-between %h4.mb-0 %a{ href: text_plain(comment['attributedTo']) }= text_plain profile['preferredUsername'] - %small - = render 'layouts/time', time: text_plain(comment['published']) + %a{ href: url } + %small + = render 'layouts/time', time: text_plain(comment['published']) - if in_reply_to.present? %dl %dt.d-inline From 7b87aaa93daf1d58a0b97ab89573043d239c4035 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 11:55:38 -0300 Subject: [PATCH 686/814] feat: referenciar objetos #15642 --- app/models/activity_pub/object.rb | 9 +++++++++ app/views/moderation_queue/_comment.haml | 9 +++++++++ app/views/moderation_queue/_comments.haml | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 9061c4c5..1d5d4478 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -29,5 +29,14 @@ class ActivityPub def object_type? true end + + # Poder explorar propiedades remotas + # + # @return [DistributedPress::V1::Social::ReferencedObject] + def referenced(site) + require 'distributed_press/v1/social/referenced_object' + + @referenced ||= DistributedPress::V1::Social::ReferencedObject.new(object: content, dereferencer: site.social_inbox.dereferencer) + end end end diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 787ae7c2..10f09106 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -1,12 +1,21 @@ -# Componente Comentario + @param site [Site] @param form [String] @param profile [Hash] @param comment [Hash] @param activity_pub [ActivityPub] - in_reply_to = text_plain comment['inReplyTo'] +:ruby + begin + if in_reply_to && (remote_object = object.referenced(site)['inReplyTo']) + in_reply_to = ActivityPub.url_from_object(remote_object) + end + rescue Exception => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, object: comment }) + end - summary = text_plain comment['summary'] -# @todo Generar un desplegable con todas las opciones - url = text_plain ActivityPub.url_from_object(comment) diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 68671f9e..583ef511 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -13,4 +13,4 @@ %h4= t('moderation_queue.nothing') - moderation_queue.each do |activity_pub| %hr - = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id + = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id, site: site, object: activity_pub.object From 9dc0ed7684ac56c456283baaabc678358abcda67 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 12:48:09 -0300 Subject: [PATCH 687/814] fix: reusar el reporto remoto #15648 --- app/controllers/concerns/moderation_concern.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/moderation_concern.rb b/app/controllers/concerns/moderation_concern.rb index 3b9d818f..8340ec2a 100644 --- a/app/controllers/concerns/moderation_concern.rb +++ b/app/controllers/concerns/moderation_concern.rb @@ -16,7 +16,9 @@ module ModerationConcern end def remote_flag_params(model) - { remote_flag_attributes: { id: model.remote_flag_id, message: ''.dup } }.tap do |p| + remote_flag = ActivityPub::RemoteFlag.find_by(actor_id: model.actor_id) + + { remote_flag_attributes: { id: remote_flag&.id, message: ''.dup } }.tap do |p| p[:remote_flag_attributes][:site_id] = model.site_id p[:remote_flag_attributes][:actor_id] = model.actor_id From bcfb7a5a7ffb3deec681767c54923244c47da0f9 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 12:55:27 -0300 Subject: [PATCH 688/814] fix: asignar la remote flag #15648 --- app/controllers/activity_pubs_controller.rb | 7 ++++++- app/controllers/actor_moderations_controller.rb | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index 225311c2..d5041a84 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -8,7 +8,12 @@ class ActivityPubsController < ApplicationController define_method(event) do authorize activity_pub - activity_pub.update(remote_flag_params(activity_pub)) if event == :report + if event == :report + remote_flag_params(activity_pub).tap do |p| + activity_pub.remote_flag_id = p[:remote_flag_attributes][:id] + activity_pub.update(p) + end + end message = if activity_pub.public_send(:"may_#{event}?") && activity_pub.public_send(:"#{event}!") diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index cd81e441..70aaf992 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -15,7 +15,12 @@ class ActorModerationsController < ApplicationController authorize actor_moderation # Crea una RemoteFlag si se envían los parámetros adecuados - actor_moderation.update(remote_flag_params(actor_moderation)) if actor_event == :report + if actor_event == :report + remote_flag_params(actor_moderation).tap do |p| + actor_moderation.remote_flag_id = p[:remote_flag_attributes][:id] + actor_moderation.update(p) + end + end message = if actor_moderation.public_send(:"may_#{actor_event}?") && actor_moderation.public_send(:"#{actor_event}!") From ceeb0009ef2fcd1faa01d5e59f2f77c2a0f124cb Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 14:40:11 -0300 Subject: [PATCH 689/814] fix: descubrir el tipo de objeto siempre closes #15656 closes #15657 closes #15658 closes #15660 closes #15661 closes #15662 closes #15663 closes #15664 closes #15665 closes #15666 closes #15667 closes #15668 closes #15669 closes #15670 closes #15671 closes #15672 closes #15673 closes #15674 closes #15675 closes #15676 closes #15677 closes #15678 closes #15679 closes #15680 closes #15681 closes #15682 closes #15683 closes #15684 closes #15685 closes #15686 closes #15687 closes #15688 closes #15689 closes #15690 closes #15691 closes #15692 closes #15693 closes #15694 closes #15695 closes #15696 closes #15697 closes #15698 closes #15699 closes #15700 closes #15701 closes #15702 closes #15704 closes #15705 closes #15706 closes #15707 closes #15708 --- app/jobs/activity_pub/process_job.rb | 13 +------------ app/models/activity_pub/object.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index 6554b44d..9b72be43 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -64,18 +64,7 @@ class ActivityPub # @return [ActivityPub::Object] def object @object ||= ::ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| - # XXX: Si el objeto es una actividad, esto siempre va a ser - # Generic - o.type ||= 'ActivityPub::Object::Generic' - - if object_embedded? - o.content = original_object - begin - type = original_object[:type].presence - o.type = "ActivityPub::Object::#{type}".constantize if type - rescue NameError - end - end + o.content = original_object if object_embedded? o.save! diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 1d5d4478..16cd6b01 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -5,6 +5,8 @@ class ActivityPub class Object < ApplicationRecord include ActivityPub::Concerns::JsonLdConcern + before_validation :type_from_content!, unless: :type? + # Los objetos son únicos a toda la base de datos validates :uri, presence: true, url: true, uniqueness: true @@ -38,5 +40,20 @@ class ActivityPub @referenced ||= DistributedPress::V1::Social::ReferencedObject.new(object: content, dereferencer: site.social_inbox.dereferencer) end + + private + + # Encuentra el tipo a partir del contenido, si existe. + # + # XXX: Si el objeto es una actividad, esto siempre va a ser + # Generic + def type_from_content! + self.type = + begin + "ActivityPub::Object::#{content['type'].presence || 'Generic'}".constantize + rescue NameError + ActivityPub::Object::Generic + end + end end end From e50ae70ebb7c254cc87769419a31b46582823c1e Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 15:06:41 -0300 Subject: [PATCH 690/814] fix: no actualizar si el contenido estaba cacheado --- app/jobs/activity_pub/fetch_job.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index bdb98e66..78a6dbee 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -22,7 +22,9 @@ class ActivityPub # @todo Fallar cuando la respuesta no funcione? return unless response.ok? - return if response.miss? && object.content.present? + # Ignorar si ya la caché fue revalidada y ya teníamos el + # contenido + return if response.hit? && object.content.present? current_type = object.type content = FastJsonparser.parse(response.body) From e6d4b4d3f16ff9f114e04530c1104d28df0fc0e6 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 15:10:16 -0300 Subject: [PATCH 691/814] fix: validar que el contenido del objeto sea el que queremos --- app/models/activity_pub/object.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 16cd6b01..d37c9b88 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -9,6 +9,7 @@ class ActivityPub # Los objetos son únicos a toda la base de datos validates :uri, presence: true, url: true, uniqueness: true + validate :uri_is_content_id?, if: :content? has_many :activity_pubs, as: :object @@ -43,6 +44,12 @@ class ActivityPub private + def uri_is_content_id? + return if self.uri == content['id'] + + errors.add(:activity_pub_objects, 'El ID del objeto no coincide con su URI') + end + # Encuentra el tipo a partir del contenido, si existe. # # XXX: Si el objeto es una actividad, esto siempre va a ser From 75b6314e1dfc70cf53e716914b211664ee3dd768 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 15:46:03 -0300 Subject: [PATCH 692/814] =?UTF-8?q?fix:=20qu=C3=A9=20pasa=20con=20los=20ob?= =?UTF-8?q?jetos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 7 ++++--- .../20240318183846_fix_duplicate_objects.rb | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20240318183846_fix_duplicate_objects.rb diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 78a6dbee..f1a51e96 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -29,15 +29,16 @@ class ActivityPub current_type = object.type content = FastJsonparser.parse(response.body) - object.update(content: content, type: ActivityPub::Object.type_from(content).name) + object.update!(content: content, type: ActivityPub::Object.type_from(content).name) return if current_type == object.type object = ::ActivityPub::Object.find(object_id) - object.actor&.save if object.actor_type? + # Actualiza la mención + object.actor&.save! if object.actor_type? # Arreglar las relaciones con actividades también - ActivityPub.where(object_id: object.id).update_all(object_type: object.type) + ActivityPub.where(object_id: object.id).update_all(object_type: object.type, updated_at: Time.now) rescue FastJsonparser::ParseError => e ExceptionNotifier.notify_exception(e, data: { site: site.name, body: response.body }) end diff --git a/db/migrate/20240318183846_fix_duplicate_objects.rb b/db/migrate/20240318183846_fix_duplicate_objects.rb new file mode 100644 index 00000000..f863ba3e --- /dev/null +++ b/db/migrate/20240318183846_fix_duplicate_objects.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# De alguna forma se guardaron objetos duplicados! +class FixDuplicateObjects < ActiveRecord::Migration[6.1] + def up + ActivityPub::Object.group(:uri).count.select { |_, v| v > 1 }.keys.each do |uri| + objects = ActivityPub::Object.where(uri: uri) + deleted_ids = objects[1..].map(&:delete).map(&:id) + + ActivityPub.where(object_id: deleted_ids).update_all(object_id: object.first.id, updated_at: Time.now) + end + end + + def down; end +end From bd0df0a53a5a0c18cd9bcfcd0e89c8ecf569d0a0 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 15:47:38 -0300 Subject: [PATCH 693/814] =?UTF-8?q?fixup!=20fix:=20qu=C3=A9=20pasa=20con?= =?UTF-8?q?=20los=20objetos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20240318183846_fix_duplicate_objects.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240318183846_fix_duplicate_objects.rb b/db/migrate/20240318183846_fix_duplicate_objects.rb index f863ba3e..88d23c6f 100644 --- a/db/migrate/20240318183846_fix_duplicate_objects.rb +++ b/db/migrate/20240318183846_fix_duplicate_objects.rb @@ -7,7 +7,7 @@ class FixDuplicateObjects < ActiveRecord::Migration[6.1] objects = ActivityPub::Object.where(uri: uri) deleted_ids = objects[1..].map(&:delete).map(&:id) - ActivityPub.where(object_id: deleted_ids).update_all(object_id: object.first.id, updated_at: Time.now) + ActivityPub.where(object_id: deleted_ids).update_all(object_id: objects.first.id, updated_at: Time.now) end end From 376339aee50cd7e7353a2212c9aa8f4f68965581 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 16:45:00 -0300 Subject: [PATCH 694/814] fix: correr las consultas de todas formas --- app/jobs/activity_pub/fetch_job.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index f1a51e96..4d4d4483 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -21,6 +21,7 @@ class ActivityPub response = site.social_inbox.dereferencer.get(uri: object.uri) # @todo Fallar cuando la respuesta no funcione? + # @todo Eliminar en 410 Gone return unless response.ok? # Ignorar si ya la caché fue revalidada y ya teníamos el # contenido @@ -31,8 +32,6 @@ class ActivityPub object.update!(content: content, type: ActivityPub::Object.type_from(content).name) - return if current_type == object.type - object = ::ActivityPub::Object.find(object_id) # Actualiza la mención object.actor&.save! if object.actor_type? From 8034d206121c6ef7e1aecca48f2174e075af6426 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 16:55:20 -0300 Subject: [PATCH 695/814] fix: ignorar comentarios y cuentas sin contenido aun --- app/views/moderation_queue/_accounts.haml | 1 + app/views/moderation_queue/_comments.haml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/views/moderation_queue/_accounts.haml b/app/views/moderation_queue/_accounts.haml index d8d76f0d..257b0fbf 100644 --- a/app/views/moderation_queue/_accounts.haml +++ b/app/views/moderation_queue/_accounts.haml @@ -12,5 +12,6 @@ - if actor_moderations.count.zero? %h4= t('moderation_queue.nothing') - actor_moderations.find_each do |actor_moderation| + - next if actor_moderation.actor.content.empty? %hr = render 'account', actor_moderation: actor_moderation, profile: actor_moderation.actor.content, form: form_id diff --git a/app/views/moderation_queue/_comments.haml b/app/views/moderation_queue/_comments.haml index 583ef511..a7523517 100644 --- a/app/views/moderation_queue/_comments.haml +++ b/app/views/moderation_queue/_comments.haml @@ -12,5 +12,7 @@ - if moderation_queue.count.zero? %h4= t('moderation_queue.nothing') - moderation_queue.each do |activity_pub| + - next if activity_pub.object.content.empty? + - next if activity_pub.actor.content.empty? %hr = render 'moderation_queue/comment', comment: activity_pub.object.content, profile: activity_pub.actor.content, activity_pub: activity_pub, form: form_id, site: site, object: activity_pub.object From ab43c84ab1b0287a49150b9ab5011f61b76fc151 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 17:13:32 -0300 Subject: [PATCH 696/814] fix: indicar el filtro activo #15652 --- app/helpers/moderation_queue_helper.rb | 10 +++++++++- app/views/components/_comments_show_submenu.haml | 3 ++- app/views/components/_dropdown_item.haml | 3 ++- app/views/components/_instances_show_submenu.haml | 3 ++- app/views/components/_profiles_show_submenu.haml | 3 ++- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app/helpers/moderation_queue_helper.rb b/app/helpers/moderation_queue_helper.rb index 3681bec3..c69364ae 100644 --- a/app/helpers/moderation_queue_helper.rb +++ b/app/helpers/moderation_queue_helper.rb @@ -2,6 +2,14 @@ module ModerationQueueHelper def filter_states(**args) - params.permit(:state, :actor_state, :activity_pub_state).merge(**args) + params.permit(:instance_state, :actor_state, :activity_pub_state).merge(**args) + end + + def active?(states, state_name, state) + if params[state_name].present? + params[state_name] == state.to_s + else + states.first == state + end end end diff --git a/app/views/components/_comments_show_submenu.haml b/app/views/components/_comments_show_submenu.haml index 60c02501..9964a62a 100644 --- a/app/views/components/_comments_show_submenu.haml +++ b/app/views/components/_comments_show_submenu.haml @@ -1,4 +1,5 @@ - ActivityPub.states.each do |state| = render 'components/dropdown_item', text: t(".submenu_#{state}", count: activity_pubs.unscope(where: :aasm_state).public_send(state).count), - path: filter_states(activity_pub_state: state) + path: filter_states(activity_pub_state: state), + class: ('active' if active?(ActivityPub.states, :activity_pub_state, state)) diff --git a/app/views/components/_dropdown_item.haml b/app/views/components/_dropdown_item.haml index e5b16950..a4d363a8 100644 --- a/app/views/components/_dropdown_item.haml +++ b/app/views/components/_dropdown_item.haml @@ -1,4 +1,5 @@ -# @param :text [String] Contenido del link @param :path [String,Hash] Link -= link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' } +- local_assigns[:class] = "dropdown-item #{local_assigns[:class]}" += link_to text, path, class: local_assigns[:class], data: { target: 'dropdown.item' } diff --git a/app/views/components/_instances_show_submenu.haml b/app/views/components/_instances_show_submenu.haml index c56df547..6b9b747e 100644 --- a/app/views/components/_instances_show_submenu.haml +++ b/app/views/components/_instances_show_submenu.haml @@ -1,4 +1,5 @@ - InstanceModeration.states.each do |state| = render 'components/dropdown_item', text: t(".submenu_#{state}", count: instance_moderations.unscope(where: :aasm_state).public_send(state).count), - path: filter_states(instance_state: state) + path: filter_states(instance_state: state), + class: ('active' if active?(InstanceModeration.states, :instance_state, state)) diff --git a/app/views/components/_profiles_show_submenu.haml b/app/views/components/_profiles_show_submenu.haml index 99694698..bebfbe20 100644 --- a/app/views/components/_profiles_show_submenu.haml +++ b/app/views/components/_profiles_show_submenu.haml @@ -1,4 +1,5 @@ - ActorModeration.states.each do |actor_state| = render 'components/dropdown_item', text: t(".submenu_#{actor_state}", count: actor_moderations.unscope(where: :aasm_state).public_send(actor_state).count), - path: filter_states(actor_state: actor_state) + path: filter_states(actor_state: actor_state), + class: ('active' if active?(ActorModeration.states, :actor_state, actor_state)) From dae0346f0ddc3d15825f7d4232b16e9fe86f2c15 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 17:28:49 -0300 Subject: [PATCH 697/814] fix: pasar el sitio como argumento --- app/views/actor_moderations/show.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/actor_moderations/show.haml b/app/views/actor_moderations/show.haml index 633c1be5..ca5764f4 100644 --- a/app/views/actor_moderations/show.haml +++ b/app/views/actor_moderations/show.haml @@ -5,4 +5,4 @@ .col-12.col-md-8 = render 'components/profiles_btn_box', actor_moderation: @actor_moderation .col-12.col-md-8 - = render 'moderation_queue/comments', moderation_queue: @moderation_queue + = render 'moderation_queue/comments', site: @site, moderation_queue: @moderation_queue From 7c9e9758c5fecd4deb09a08f337e95439e0469da Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 17:51:29 -0300 Subject: [PATCH 698/814] =?UTF-8?q?fix:=20informar=20la=20uri=20que=20fall?= =?UTF-8?q?=C3=B3=20#15712?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/fetch_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 4d4d4483..9d14307a 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -39,7 +39,7 @@ class ActivityPub # Arreglar las relaciones con actividades también ActivityPub.where(object_id: object.id).update_all(object_type: object.type, updated_at: Time.now) rescue FastJsonparser::ParseError => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, body: response.body }) + ExceptionNotifier.notify_exception(e, data: { site: site.name, object: object.uri, body: response.body }) end end end From e2abe224d40f7572244f4969cedf3af1bd1a65df Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 17:54:07 -0300 Subject: [PATCH 699/814] fix: fallbacks #15659 --- app/controllers/actor_moderations_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 70aaf992..739b1f46 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -44,7 +44,7 @@ class ActorModerationsController < ApplicationController @moderation_queue = rubanok_process(site.activity_pubs.where(actor_id: actor_moderation.actor_id), with: ActivityPubProcessor) - breadcrumb @remote_profile['name'], '' + breadcrumb @remote_profile['name'] || actor_moderation.actor.mention || actor_moderation.actor.uri, '' end def action_on_several From d13e56e692e65344b436d5585289b9268fe43669 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 18:09:32 -0300 Subject: [PATCH 700/814] =?UTF-8?q?fix:=20descripci=C3=B3n=20para=20las=20?= =?UTF-8?q?listas=20de=20bloqueo=20#15643?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 6f76fe57..075b62ec 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -180,7 +180,7 @@ en: reply_to: Reply to instances: title: My block lists - description: Description + description: "Blocklists contain instances known for hosting hate speech, promote fascism, violence, sexual/gendered abuse and/or misinformation." custom_block: Custom block lists submit: Save block lists instance: diff --git a/config/locales/es.yml b/config/locales/es.yml index 39d35afe..2d4974b1 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -179,7 +179,7 @@ es: reply_to: En respuesta a instances: title: Mis listas de bloqueo - description: Descripción de listas de bloqueo + description: "Las listas de bloqueo contienen instancias conocidas por alojar discurso de odio, promover el fascismo, la violencia, abuso sexual y/o desinformación." custom_block: Lista personalizada de bloqueo submit: Guardar listas de bloqueo instance: From 979f3c1b3ac214856840a7bfa248603229dbdbfe Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Mar 2024 18:12:02 -0300 Subject: [PATCH 701/814] fix: ayuda para la lista customizada #15643 --- app/views/moderation_queue/_block_instances_textarea.haml | 2 +- config/locales/en.yml | 3 +++ config/locales/es.yml | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/views/moderation_queue/_block_instances_textarea.haml b/app/views/moderation_queue/_block_instances_textarea.haml index 9729d4de..7daf0410 100644 --- a/app/views/moderation_queue/_block_instances_textarea.haml +++ b/app/views/moderation_queue/_block_instances_textarea.haml @@ -1,3 +1,3 @@ .form-group = label_tag 'custom_blocklist', t('moderation_queue.instances.custom_block') - = text_area_tag 'custom_blocklist', nil, class: 'form-control' + = text_area_tag 'custom_blocklist', nil, class: 'form-control', placeholder: t('moderation_queue.instances.custom_block_placeholder') diff --git a/config/locales/en.yml b/config/locales/en.yml index 075b62ec..35b857e6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -182,6 +182,9 @@ en: title: My block lists description: "Blocklists contain instances known for hosting hate speech, promote fascism, violence, sexual/gendered abuse and/or misinformation." custom_block: Custom block lists + custom_block_placeholder: | + a.doma.in + per.li.ne submit: Save block lists instance: users: "Users:" diff --git a/config/locales/es.yml b/config/locales/es.yml index 2d4974b1..77e611ed 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -181,6 +181,9 @@ es: title: Mis listas de bloqueo description: "Las listas de bloqueo contienen instancias conocidas por alojar discurso de odio, promover el fascismo, la violencia, abuso sexual y/o desinformación." custom_block: Lista personalizada de bloqueo + custom_block_placeholder: | + un.domin.io + por.lin.ea submit: Guardar listas de bloqueo instance: users: "Usuaries:" From b90f8864461e3b2d8a5f725a0a81cd9f4cc858e7 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 09:47:24 -0300 Subject: [PATCH 702/814] feat: fedipact --- app/models/activity_pub/fediblock.rb | 4 +-- ...240319124212_add_fedipact_to_fediblocks.rb | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20240319124212_add_fedipact_to_fediblocks.rb diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb index 4abcb80f..ec66c032 100644 --- a/app/models/activity_pub/fediblock.rb +++ b/app/models/activity_pub/fediblock.rb @@ -31,8 +31,8 @@ class ActivityPub class FediblockDownloadError < ::StandardError; end - validates_presence_of :title, :url, :download_url, :format - validates_inclusion_of :format, in: %w[mastodon fediblock] + validates_presence_of :title, :url, :format + validates_inclusion_of :format, in: %w[mastodon fediblock none] HOSTNAME_HEADERS = { 'mastodon' => '#domain', diff --git a/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb b/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb new file mode 100644 index 00000000..648f2ee7 --- /dev/null +++ b/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# Agrega threads.net a las listas de bloqueo +class AddFedipactToFediblocks < ActiveRecord::Migration[6.1] + def up + fedipact = + ActivityPub::Fediblock.create( + hostnames: %w[threads.net], + title: 'Fedipact', + url: 'https://fedipact.online/', + format: 'none' + ) + + DeploySocialDistributedPress.find_each do |deploy| + FediblockState.create(site: deploy.site, fediblock: fedipact, aasm_state: 'disabled').tap do |f| + f.enable! + end + end + end + + def down + fedipact = ActivityPub::Fediblock.find_by(url: 'https://fedipact.online/').delete + FediblockState.where(fediblock_id: fedipact.id).delete_all + end +end From c047858a6f418a7bbf42eb5d3730a5ed114916c1 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 09:49:34 -0300 Subject: [PATCH 703/814] fixup! feat: fedipact --- db/migrate/20240319124212_add_fedipact_to_fediblocks.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb b/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb index 648f2ee7..d78439b2 100644 --- a/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb +++ b/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb @@ -3,6 +3,8 @@ # Agrega threads.net a las listas de bloqueo class AddFedipactToFediblocks < ActiveRecord::Migration[6.1] def up + change_column :activity_pub_fediblocks, :download_url, :string, null: true + fedipact = ActivityPub::Fediblock.create( hostnames: %w[threads.net], @@ -21,5 +23,6 @@ class AddFedipactToFediblocks < ActiveRecord::Migration[6.1] def down fedipact = ActivityPub::Fediblock.find_by(url: 'https://fedipact.online/').delete FediblockState.where(fediblock_id: fedipact.id).delete_all + change_column :activity_pub_fediblocks, :download_url, :string, null: false end end From 48d8d2d8d802b46318f6a36c6beb9a1955683fa5 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 10:59:10 -0300 Subject: [PATCH 704/814] =?UTF-8?q?fix:=20la=20l=C3=B3gica=20estaba=20al?= =?UTF-8?q?=20rev=C3=A9s=20#15647?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/remote_flag_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 20833bd4..71751d39 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -13,7 +13,7 @@ class ActivityPub self.priority = 30 def perform(remote_flag:) - return if remote_flag.may_queue? + return unless remote_flag.may_queue? inbox = remote_flag.actor&.content&.[]('inbox') From 93ebb6431a211d75f462c86163ec9fbc5e9ea73d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 11:20:49 -0300 Subject: [PATCH 705/814] =?UTF-8?q?fix:=20buscar=20un=20c=C3=B3digo=20de?= =?UTF-8?q?=20respuesta=20general?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/actor_fetch_job.rb | 2 +- app/jobs/activity_pub/fetch_job.rb | 2 +- app/jobs/activity_pub/inbox_job.rb | 2 +- app/jobs/activity_pub/instance_fetch_job.rb | 2 +- app/jobs/activity_pub/remote_flag_job.rb | 2 +- app/jobs/activity_pub/sync_lists_job.rb | 2 +- app/models/activity_pub/fediblock.rb | 2 +- app/models/deploy_social_distributed_press.rb | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb index 1190e936..598ecd83 100644 --- a/app/jobs/activity_pub/actor_fetch_job.rb +++ b/app/jobs/activity_pub/actor_fetch_job.rb @@ -16,7 +16,7 @@ class ActivityPub response = site.social_inbox.dereferencer.get(uri: actor.uri) # @todo Fallar cuando la respuesta no funcione? - return unless response.ok? + return unless response.success? return if response.miss? && actor.content.present? actor.object.update(content: FastJsonparser.parse(response.body)) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 9d14307a..beb585ff 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -22,7 +22,7 @@ class ActivityPub # @todo Fallar cuando la respuesta no funcione? # @todo Eliminar en 410 Gone - return unless response.ok? + return unless response.success? # Ignorar si ya la caché fue revalidada y ya teníamos el # contenido return if response.hit? && object.content.present? diff --git a/app/jobs/activity_pub/inbox_job.rb b/app/jobs/activity_pub/inbox_job.rb index 93216d44..cb807704 100644 --- a/app/jobs/activity_pub/inbox_job.rb +++ b/app/jobs/activity_pub/inbox_job.rb @@ -10,7 +10,7 @@ class ActivityPub def perform(site:, activity:, action:) response = site.social_inbox.inbox.public_send(action, id: activity) - raise response.body unless response.ok? + raise response.body unless response.success? end end end diff --git a/app/jobs/activity_pub/instance_fetch_job.rb b/app/jobs/activity_pub/instance_fetch_job.rb index 9c562f7d..dc84caf2 100644 --- a/app/jobs/activity_pub/instance_fetch_job.rb +++ b/app/jobs/activity_pub/instance_fetch_job.rb @@ -15,7 +15,7 @@ class ActivityPub response = site.social_inbox.dereferencer.get(uri: uri) - next unless response.ok? + next unless response.success? # @todo Validate schema next unless response.parsed_response.is_a?(DistributedPress::V1::Social::ReferencedObject) diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index 71751d39..f586a92e 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -25,7 +25,7 @@ class ActivityPub client = remote_flag.main_site.social_inbox.client_for(uri.origin) response = client.post(endpoint: uri.path, body: remote_flag.content) - raise 'No se pudo enviar el reporte' unless response.ok? + raise 'No se pudo enviar el reporte' unless response.success? remote_flag.report! rescue Exception => e diff --git a/app/jobs/activity_pub/sync_lists_job.rb b/app/jobs/activity_pub/sync_lists_job.rb index 39f6bdc9..cc500bee 100644 --- a/app/jobs/activity_pub/sync_lists_job.rb +++ b/app/jobs/activity_pub/sync_lists_job.rb @@ -53,7 +53,7 @@ class ActivityPub def process(stage) response = yield - return if response.ok? + return if response.success? logs[stage] ||= [] logs[stage] << { body: response.body, code: response.code } diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb index ec66c032..17897d79 100644 --- a/app/models/activity_pub/fediblock.rb +++ b/app/models/activity_pub/fediblock.rb @@ -52,7 +52,7 @@ class ActivityPub def process! response = client.get(download_url) - raise FediblockDownloadError unless response.ok? + raise FediblockDownloadError unless response.success? Fediblock.transaction do csv = response.parsed_response diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index c7a103a4..e7f97406 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -84,7 +84,7 @@ class DeploySocialDistributedPress < Deploy response = hook_client.put(event: event, hook: webhook) - raise ArgumentError, response.body unless response.ok? + raise ArgumentError, response.body unless response.success? rescue ArgumentError => e ExceptionNotifier.notify_exception(e, data: { site_id: site.name, usuarie_id: rol.usuarie_id }) end From 8d6d215e1af43cd2bc80f24f4aea5a5687f9d286 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 11:21:03 -0300 Subject: [PATCH 706/814] =?UTF-8?q?fix:=20si=20falla=20el=20reporte=20marc?= =?UTF-8?q?arlo=20para=20reenv=C3=ADo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/remote_flag_job.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/jobs/activity_pub/remote_flag_job.rb b/app/jobs/activity_pub/remote_flag_job.rb index f586a92e..211f46fc 100644 --- a/app/jobs/activity_pub/remote_flag_job.rb +++ b/app/jobs/activity_pub/remote_flag_job.rb @@ -30,6 +30,7 @@ class ActivityPub remote_flag.report! rescue Exception => e ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response }) + remote_flag.resend! raise end end From 0ed702992b509cbd6d435474db050228cb88354f Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 12:39:41 -0300 Subject: [PATCH 707/814] fix: prevenir objetos multiplicados! parece que la forma en que estabamos creando indices unicos ya no funciona (??) asi que a veces estabamos creando objetos duplicados en threads. de paso actorfetchjob ya no es necesario. closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 --- app/jobs/activity_pub/actor_fetch_job.rb | 26 ---------- app/jobs/activity_pub/fetch_job.rb | 2 +- app/jobs/activity_pub/process_job.rb | 17 +++---- app/models/activity_pub/actor.rb | 2 +- ...240319144735_add_missing_unique_indexes.rb | 48 +++++++++++++++++++ db/structure.sql | 28 +++++++++-- 6 files changed, 82 insertions(+), 41 deletions(-) delete mode 100644 app/jobs/activity_pub/actor_fetch_job.rb create mode 100644 db/migrate/20240319144735_add_missing_unique_indexes.rb diff --git a/app/jobs/activity_pub/actor_fetch_job.rb b/app/jobs/activity_pub/actor_fetch_job.rb deleted file mode 100644 index 598ecd83..00000000 --- a/app/jobs/activity_pub/actor_fetch_job.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -# Obtiene o actualiza el contenido de un objeto, usando las credenciales -# del sitio. -# -# XXX: Esto usa las credenciales del sitio para volver el objeto -# disponible para todo el CMS. Asumimos que el objeto devuelto es el -# mismo para todo el mundo y las credenciales solo son para -# autenticación. -class ActivityPub - class ActorFetchJob < ApplicationJob - self.priority = 50 - - def perform(site:, actor:) - ActivityPub::Actor.transaction do - response = site.social_inbox.dereferencer.get(uri: actor.uri) - - # @todo Fallar cuando la respuesta no funcione? - return unless response.success? - return if response.miss? && actor.content.present? - - actor.object.update(content: FastJsonparser.parse(response.body)) - end - end - end -end diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index beb585ff..e0033439 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -30,7 +30,7 @@ class ActivityPub current_type = object.type content = FastJsonparser.parse(response.body) - object.update!(content: content, type: ActivityPub::Object.type_from(content).name) + object.lock.update!(content: content, type: ActivityPub::Object.type_from(content).name) object = ::ActivityPub::Object.find(object_id) # Actualiza la mención diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index 9b72be43..4e278797 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -63,7 +63,7 @@ class ActivityPub # # @return [ActivityPub::Object] def object - @object ||= ::ActivityPub::Object.find_or_initialize_by(uri: object_uri).tap do |o| + @object ||= ::ActivityPub::Object.lock.find_or_initialize_by(uri: object_uri).tap do |o| o.content = original_object if object_embedded? o.save! @@ -80,8 +80,8 @@ class ActivityPub # # @return [ActivityPub] def activity_pub - @activity_pub ||= site.activity_pubs.find_or_create_by!(site: site, actor: actor, instance: instance, - object_id: object.id, object_type: object.type) + @activity_pub ||= site.activity_pubs.lock.find_or_create_by!(site: site, actor: actor, instance: instance, + object_id: object.id, object_type: object.type) end # Crea la actividad y la vincula con el estado @@ -91,6 +91,7 @@ class ActivityPub @activity ||= ::ActivityPub::Activity .type_from(original_activity) + .lock .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup a.content[:object] = object.uri @@ -103,20 +104,20 @@ class ActivityPub # # @return [Actor] def actor - @actor ||= ::ActivityPub::Actor.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| + @actor ||= ::ActivityPub::Actor.lock.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| unless a.instance - a.instance = ::ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname) + a.instance = ::ActivityPub::Instance.lock.find_or_create_by(hostname: URI.parse(a.uri).hostname) ::ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance) end - site.instance_moderations.find_or_create_by(instance: a.instance) + site.instance_moderations.lock.find_or_create_by(instance: a.instance) a.save! - site.actor_moderations.find_or_create_by(actor: a) + site.actor_moderations.lock.find_or_create_by(actor: a) - ::ActivityPub::ActorFetchJob.perform_later(site: site, actor: a) + ::ActivityPub::FetchJob.perform_later(site: site, actor: a.object) end end diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index a8cc0d5d..6a284025 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -33,7 +33,7 @@ class ActivityPub end def object - @object ||= ActivityPub::Object.find_or_initialize_by(uri: uri) + @object ||= ActivityPub::Object.lock.find_or_create_by(uri: uri) end def content diff --git a/db/migrate/20240319144735_add_missing_unique_indexes.rb b/db/migrate/20240319144735_add_missing_unique_indexes.rb new file mode 100644 index 00000000..7d18c8e8 --- /dev/null +++ b/db/migrate/20240319144735_add_missing_unique_indexes.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +# Parece que la sintaxis que veníamos usando para los índices únicos ya +# no es válida y por eso teníamos objetos duplicados. +class AddMissingUniqueIndexes < ActiveRecord::Migration[6.1] + def up + ActivityPub::Object.group(:uri).count.select { |_, v| v > 1 }.keys.each do |uri| + objects = ActivityPub::Object.where(uri: uri) + deleted_ids = objects[1..].map(&:delete).map(&:id) + + ActivityPub.where(object_id: deleted_ids).update_all(object_id: objects.first.id, updated_at: Time.now) + end + + ActivityPub::Actor.group(:uri).count.select { |_, v| v > 1 }.keys.each do |uri| + objects = ActivityPub::Actor.where(uri: uri) + deleted_ids = objects[1..].map(&:delete).map(&:id) + + ActivityPub.where(actor_id: deleted_ids).update_all(actor_id: objects.first.id, updated_at: Time.now) + ActorModeration.where(actor_id: deleted_ids).update_all(actor_id: objects.first.id, updated_at: Time.now) + ActivityPub::Activity.where(actor_id: deleted_ids).update_all(actor_id: objects.first.id, updated_at: Time.now) + ActivityPub::RemoteFlag.where(actor_id: deleted_ids).update_all(actor_id: objects.first.id, updated_at: Time.now) + end + + ActivityPub::Instance.group(:hostname).count.select { |_, v| v > 1 }.keys.each do |hostname| + objects = ActivityPub::Instance.where(hostname: hostname) + deleted_ids = objects[1..].map(&:delete).map(&:id) + + ActivityPub.where(instance_id: deleted_ids).update_all(instance_id: objects.first.id, updated_at: Time.now) + InstanceModeration.where(instance_id: deleted_ids).update_all(instance_id: objects.first.id, updated_at: Time.now) + ActivityPub::Actor.where(instance_id: deleted_ids).update_all(instance_id: objects.first.id, updated_at: Time.now) + end + + remove_index :activity_pub_instances, :hostname + remove_index :activity_pub_actors, :uri + add_index :activity_pub_instances, :hostname, unique: true + add_index :activity_pub_objects, :uri, unique: true + add_index :activity_pub_actors, :uri, unique: true + end + + def down + remove_index :activity_pub_instances, :hostname, unique: true + remove_index :activity_pub_objects, :uri, unique: true + remove_index :activity_pub_actors, :uri, unique: true + add_index :activity_pub_instances, :hostname + add_index :activity_pub_objects, :uri + add_index :activity_pub_actors, :uri + end +end diff --git a/db/structure.sql b/db/structure.sql index ed58ebec..21cf04d0 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -498,7 +498,8 @@ CREATE TABLE public.activity_pub_actors ( created_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL, instance_id uuid NOT NULL, - uri character varying NOT NULL + uri character varying NOT NULL, + mention character varying ); @@ -512,7 +513,7 @@ CREATE TABLE public.activity_pub_fediblocks ( updated_at timestamp(6) without time zone NOT NULL, title character varying NOT NULL, url character varying NOT NULL, - download_url character varying NOT NULL, + download_url character varying, format character varying NOT NULL, hostnames jsonb DEFAULT '[]'::jsonb ); @@ -557,6 +558,7 @@ CREATE TABLE public.activity_pub_remote_flags ( site_id bigint, actor_id uuid, message text, + content jsonb, aasm_state character varying DEFAULT 'waiting'::character varying NOT NULL ); @@ -2138,14 +2140,21 @@ CREATE INDEX index_activity_pub_actors_on_instance_id ON public.activity_pub_act -- Name: index_activity_pub_actors_on_uri; Type: INDEX; Schema: public; Owner: - -- -CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USING btree (uri); +CREATE UNIQUE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USING btree (uri); -- -- Name: index_activity_pub_instances_on_hostname; Type: INDEX; Schema: public; Owner: - -- -CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname); +CREATE UNIQUE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname); + + +-- +-- Name: index_activity_pub_objects_on_uri; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX index_activity_pub_objects_on_uri ON public.activity_pub_objects USING btree (uri); -- @@ -2701,6 +2710,15 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240305164653'), ('20240305184854'), ('20240307201510'), -('20240307203039'); +('20240307203039'), +('20240313192134'), +('20240313204105'), +('20240314141536'), +('20240314153017'), +('20240314205923'), +('20240316203721'), +('20240318183846'), +('20240319124212'), +('20240319144735'); From 029d4e7c974914e9b17b871362be599440d1bc0b Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 13:01:26 -0300 Subject: [PATCH 708/814] fix: object_id closes #15739 closes #15738 closes #15737 --- app/jobs/activity_pub/process_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index 4e278797..f3aeebb4 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -117,7 +117,7 @@ class ActivityPub site.actor_moderations.lock.find_or_create_by(actor: a) - ::ActivityPub::FetchJob.perform_later(site: site, actor: a.object) + ::ActivityPub::FetchJob.perform_later(site: site, object_id: a.object.id) end end From d33e7b37a14c4636a2dab745d40831ffc091448a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 13:16:28 -0300 Subject: [PATCH 709/814] fix: lock closes #15740 closes #15741 closes #15742 closes #15743 closes #15744 closes #15745 closes #15746 closes #15747 closes #15748 closes #15749 closes #15750 closes #15751 closes #15752 closes #15753 closes #15754 closes #15755 closes #15756 closes #15757 closes #15758 closes #15759 --- app/jobs/activity_pub/fetch_job.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index e0033439..73fc1c9f 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -30,7 +30,9 @@ class ActivityPub current_type = object.type content = FastJsonparser.parse(response.body) - object.lock.update!(content: content, type: ActivityPub::Object.type_from(content).name) + object.with_lock do + object.update!(content: content, type: ActivityPub::Object.type_from(content).name) + end object = ::ActivityPub::Object.find(object_id) # Actualiza la mención From 1ef7996ce90eacea7448293e7f0a29192ee1f1b6 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 13:21:41 -0300 Subject: [PATCH 710/814] fix: agrupar errores para que no nos inunden --- config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 5e089ff9..bc7cecd7 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -142,7 +142,7 @@ Rails.application.configure do } config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl") } - config.middleware.use ExceptionNotification::Rack, gitlab: {}, ignore_exceptions: ['DeployJob::DeployAlreadyRunningException'] + config.middleware.use ExceptionNotification::Rack, gitlab: {}, error_grouping: true, ignore_exceptions: ['DeployJob::DeployAlreadyRunningException'] Rails.application.routes.default_url_options[:host] = "panel.#{ENV.fetch('SUTTY', 'sutty.nl')}" Rails.application.routes.default_url_options[:protocol] = 'https' From eafa6fad37cdb15a973f8fc0f3751044c2bab9cc Mon Sep 17 00:00:00 2001 From: f Date: Tue, 19 Mar 2024 17:02:19 -0300 Subject: [PATCH 711/814] fix: cargar el objeto por id y modificarlo closes #15775 closes #15773 closes #15772 closes #15771 closes #15770 closes #15767 closes #15766 closes #15765 closes #15764 --- app/jobs/activity_pub/fetch_job.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 73fc1c9f..b19d5e41 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -30,9 +30,8 @@ class ActivityPub current_type = object.type content = FastJsonparser.parse(response.body) - object.with_lock do - object.update!(content: content, type: ActivityPub::Object.type_from(content).name) - end + # Modificar atómicamente + ::ActivityPub::Object.lock.find(object_id).update!(content: content, type: ActivityPub::Object.type_from(content).name) object = ::ActivityPub::Object.find(object_id) # Actualiza la mención From 28053b2a5676427deed9097717b69ed7bbd7f682 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Mar 2024 16:18:01 -0300 Subject: [PATCH 712/814] =?UTF-8?q?fix:=20las=20cuentas=20reportadas=20tam?= =?UTF-8?q?bi=C3=A9n=20est=C3=A1n=20bloqueadas=20#15649?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/sync_lists_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/sync_lists_job.rb b/app/jobs/activity_pub/sync_lists_job.rb index cc500bee..de71fe64 100644 --- a/app/jobs/activity_pub/sync_lists_job.rb +++ b/app/jobs/activity_pub/sync_lists_job.rb @@ -18,7 +18,7 @@ class ActivityPub instance_scope = site.instance_moderations.joins(:instance) actor_scope = site.actor_moderations.joins(:actor) - blocklist = wildcardize(instance_scope.blocked.pluck(:hostname)) + actor_scope.blocked.distinct.pluck(:mention).compact + blocklist = wildcardize(instance_scope.blocked.pluck(:hostname)) + actor_scope.blocked.distinct.pluck(:mention).compact + actor_scope.reported.distinct.pluck(:mention).compact allowlist = wildcardize(instance_scope.allowed.pluck(:hostname)) + actor_scope.allowed.distinct.pluck(:mention).compact pauselist = wildcardize(instance_scope.paused.pluck(:hostname)) + actor_scope.paused.distinct.pluck(:mention).compact From 0a1b86c11195af3a5ecaa2002173caa95bd0954e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Mar 2024 17:49:09 -0300 Subject: [PATCH 713/814] fix: se pueden rechazar comentarios luego de aprobarlos #15600 --- app/models/activity_pub.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 913ac67d..335121d2 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -128,7 +128,7 @@ class ActivityPub < ApplicationRecord # La actividad fue rechazada event :reject do - transitions from: %i[paused], to: :rejected + transitions from: %i[paused approved], to: :rejected after do ActivityPub::InboxJob.perform_later(site: site, activity: activities.first.uri, action: :reject) From 0578b03ee76f8094c1b7a9fa6ee4fbb491b2503c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Mar 2024 17:50:39 -0300 Subject: [PATCH 714/814] fix: reportar implicar bloquear #15600 --- app/models/activity_pub.rb | 5 +++-- app/models/actor_moderation.rb | 2 +- config/locales/en.yml | 4 ++-- config/locales/es.yml | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index 335121d2..cd893406 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -135,11 +135,12 @@ class ActivityPub < ApplicationRecord end end - # Solo podemos reportarla luego de rechazarla + # Reportarla implica rechazarla event :report do - transitions from: :rejected, to: :reported + transitions from: %i[paused approved rejected], to: :reported after do + ActivityPub::InboxJob.perform_later(site: site, activity: activities.first.uri, action: :reject) ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? end end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 18149be4..1c3cf83a 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -43,7 +43,7 @@ class ActorModeration < ApplicationRecord # Al reportar, necesitamos asociar una RemoteFlag para poder # enviarla. event :report do - transitions from: %i[blocked], to: :reported + transitions from: %i[pause allowed blocked], to: :reported, after: :synchronize! after do ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting? diff --git a/config/locales/en.yml b/config/locales/en.yml index 35b857e6..643effaf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,7 +106,7 @@ en: text_reject: Reject text_reply: Reply text_report: Report - confirm_report: "Send report to the remote instance?" + confirm_report: "Send report to the remote instance? This action will also reject the comment." instances_btn_box: text_pause: Check case by case text_allow: Allow everything @@ -116,7 +116,7 @@ en: text_allow: Always approve text_block: Block text_report: Report - confirm_report: "Send report to the remote instance?" + confirm_report: "Send report to the remote instance? This action will also block the account." remote_flags: report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." activity_pubs: diff --git a/config/locales/es.yml b/config/locales/es.yml index 77e611ed..b8bfc524 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -105,7 +105,7 @@ es: text_approve: Aceptar text_reject: Rechazar text_report: Reportar - confirm_report: "¿Enviar el reporte a la instancia remota?" + confirm_report: "¿Enviar el reporte a la instancia remota? Esta acción también rechazará el comentario." instances_btn_box: text_pause: Moderar caso por caso text_allow: Permitir todo @@ -115,7 +115,7 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar - confirm_report: "¿Enviar el reporte a la instancia remota?" + confirm_report: "¿Enviar el reporte a la instancia remota? Esta acción también bloqueará la cuenta." remote_flags: report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." activity_pubs: From e2fdce91f3b2cbfa110559ac2e0b01ef0333ab21 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Mar 2024 17:51:23 -0300 Subject: [PATCH 715/814] fix: agrupar espacialmente acciones #15600 --- app/views/components/_comments_filters.haml | 2 +- app/views/components/_instances_filters.haml | 2 +- app/views/components/_profiles_filters.haml | 2 +- app/views/moderation_queue/_comment.haml | 2 +- config/locales/en.yml | 6 +++--- config/locales/es.yml | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/components/_comments_filters.haml b/app/views/components/_comments_filters.haml index cf8c1aa2..b2870c5a 100644 --- a/app/views/components/_comments_filters.haml +++ b/app/views/components/_comments_filters.haml @@ -3,7 +3,7 @@ - current_state = params[:activity_pub_state]&.to_sym || ActivityPub.states.first -.d-flex.py-2 +.d-flex.flex-row.justify-content-between.py-2 - if ActivityPub.transitionable_events(current_state).present? = render 'components/dropdown', text: t('.text_checked') do = render 'components/comments_checked_submenu', form: form diff --git a/app/views/components/_instances_filters.haml b/app/views/components/_instances_filters.haml index 730184bd..f2296c7b 100644 --- a/app/views/components/_instances_filters.haml +++ b/app/views/components/_instances_filters.haml @@ -3,7 +3,7 @@ - current_state = params[:state]&.to_sym || InstanceModeration.states.first -.d-flex.py-2 +.d-flex.flex-row.justify-content-between.py-2 - if InstanceModeration.transitionable_events(current_state).present? = render 'components/dropdown', text: t('.text_checked') do = render 'components/instances_checked_submenu', form: form, current_state: current_state diff --git a/app/views/components/_profiles_filters.haml b/app/views/components/_profiles_filters.haml index 3f830ec8..c2670944 100644 --- a/app/views/components/_profiles_filters.haml +++ b/app/views/components/_profiles_filters.haml @@ -3,7 +3,7 @@ - current_state = params[:actor_state]&.to_sym || ActorModeration.states.first -.d-flex.py-2 +.d-flex.flex-row.justify-content-between.py-2 - if ActorModeration.transitionable_events(current_state).present? = render 'components/dropdown', text: t('.text_checked') do = render 'components/profiles_checked_submenu', form: form, current_state: current_state diff --git a/app/views/moderation_queue/_comment.haml b/app/views/moderation_queue/_comment.haml index 10f09106..a80bd27c 100644 --- a/app/views/moderation_queue/_comment.haml +++ b/app/views/moderation_queue/_comment.haml @@ -38,7 +38,7 @@ %dd.d-inline %small %a{ href: in_reply_to }= in_reply_to - .content + .content.mb-3 - if summary.present? = render 'layouts/details', summary: summary, summary_class: 'h5' do = sanitize comment['content'] diff --git a/config/locales/en.yml b/config/locales/en.yml index 643effaf..8059b6db 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -63,7 +63,7 @@ en: instances_blocked: Instances blocked instances_filters: text_show: Show - text_checked: With selected + text_checked: With selected... instances_checked_submenu: submenu_pause: Moderate submenu_allow: Allow @@ -74,7 +74,7 @@ en: submenu_blocked: "Blocked (%{count})" comments_filters: text_show: Show - text_checked: With selected + text_checked: With selected... comments_checked_submenu: submenu_pause: Pause submenu_approve: Approve @@ -87,7 +87,7 @@ en: submenu_reported: "Reported (%{count})" profiles_filters: text_show: Show - text_checked: With selected + text_checked: With selected... profiles_checked_submenu: submenu_pause: Pause submenu_allow: Allow diff --git a/config/locales/es.yml b/config/locales/es.yml index b8bfc524..06b933bc 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -63,7 +63,7 @@ es: instances_blocked: Instancias bloqueadas instances_filters: text_show: Ver - text_checked: Con los marcados + text_checked: Con los marcados... instances_checked_submenu: submenu_pause: Moderar caso por caso submenu_allow: Permitir todo @@ -74,7 +74,7 @@ es: submenu_blocked: "Bloqueadas (%{count})" comments_filters: text_show: Ver - text_checked: Con los marcados + text_checked: Con los marcados... comments_checked_submenu: submenu_pause: Pausar submenu_approve: Aprobar @@ -87,7 +87,7 @@ es: submenu_reported: "Reportados (%{count})" profiles_filters: text_show: Ver - text_checked: Con los marcados + text_checked: Con los marcados... profiles_checked_submenu: submenu_pause: Pausar submenu_allow: Aceptar From eda075fd4b889707328c2c62bcc6ac47984944ee Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Mar 2024 17:52:31 -0300 Subject: [PATCH 716/814] =?UTF-8?q?fix:=20la=20acci=C3=B3n=20no=20se=20pue?= =?UTF-8?q?de=20hacer=20porque=20es=20el=20estado=20actual=20#15600?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_btn_base.haml | 1 - app/views/components/_comments_btn_box.haml | 4 +++- app/views/components/_instances_btn_box.haml | 5 +++-- app/views/components/_profiles_btn_box.haml | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/views/components/_btn_base.haml b/app/views/components/_btn_base.haml index faa5c85f..fed3254c 100644 --- a/app/views/components/_btn_base.haml +++ b/app/views/components/_btn_base.haml @@ -1,7 +1,6 @@ -# Componente Botón general Moderación - local_assigns[:method] ||= 'patch' -- local_assigns[:class] ||= 'btn-secondary' - local_assigns[:class] = "btn #{local_assigns[:class]}" - local_assigns.delete(:text) diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 1993e5cb..ffc773a7 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -4,8 +4,10 @@ .d-flex.flex-row - ActivityPub.events.each do |event| + - possible = activity_pub.public_send(:"may_#{event}?") = render 'components/btn_base', text: t(".text_#{event}"), path: public_send(:"site_activity_pub_#{event}_path", activity_pub_id: activity_pub), - disabled: !activity_pub.public_send(:"may_#{event}?"), + class: ('btn-secondary' if possible), + disabled: !possible, data: local_data[event] diff --git a/app/views/components/_instances_btn_box.haml b/app/views/components/_instances_btn_box.haml index 15c6c040..8c3a5f88 100644 --- a/app/views/components/_instances_btn_box.haml +++ b/app/views/components/_instances_btn_box.haml @@ -2,9 +2,10 @@ - local_data = {} - InstanceModeration.events.each do |event| + - possible = instance_moderation.public_send(:"may_#{event}?") = render 'components/btn_base', path: public_send(:"site_instance_moderation_#{event}_path", instance_moderation_id: instance_moderation), text: t(".text_#{event}"), - class: 'btn btn-secondary', - disabled: !instance_moderation.public_send(:"may_#{event}?"), + class: ('btn-secondary' if possible), + disabled: !possible, data: local_data[event] diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 488373b9..9414c178 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -2,9 +2,10 @@ .d-flex.flex-row - local_data = { report: { confirm: t('.confirm_report') } } - ActorModeration.events.each do |actor_event| + - possible = !actor_moderation.public_send(:"may_#{actor_event}?") = render 'components/btn_base', text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), - class: 'btn-secondary', - disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), + class: ('btn-secondary' if possible), + disabled: !possible, data: local_data[actor_event] From 8dae40cb0ebef8c9851b03467962d2bb6bffb724 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Mar 2024 17:53:00 -0300 Subject: [PATCH 717/814] fix: confirmar al rechazar #15600 --- app/views/components/_comments_btn_box.haml | 2 +- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index ffc773a7..19ea169c 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,6 +1,6 @@ -# Componente Botonera de Comentarios -- local_data = { report: { confirm: t('.confirm_report') } } +- local_data = { reject: { confirm: t('.confirm_reject') }, report: { confirm: t('.confirm_report') } } .d-flex.flex-row - ActivityPub.events.each do |event| diff --git a/config/locales/en.yml b/config/locales/en.yml index 8059b6db..c88f7b26 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -107,6 +107,7 @@ en: text_reply: Reply text_report: Report confirm_report: "Send report to the remote instance? This action will also reject the comment." + confirm_reject: "Reject this comment? Please notice we can't undo this action at this moment." instances_btn_box: text_pause: Check case by case text_allow: Allow everything diff --git a/config/locales/es.yml b/config/locales/es.yml index 06b933bc..695b4e60 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,6 +106,7 @@ es: text_reject: Rechazar text_report: Reportar confirm_report: "¿Enviar el reporte a la instancia remota? Esta acción también rechazará el comentario." + confirm_reject: "¿Rechazar este comentario? Tené en cuenta que por el momento no es posible deshacer esta acción." instances_btn_box: text_pause: Moderar caso por caso text_allow: Permitir todo From e05a8aafda806adadea1af6b95c5ed13b8d0565b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Mar 2024 11:14:36 -0300 Subject: [PATCH 718/814] fix: enviar los botones de reporte a la derecha #15600 --- app/views/components/_comments_btn_box.haml | 15 ++++++++------- app/views/components/_profiles_btn_box.haml | 17 +++++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/app/views/components/_comments_btn_box.haml b/app/views/components/_comments_btn_box.haml index 19ea169c..578f6662 100644 --- a/app/views/components/_comments_btn_box.haml +++ b/app/views/components/_comments_btn_box.haml @@ -1,13 +1,14 @@ -# Componente Botonera de Comentarios -- local_data = { reject: { confirm: t('.confirm_reject') }, report: { confirm: t('.confirm_report') } } +- local = { reject: { data: { confirm: t('.confirm_reject') } }, report: { class: 'ml-auto', data: { confirm: t('.confirm_report') } } } .d-flex.flex-row - ActivityPub.events.each do |event| - possible = activity_pub.public_send(:"may_#{event}?") - = render 'components/btn_base', - text: t(".text_#{event}"), - path: public_send(:"site_activity_pub_#{event}_path", activity_pub_id: activity_pub), - class: ('btn-secondary' if possible), - disabled: !possible, - data: local_data[event] + %div{ class: local.dig(event, :class) } + = render 'components/btn_base', + text: t(".text_#{event}"), + path: public_send(:"site_activity_pub_#{event}_path", activity_pub_id: activity_pub), + class: ('btn-secondary' if possible), + disabled: !possible, + data: local.dig(event, :data) diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 9414c178..8fc8dd39 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,11 +1,12 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) -.d-flex.flex-row - - local_data = { report: { confirm: t('.confirm_report') } } +.d-flex.flex-row.w-100 + - local = { report: { class: 'ml-auto', data: { confirm: t('.confirm_report') } } } - ActorModeration.events.each do |actor_event| - possible = !actor_moderation.public_send(:"may_#{actor_event}?") - = render 'components/btn_base', - text: t(".text_#{actor_event}"), - path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), - class: ('btn-secondary' if possible), - disabled: !possible, - data: local_data[actor_event] + %div{ class: local.dig(actor_event, :class) } + = render 'components/btn_base', + text: t(".text_#{actor_event}"), + path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), + class: ('btn-secondary' if possible), + disabled: !possible, + data: local.dig(actor_event, :data) From 2aa2b9f3bb5e0aecd5f7b256a3248adadbd25087 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Mar 2024 18:12:12 -0300 Subject: [PATCH 719/814] =?UTF-8?q?fix:=20poder=20ir=20a=20la=20cola=20de?= =?UTF-8?q?=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.scss | 16 ++++ .../moderation_queue_controller.rb | 3 + app/models/moderation_queue.rb | 3 + app/models/site/social_distributed_press.rb | 23 ++++++ app/policies/moderation_queue_policy.rb | 9 +++ app/views/posts/index.haml | 10 +-- app/views/sites/_moderation_queue.haml | 9 +++ app/views/sites/index.haml | 74 +++++++++---------- 8 files changed, 103 insertions(+), 44 deletions(-) create mode 100644 app/models/moderation_queue.rb create mode 100644 app/policies/moderation_queue_policy.rb create mode 100644 app/views/sites/_moderation_queue.haml diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index cdf97b5b..11c44d90 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -32,6 +32,22 @@ $sizes: ( @import "bootstrap"; @import "editor"; +@each $color, $rgb in $theme-colors { + .#{$color} { + color: var(--#{$color}); + + &:focus { + color: var(--#{$color}); + } + + ::-moz-selection, + ::selection { + background: var(--#{$color}); + color: white; + } + } +} + .editor { .editor-content { figure { diff --git a/app/controllers/moderation_queue_controller.rb b/app/controllers/moderation_queue_controller.rb index 4bd61e38..ef830c41 100644 --- a/app/controllers/moderation_queue_controller.rb +++ b/app/controllers/moderation_queue_controller.rb @@ -11,9 +11,12 @@ class ModerationQueueController < ApplicationController # Cola de moderación viendo todo el sitio def index + authorize ModerationQueue.new(site) breadcrumb site.title, site_posts_path(site) breadcrumb I18n.t('moderation_queue.index.title'), '' + site.moderation_checked! + # @todo cambiar el estado por query @activity_pubs = site.activity_pubs @instance_moderations = rubanok_process(site.instance_moderations, with: InstanceModerationProcessor) diff --git a/app/models/moderation_queue.rb b/app/models/moderation_queue.rb new file mode 100644 index 00000000..31ca3c9b --- /dev/null +++ b/app/models/moderation_queue.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +ModerationQueue = Struct.new(:site) diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 0716a670..8d8d60d4 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -19,6 +19,29 @@ class Site before_save :generate_private_key_pem!, unless: :private_key_pem? + def moderation_enabled? + deploy_social_inbox.present? + end + + def deploy_social_inbox + @deploy_social_inbox ||= deploys.find_by(type: 'DeploySocialDistributedPress') + end + + def moderation_checked! + deploy_social_inbox.touch + end + + # @return [Bool] + def moderation_needed? + return false unless moderation_enabled? + + last_activity_pub = activity_pubs.order(updated_at: :desc).first&.updated_at + + return false if last_activity_pub.blank? + + last_activity_pub > deploy_social_inbox.updated_at + end + # @return [SocialInbox] def social_inbox @social_inbox ||= SocialInbox.new(site: self) diff --git a/app/policies/moderation_queue_policy.rb b/app/policies/moderation_queue_policy.rb new file mode 100644 index 00000000..75a4c45a --- /dev/null +++ b/app/policies/moderation_queue_policy.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Si la cola de moderación está activada y le usuarie tiene permisos de +# usuarie. +ModerationQueuePolicy = Struct.new(:usuarie, :moderation_queue) do + def index? + moderation_queue.site.moderation_enabled? && moderation_queue.site.usuarie?(usuarie) + end +end diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 69fb2d8f..6d77b75d 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -1,10 +1,10 @@ %main.row %aside.menu.col-md-3 - = render 'sites/header', site: @site - - = render 'sites/status', site: @site - - = render 'sites/build', site: @site, class: 'btn-block' + .mb-3 + = render 'sites/header', site: @site + = render 'sites/status', site: @site + = render 'sites/build', site: @site, class: 'btn-block' + = render 'sites/moderation_queue', site: @site, class: 'btn-block' %h3= t('posts.new') %table.table.table-sm.mb-3 diff --git a/app/views/sites/_moderation_queue.haml b/app/views/sites/_moderation_queue.haml new file mode 100644 index 00000000..6b39d797 --- /dev/null +++ b/app/views/sites/_moderation_queue.haml @@ -0,0 +1,9 @@ +- if policy(ModerationQueue.new(site)).index? + - moderation_needed = site.moderation_needed? + + - local_assigns[:class] = "btn btn-secondary #{local_assigns[:class]}" + = link_to site_moderation_queue_path(site), class: local_assigns[:class], title: (t('.moderation_needed') if moderation_needed) do + = t('moderation_queue.index.title') + - if moderation_needed + %span.primary ⏺ + %span.sr-only= t('.moderation_needed') diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index ed87180a..fc8184e1 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -15,43 +15,39 @@ %tbody - @sites.each do |site| - next unless site.jekyll? - - rol = current_usuarie.rol_for_site(site) - -# - TODO: Solo les usuaries cachean porque tenemos que separar - les botones por permisos. - - cache_if (rol.usuarie? && !rol.temporal), [site, I18n.locale] do - %tr - %td - %h2 - - if policy(site).show? - = link_to site.title, site_posts_path(site, locale: site.default_locale) - - else - = site.title - %p.lead= site.description - %br - = link_to t('.visit'), site.url, class: 'btn btn-secondary' - - if rol.temporal - = button_to t('sites.invitations.accept'), - site_usuaries_accept_invitation_path(site), - method: :patch, - title: t('help.sites.invitations.accept'), - class: 'btn btn-secondary' - = button_to t('sites.invitations.reject'), - site_usuaries_reject_invitation_path(site), - method: :patch, - title: t('help.sites.invitations.reject'), - class: 'btn btn-secondary' + %tr + %td + %h2 + - if policy(site).show? + = link_to site.title, site_posts_path(site, locale: site.default_locale) - 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') - - 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) - = render 'sites/build', site: site + = 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) From ad637189b542a386ba6c09908b0cb59d20a2b91f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Mar 2024 18:25:36 -0300 Subject: [PATCH 720/814] =?UTF-8?q?fixup!=20fix:=20poder=20ir=20a=20la=20c?= =?UTF-8?q?ola=20de=20moderaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index c88f7b26..f024fa98 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -573,6 +573,8 @@ en: column: "Country" empty: "(couldn't detect country)" sites: + moderation_queue: + moderation_needed: "There are new activities pending revision since the last time you moderated." donations: url: 'https://donaciones.sutty.nl/en/' text: 'Support us' diff --git a/config/locales/es.yml b/config/locales/es.yml index 695b4e60..204a3587 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -577,6 +577,8 @@ es: column: "País" empty: "(no se pudo detectar el país)" sites: + moderation_queue: + moderation_needed: "Hay actividades pendientes de revisión desde la última vez que moderaste." donations: url: 'https://donaciones.sutty.nl/' text: 'Apoyá nuestro trabajo' From 48532633740028bf406d2bd7ca97ab85f9c076bd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 11:53:23 -0300 Subject: [PATCH 721/814] fix: pedir locks antes de guardar closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 closes #15735 closes #15736 --- app/jobs/activity_pub/process_job.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index f3aeebb4..bd010613 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -66,6 +66,7 @@ class ActivityPub @object ||= ::ActivityPub::Object.lock.find_or_initialize_by(uri: object_uri).tap do |o| o.content = original_object if object_embedded? + o.lock! o.save! # XXX: el objeto necesita ser guardado antes de poder @@ -95,6 +96,7 @@ class ActivityPub .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup a.content[:object] = object.uri + a.lock! a.save! end end @@ -113,6 +115,7 @@ class ActivityPub site.instance_moderations.lock.find_or_create_by(instance: a.instance) + a.lock! a.save! site.actor_moderations.lock.find_or_create_by(actor: a) From 0561b022de3eb01d747c4379590904087385f8c2 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 11:57:22 -0300 Subject: [PATCH 722/814] fix: no fallar si no hay registros sobre los que actuar #15725 --- app/controllers/activity_pubs_controller.rb | 6 ++++-- app/controllers/actor_moderations_controller.rb | 6 ++++-- app/controllers/instance_moderations_controller.rb | 6 ++++-- app/policies/instance_moderation_policy.rb | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/controllers/activity_pubs_controller.rb b/app/controllers/activity_pubs_controller.rb index d5041a84..428d5cb1 100644 --- a/app/controllers/activity_pubs_controller.rb +++ b/app/controllers/activity_pubs_controller.rb @@ -29,16 +29,18 @@ class ActivityPubsController < ApplicationController end def action_on_several + redirect_to_moderation_queue! + activity_pubs = site.activity_pubs.where(id: params[:activity_pub]) + return if activity_pubs.count.zero? + authorize activity_pubs action = params[:activity_pub_action].to_sym method = :"#{action}_all!" may = :"may_#{action}?" - redirect_to_moderation_queue! - return unless ActivityPub.events.include? action # Crear una sola remote flag por autore diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index 739b1f46..04d2603b 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -48,16 +48,18 @@ class ActorModerationsController < ApplicationController end def action_on_several + redirect_to_moderation_queue! + actor_moderations = site.actor_moderations.where(id: params[:actor_moderation]) + return if actor_moderations.count.zero? + authorize actor_moderations action = params[:actor_moderation_action].to_sym method = :"#{action}_all!" may = :"may_#{action}?" - redirect_to_moderation_queue! - return unless ActorModeration.events.include? action ActorModeration.transaction do diff --git a/app/controllers/instance_moderations_controller.rb b/app/controllers/instance_moderations_controller.rb index 13d7f428..de990eb1 100644 --- a/app/controllers/instance_moderations_controller.rb +++ b/app/controllers/instance_moderations_controller.rb @@ -22,15 +22,17 @@ class InstanceModerationsController < ApplicationController end def action_on_several + redirect_to_moderation_queue! + instance_moderations = site.instance_moderations.where(id: params[:instance_moderation]) + return if instance_moderations.count.zero? + authorize instance_moderations action = params[:instance_moderation_action].to_sym method = :"#{action}_all!" - redirect_to_moderation_queue! - return unless InstanceModeration.events.include? action InstanceModeration.transaction do diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb index 13ebfeca..c54eb4b8 100644 --- a/app/policies/instance_moderation_policy.rb +++ b/app/policies/instance_moderation_policy.rb @@ -11,6 +11,6 @@ InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do # En este paso tenemos varias instancias por moderar pero todas son # del mismo sitio. def action_on_several? - instance_moderation.first.site.usuarie? usuarie + instance_moderation.first.presence && instance_moderation.first.site.usuarie? usuarie end end From cc654be121986126642308d68c0b9fdbb6cdb4a3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 12:01:08 -0300 Subject: [PATCH 723/814] fixup! fix: no fallar si no hay registros sobre los que actuar #15725 --- app/policies/instance_moderation_policy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/policies/instance_moderation_policy.rb b/app/policies/instance_moderation_policy.rb index c54eb4b8..c6a229d3 100644 --- a/app/policies/instance_moderation_policy.rb +++ b/app/policies/instance_moderation_policy.rb @@ -11,6 +11,6 @@ InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do # En este paso tenemos varias instancias por moderar pero todas son # del mismo sitio. def action_on_several? - instance_moderation.first.presence && instance_moderation.first.site.usuarie? usuarie + instance_moderation.first.presence && instance_moderation.first.site.usuarie?(usuarie) end end From b6fdc8a5801ebacee50eb0b522a374ca4ac3aa52 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 12:38:54 -0300 Subject: [PATCH 724/814] =?UTF-8?q?fix:=20permitir=20hostnames=20num=C3=A9?= =?UTF-8?q?ricos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15789 --- app/models/activity_pub/instance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/activity_pub/instance.rb b/app/models/activity_pub/instance.rb index 749d98ac..cd14ef23 100644 --- a/app/models/activity_pub/instance.rb +++ b/app/models/activity_pub/instance.rb @@ -9,7 +9,7 @@ class ActivityPub include AASM validates :aasm_state, presence: true, inclusion: { in: %w[paused allowed blocked] } - validates :hostname, uniqueness: true, hostname: true + validates :hostname, uniqueness: true, hostname: { allow_numeric_hostname: true } has_many :activity_pubs has_many :actors From 5db263ef6c65450ae997e26a9ba9951f7ea859aa Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 12:54:27 -0300 Subject: [PATCH 725/814] fix: recordar que hay que volver a correr la tarea manualmente #15789 --- app/jobs/activity_pub/process_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index bd010613..94799735 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -28,7 +28,7 @@ class ActivityPub # Al generar una excepción, en lugar de seguir intentando, enviamos # el reporte. rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, activity: original_activity }) + ExceptionNotifier.notify_exception(e, data: { site: site.name, body: body, initial_state: initial_state, activity: original_activity, message: 'Esta acción se canceló automáticamente, para regenerarla, volver a correr el proceso con los mismos parámetros.' }) end private From dad5f5f00ce99d9b724853b6eaaa1ea0a0be70b8 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 13:06:58 -0300 Subject: [PATCH 726/814] =?UTF-8?q?fix:=20solo=20bloquear=20cuando=20ya=20?= =?UTF-8?q?est=C3=A1=20en=20la=20base=20de=20datos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15791 --- app/jobs/activity_pub/process_job.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index 94799735..9b7c30fc 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -66,7 +66,7 @@ class ActivityPub @object ||= ::ActivityPub::Object.lock.find_or_initialize_by(uri: object_uri).tap do |o| o.content = original_object if object_embedded? - o.lock! + o.lock! if o.persisted? o.save! # XXX: el objeto necesita ser guardado antes de poder @@ -96,7 +96,7 @@ class ActivityPub .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| a.content = original_activity.dup a.content[:object] = object.uri - a.lock! + a.lock! if o.persisted? a.save! end end @@ -115,7 +115,7 @@ class ActivityPub site.instance_moderations.lock.find_or_create_by(instance: a.instance) - a.lock! + a.lock! if o.persisted? a.save! site.actor_moderations.lock.find_or_create_by(actor: a) From 071f20762c3ed2d435ed5351d5b9b5cd937865e5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 13:09:13 -0300 Subject: [PATCH 727/814] fix: bloquear antes de empezar a modificar closes #15791 --- app/jobs/activity_pub/process_job.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index 9b7c30fc..a79abf5d 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -64,9 +64,9 @@ class ActivityPub # @return [ActivityPub::Object] def object @object ||= ::ActivityPub::Object.lock.find_or_initialize_by(uri: object_uri).tap do |o| + o.lock! if o.persisted? o.content = original_object if object_embedded? - o.lock! if o.persisted? o.save! # XXX: el objeto necesita ser guardado antes de poder @@ -94,9 +94,9 @@ class ActivityPub .type_from(original_activity) .lock .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| + a.lock! if o.persisted? a.content = original_activity.dup a.content[:object] = object.uri - a.lock! if o.persisted? a.save! end end @@ -107,6 +107,8 @@ class ActivityPub # @return [Actor] def actor @actor ||= ::ActivityPub::Actor.lock.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| + a.lock! if o.persisted? + unless a.instance a.instance = ::ActivityPub::Instance.lock.find_or_create_by(hostname: URI.parse(a.uri).hostname) @@ -114,8 +116,6 @@ class ActivityPub end site.instance_moderations.lock.find_or_create_by(instance: a.instance) - - a.lock! if o.persisted? a.save! site.actor_moderations.lock.find_or_create_by(actor: a) From dbf15397e53de6ce46f148a1be61ef98ab6fefb8 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 15:44:28 -0300 Subject: [PATCH 728/814] fix: mostrar los desplegables como accionables #15600 --- app/views/components/_dropdown.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_dropdown.haml b/app/views/components/_dropdown.haml index 54ddcffb..6f34950b 100644 --- a/app/views/components/_dropdown.haml +++ b/app/views/components/_dropdown.haml @@ -11,7 +11,7 @@ controller: 'dropdown' } } - %button.btn.dropdown-toggle{ + %button.btn.btn-outline-secondary.dropdown-toggle{ type: 'button', class: button_classes, data: { From 07fd2cff930d26e33e8e3ac3fb3307554a3166b0 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 17:31:53 -0300 Subject: [PATCH 729/814] fix: usar locks en moderaciones de instancia closes #15788 --- app/jobs/activity_pub/instance_moderation_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/instance_moderation_job.rb b/app/jobs/activity_pub/instance_moderation_job.rb index 00100abf..9da0627f 100644 --- a/app/jobs/activity_pub/instance_moderation_job.rb +++ b/app/jobs/activity_pub/instance_moderation_job.rb @@ -9,7 +9,7 @@ class ActivityPub def perform(site:, hostnames:, perform_remotely: true) # Crear las instancias que no existan todavía hostnames.each do |hostname| - ActivityPub::Instance.find_or_create_by(hostname: hostname) + ActivityPub::Instance.lock.find_or_create_by(hostname: hostname) end instances = ActivityPub::Instance.where(hostname: hostnames) @@ -20,7 +20,7 @@ class ActivityPub instances.find_each do |instance| # Esto bloquea cada una individualmente en la Social Inbox, # idealmente son pocas instancias las que aparecen. - site.instance_moderations.find_or_create_by(instance: instance) + site.instance_moderations.lock.find_or_create_by(instance: instance) end scope = site.instance_moderations.where(instance_id: instances.ids) From 366494b61535358b6fecaa13482ff3dde10358af Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 18:28:34 -0300 Subject: [PATCH 730/814] fix: typo closes #15792 closes #15793 closes #15794 closes #15795 closes #15796 closes #15797 closes #15798 closes #15799 closes #15800 closes #15801 closes #15802 closes #15803 closes #15804 closes #15805 closes #15806 closes #15807 closes #15808 closes #15809 closes #15810 closes #15811 closes #15812 closes #15813 closes #15814 closes #15815 closes #15816 closes #15817 closes #15818 --- app/jobs/activity_pub/process_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index a79abf5d..af686dbd 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -94,7 +94,7 @@ class ActivityPub .type_from(original_activity) .lock .find_or_initialize_by(uri: original_activity[:id], activity_pub: activity_pub, actor: actor).tap do |a| - a.lock! if o.persisted? + a.lock! if a.persisted? a.content = original_activity.dup a.content[:object] = object.uri a.save! @@ -107,7 +107,7 @@ class ActivityPub # @return [Actor] def actor @actor ||= ::ActivityPub::Actor.lock.find_or_initialize_by(uri: original_activity[:actor]).tap do |a| - a.lock! if o.persisted? + a.lock! if a.persisted? unless a.instance a.instance = ::ActivityPub::Instance.lock.find_or_create_by(hostname: URI.parse(a.uri).hostname) From fb38600884faffea66a9ff832d854fec3eb5dc03 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 18:34:24 -0300 Subject: [PATCH 731/814] =?UTF-8?q?feat:=20recargar=20autom=C3=A1ticamente?= =?UTF-8?q?=20el=20estado=20de=20publicaci=C3=B3n=20#13611?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/sites_controller.rb | 7 +++++ app/javascript/packs/application.js | 2 ++ app/views/sites/_status.haml | 41 ++++++++++++++++------------- app/views/sites/status.haml | 1 + config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- config/routes.rb | 2 ++ package.json | 3 ++- yarn.lock | 5 ++++ 9 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 app/views/sites/status.haml diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index bec42b39..49527cf7 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -15,6 +15,13 @@ class SitesController < ApplicationController fresh_when @sites end + # Genera la caja del estado para HTMX + def status + authorize site + + render('sites/status', layout: false) if stale? site + end + # No tenemos propiedades de un sitio aún, así que vamos al listado de # artículos def show diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 9cbc30bf..9ddc9753 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -33,3 +33,5 @@ import 'chartkick/chart.js' Rails.start() Turbolinks.start() ActiveStorage.start() + +window.htmx = require('htmx.org/dist/htmx') diff --git a/app/views/sites/_status.haml b/app/views/sites/_status.haml index 6a610e73..47bed657 100644 --- a/app/views/sites/_status.haml +++ b/app/views/sites/_status.haml @@ -1,21 +1,24 @@ -- link = nil -- if site.not_published_yet? - - message = t('.not_published_yet') -- elsif site.awaiting_publication? - - message = t('.awaiting_publication') -- elsif site.building? - - if site.average_publication_time_calculable? - - average_building_time = site.average_publication_time - - elsif !site.similar_sites? - - average_building_time = 60 +- cache site do + - link = nil + - if site.not_published_yet? + - message = t('.not_published_yet') + - elsif site.awaiting_publication? + - message = t('.awaiting_publication') + - elsif site.building? + - if site.average_publication_time_calculable? + - average_building_time = site.average_publication_time + - elsif !site.similar_sites? + - average_building_time = 60 + - else + - average_building_time = site.average_publication_time_for_similar_sites + + - average_publication_time_human = distance_of_time_in_words average_building_time + - message = t('.building', average_time: average_publication_time_human, seconds: average_building_time) - else - - average_building_time = site.average_publication_time_for_similar_sites + - message = t('.available') + - link = true - - average_publication_time_human = distance_of_time_in_words average_building_time - - message = t('.building', average_time: average_publication_time_human, seconds: average_building_time) -- else - - message = t('.available') - - link = true - -= render 'bootstrap/alert' do - = link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link' + -# TODO: Calcular cada cuanto sería óptimo recargar + %div{ 'hx-get': site_status_path(site), 'hx-trigger': 'every 10s', 'hx-swap': 'outerHTML' } + = render 'bootstrap/alert' do + = link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link' diff --git a/app/views/sites/status.haml b/app/views/sites/status.haml new file mode 100644 index 00000000..3d9793a5 --- /dev/null +++ b/app/views/sites/status.haml @@ -0,0 +1 @@ += render 'sites/status', site: @site diff --git a/config/locales/en.yml b/config/locales/en.yml index fc9d4894..720f784a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -389,7 +389,7 @@ en: static_file_migration: 'File migration' find_and_replace: 'Search and replace' status: - building: "Your site is building, refresh this page in ." + building: "Your site is building, it will be ready in ." not_published_yet: "Your site is being published for the first time, please wait up to 1 minute..." available: "Your site is available! Click here to find all the different ways to visit it." awaiting_publication: "There are unpublished changes. Click the button below and wait a moment to find them on your site." diff --git a/config/locales/es.yml b/config/locales/es.yml index 4bda4982..e7ff0864 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -394,7 +394,7 @@ es: static_file_migration: 'Migración de archivos' find_and_replace: 'Búsqueda y reemplazo' status: - building: "Tu sitio se está publicando, recargá esta página en ." + building: "Tu sitio se está publicando, estará listo en ." not_published_yet: "Tu sitio se está publicando por primera vez, por favor espera hasta un minuto..." available: "¡Tu sitio está disponible! Cliqueá aquí para encontrar todas las formas en que podés visitarlo." awaiting_publication: "Hay cambios sin publicar, cliqueá el botón debajo y espera un momento para encontrarlos en tu sitio." diff --git a/config/routes.rb b/config/routes.rb index 635be07a..557439e9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -37,6 +37,8 @@ Rails.application.routes.draw do get 'pull', to: 'sites#fetch' post 'pull', to: 'sites#merge' + get 'status', to: 'sites#status' + # Gestionar usuaries get 'usuaries/invite', to: 'usuaries#invite' post 'usuaries/invite', to: 'usuaries#send_invitations' diff --git a/package.json b/package.json index 7901ad41..871c9d9b 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "zepto": "^1.2.0" }, "devDependencies": { - "@types/rails__activestorage": "^6.0.0" + "@types/rails__activestorage": "^6.0.0", + "htmx.org": "^1.9.11" } } diff --git a/yarn.lock b/yarn.lock index 0c52b9d3..4619169e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4548,6 +4548,11 @@ html-entities@^1.3.1: resolved "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz" integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== +htmx.org@^1.9.11: + version "1.9.11" + resolved "https://registry.yarnpkg.com/htmx.org/-/htmx.org-1.9.11.tgz#00192041ee682d6ca7146d0fbd901169ffe72d87" + integrity sha512-WlVuICn8dfNOOgYmdYzYG8zSnP3++AdHkMHooQAzGZObWpVXYathpz/I37ycF4zikR6YduzfCvEcxk20JkIUsw== + http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" From 736f0552f73e9a88a81552da1725b87dfeea33e4 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 18:46:21 -0300 Subject: [PATCH 732/814] =?UTF-8?q?fix:=20poder=20importar=20htmx=20en=20p?= =?UTF-8?q?roducci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/packs/application.js | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 9ddc9753..d8ff0dd1 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -34,4 +34,4 @@ Rails.start() Turbolinks.start() ActiveStorage.start() -window.htmx = require('htmx.org/dist/htmx') +window.htmx = require('htmx.org/dist/htmx.js') diff --git a/package.json b/package.json index 871c9d9b..870b8e9b 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "commonmark": "^0.29.0", "fork-awesome": "^1.1.7", "fork-ts-checker-webpack-plugin": "^6.1.0", + "htmx.org": "^1.9.11", "input-map": "git+https://0xacab.org/sutty/input-map.git", "input-tag": "git+https://0xacab.org/sutty/input-tag.git", "leaflet": "^1.7.1", @@ -34,7 +35,6 @@ "zepto": "^1.2.0" }, "devDependencies": { - "@types/rails__activestorage": "^6.0.0", - "htmx.org": "^1.9.11" + "@types/rails__activestorage": "^6.0.0" } } From 95231511b78243dede6c4cab52ab6116fb145a54 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Mar 2024 18:54:18 -0300 Subject: [PATCH 733/814] fix: poder ver el estado --- app/policies/site_policy.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/policies/site_policy.rb b/app/policies/site_policy.rb index 2ca96256..d5465d6b 100644 --- a/app/policies/site_policy.rb +++ b/app/policies/site_policy.rb @@ -14,6 +14,10 @@ class SitePolicy true end + def status? + true + end + # Puede ver la versión privada del sitio? def private? edit? && site.deploys.find_by_type('DeployPrivate') From 1128f0495436777e95af4fcccbafde34ea4845db Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 12:42:15 -0300 Subject: [PATCH 734/814] =?UTF-8?q?fix:=20mostrar=20los=20botones=20de=20i?= =?UTF-8?q?nvitaci=C3=B3n=20en=20una=20sola=20l=C3=ADnea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/sites/index.haml | 53 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index ed87180a..f771be3b 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -29,29 +29,30 @@ = site.title %p.lead= site.description %br - = link_to t('.visit'), site.url, class: 'btn btn-secondary' - - if rol.temporal - = button_to t('sites.invitations.accept'), - site_usuaries_accept_invitation_path(site), - method: :patch, - title: t('help.sites.invitations.accept'), - class: 'btn btn-secondary' - = button_to t('sites.invitations.reject'), - site_usuaries_reject_invitation_path(site), - method: :patch, - title: t('help.sites.invitations.reject'), - class: 'btn 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') - - 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) - = render 'sites/build', site: site + .d-flex.flex-row + = link_to t('.visit'), site.url, class: 'btn btn-secondary' + - if rol.temporal + = button_to t('sites.invitations.accept'), + site_usuaries_accept_invitation_path(site), + method: :patch, + title: t('help.sites.invitations.accept'), + class: 'btn btn-secondary' + = button_to t('sites.invitations.reject'), + site_usuaries_reject_invitation_path(site), + method: :patch, + title: t('help.sites.invitations.reject'), + class: 'btn 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') + - 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) + = render 'sites/build', site: site From 316b192d1e2bb5b504d9edfbba43de206c74404f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 12:42:26 -0300 Subject: [PATCH 735/814] fix: poder aceptar o rechazar invitaciones #15154 --- app/policies/site_usuarie_policy.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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? From d7de351e1af36ab1383d2cf0c4e8f040fef6a686 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 13:32:08 -0300 Subject: [PATCH 736/814] fix: espaciar el procesamiento de tareas closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 closes #15735 closes #15736 closes #15824 --- .../api/v1/webhooks/social_inbox_controller.rb | 4 +++- app/jobs/application_job.rb | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks/social_inbox_controller.rb b/app/controllers/api/v1/webhooks/social_inbox_controller.rb index 6ac91a51..9d215812 100644 --- a/app/controllers/api/v1/webhooks/social_inbox_controller.rb +++ b/app/controllers/api/v1/webhooks/social_inbox_controller.rb @@ -49,7 +49,9 @@ module Api # # @param initial_state [Symbol] def process!(initial_state) - ::ActivityPub::ProcessJob.perform_later(site: site, body: request.raw_post, initial_state: initial_state) + ::ActivityPub::ProcessJob + .set(wait: ApplicationJob.random_wait) + .perform_later(site: site, body: request.raw_post, initial_state: initial_state) end end end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 06690c53..1bf20345 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -4,6 +4,17 @@ class ApplicationJob < ActiveJob::Base include Que::ActiveJob::JobExtensions + # Esperar una cantidad random de segundos primos, para que no se + # superpongan tareas + # + # @return [Array] + RANDOM_WAIT = [3, 5, 7, 11, 13].seconds + + # @return [ActiveSupport::Duration] + def self.random_wait + RANDOM_WAIT.sample + end + private def site From 718b8643562f2f1d3202ed3c0a7ded93a115ceb5 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 13:33:52 -0300 Subject: [PATCH 737/814] fixup! fix: espaciar el procesamiento de tareas --- app/jobs/application_job.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 1bf20345..dc6d0478 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -7,12 +7,12 @@ class ApplicationJob < ActiveJob::Base # Esperar una cantidad random de segundos primos, para que no se # superpongan tareas # - # @return [Array] - RANDOM_WAIT = [3, 5, 7, 11, 13].seconds + # @return [Array] + RANDOM_WAIT = [3, 5, 7, 11, 13] # @return [ActiveSupport::Duration] def self.random_wait - RANDOM_WAIT.sample + RANDOM_WAIT.sample.seconds end private From 88cc5f9cb0adee2eca01b5b905d69dd6f160fd37 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 14:17:26 -0300 Subject: [PATCH 738/814] fix: reintentar antes de reportar el error #15824 --- app/jobs/activity_pub/process_job.rb | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index af686dbd..d94c31e2 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -3,15 +3,16 @@ class ActivityPub # Procesar las actividades a medida que llegan class ProcessJob < ApplicationJob - attr_reader :body + attr_reader :body, :initial_state # Procesa la actividad en segundo plano # # @param :body [String] # @param :initial_state [Symbol,String] def perform(site:, body:, initial_state: :paused) - @body = body @site = site + @body = body + @initial_state = initial_state ActiveRecord::Base.connection_pool.with_connection do ::ActivityPub.transaction do @@ -25,10 +26,24 @@ class ActivityPub activity.update_activity_pub_state! end end + end + # Al generar una excepción, en lugar de seguir intentando, enviamos # el reporte. - rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, body: body, initial_state: initial_state, activity: original_activity, message: 'Esta acción se canceló automáticamente, para regenerarla, volver a correr el proceso con los mismos parámetros.' }) + def handle_error(error) + case error + when ActiveRecord::RecordInvalid then retry_in(ApplicationJob.random_wait) + else + ExceptionNotifier.notify_exception( + error, + data: { + site: site.name, + body: body, + initial_state: initial_state, + activity: original_activity, + message: 'Esta acción se canceló automáticamente, para regenerarla, volver a correr el proceso con los mismos parámetros.' + }) + end end private From 8384a8a32ad1fadb2fa6c5ec4fe71312cffb9768 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 14:29:05 -0300 Subject: [PATCH 739/814] feat: darle formato al html guardado #14417 --- Gemfile | 1 + Gemfile.lock | 2 ++ app/models/metadata_content.rb | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 466ec079..995cb849 100644 --- a/Gemfile +++ b/Gemfile @@ -76,6 +76,7 @@ gem 'webpacker' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' gem 'device_detector' +gem 'htmlbeautifier' # database gem 'hairtrigger' diff --git a/Gemfile.lock b/Gemfile.lock index 78563c84..862880b9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -255,6 +255,7 @@ GEM heapy (0.2.0) thor hiredis (0.6.3-x86_64-linux-musl) + htmlbeautifier (1.4.2) http_parser.rb (0.8.0-x86_64-linux-musl) httparty (0.21.0) mini_mime (>= 1.0.0) @@ -616,6 +617,7 @@ DEPENDENCIES haml-lint hamlit-rails hiredis + htmlbeautifier httparty icalendar image_processing diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 761518e8..444ee2fe 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 @@ -86,7 +88,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 From 3f9714f6d06ed33baef92f8d8b3d3f0b31433349 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 15:30:44 -0300 Subject: [PATCH 740/814] =?UTF-8?q?fix:=20permitir=20cargar=20blobs=20en?= =?UTF-8?q?=20previsualizaci=C3=B3n=20de=20videos=20y=20audios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/initializers/content_security_policy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From d577075615067d70eca20ce7d46896f1185622f7 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Mar 2024 15:33:10 -0300 Subject: [PATCH 741/814] feat: informar que se va a modificar el archivo #4101 --- .../controllers/file_preview_controller.js | 19 +++++++++++++++++++ app/javascript/etc/image_preview.js | 11 ----------- app/javascript/etc/index.js | 1 - app/views/posts/attributes/_file.haml | 10 ++++++---- app/views/posts/attributes/_image.haml | 9 +++++---- package.json | 1 + yarn.lock | 5 +++++ 7 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 app/javascript/controllers/file_preview_controller.js delete mode 100644 app/javascript/etc/image_preview.js 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/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/package.json b/package.json index 7901ad41..4f5bb05c 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/yarn.lock b/yarn.lock index 0c52b9d3..28155abf 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" From 0d28748b8b65192f59af90869e02cef44fd0a50c Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 11:42:29 -0300 Subject: [PATCH 742/814] fix: i18n --- config/locales/en.yml | 5 +---- config/locales/es.yml | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index f024fa98..1c9f4576 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -771,10 +771,7 @@ en: categories: 'Everything' index: search: 'Search' - edit_post: 'Edit' - edit: - moderation_queue: Moderation Queue - post: Post + edit: Edit preview: btn: 'Preliminary version' alert: 'Not every article type has a preliminary version' diff --git a/config/locales/es.yml b/config/locales/es.yml index 204a3587..a96d5e60 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -712,9 +712,7 @@ es: en: 'inglés' ar: 'árabe' posts: - edit: - moderation_queue: Comentarios - post: Contenido + edit: Editar prev: Página anterior next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. From a27d68cf544d1d9d5459e32c4b2059ef0f6dbeb5 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 12:28:19 -0300 Subject: [PATCH 743/814] fix: las llaves estaban mal nombradas!! #13578 --- app/views/env/index.js.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/env/index.js.haml b/app/views/env/index.js.haml index 597ba53f..8627fa4f 100644 --- a/app/views/env/index.js.haml +++ b/app/views/env/index.js.haml @@ -2,7 +2,7 @@ = cache @site do :plain window.env = { - AIRBRAKE_SITE_ID: #{@site.id}, - AIRBRAKE_API_KEY: "#{@site.airbrake_api_key}", + AIRBRAKE_PROJECT_ID: #{@site.id}, + AIRBRAKE_PROJECT_KEY: "#{@site.airbrake_api_key}", PANEL_URL: "#{ENV['PANEL_URL']}" } From 2fdfbb2eaa0d56fcad9c0040c54ada83e0acccbe Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 12:28:40 -0300 Subject: [PATCH 744/814] fix: si no hay sitio para el panel usar el primer sitio --- app/controllers/env_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/env_controller.rb b/app/controllers/env_controller.rb index de61c704..500cdee4 100644 --- a/app/controllers/env_controller.rb +++ b/app/controllers/env_controller.rb @@ -4,7 +4,7 @@ class EnvController < ActionController::Base skip_before_action :verify_authenticity_token def index - @site = Site.find_by_name('panel') + @site = Site.find_by_name('panel') || Site.first stale? @site if @site end From a79354ceb1223d0a952ec0a1c0dc45b1d5cc1997 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 12:28:53 -0300 Subject: [PATCH 745/814] fix: atrasar la carga de js --- app/views/layouts/application.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 16765965..eaa15eb4 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -15,7 +15,7 @@ = csrf_meta_tags = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = stylesheet_link_tag 'dark', rel: 'alternate stylesheet', media: 'all', 'data-turbolinks-track': 'reload', title: t('dark') - = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' + = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload', defer: true = stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' = favicon_link_tag 'sutty_cuadrada.png', rel: 'apple-touch-icon', type: 'image/png' = render 'layouts/link_rel_alternate' From b10eef7644a23e8104b9a97019f0f0ec793976bb Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 13:03:46 -0300 Subject: [PATCH 746/814] =?UTF-8?q?fix:=20botones=20en=20una=20sola=20l?= =?UTF-8?q?=C3=ADnea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 6d77b75d..9def84b0 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -125,10 +125,11 @@ %br/ = post.order %td.text-nowrap - - if @usuarie || policy(post).edit? - = link_to t('posts.edit_post'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block' - - if @usuarie || policy(post).destroy? - = link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-secondary btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') } + .d-flex.flex-row.align-items-start + - if @usuarie || policy(post).edit? + = link_to t('posts.edit_post'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary' + - if @usuarie || policy(post).destroy? + = link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-secondary', method: :delete, data: { confirm: t('posts.confirm_destroy') } #footnotes{ hidden: true } - @filter_params.each do |param, value| From 34a858f26a20fa0095bfb3efb02ef7252944918b Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 13:08:11 -0300 Subject: [PATCH 747/814] fix: botones apaisados --- app/views/layouts/_breadcrumb.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index 137f086e..a946243a 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -13,7 +13,7 @@ %span.line-clamp-1= link_to crumb.name, crumb.url - if @current_usuarie || current_usuarie - %ul.navbar-nav + %ul.navbar-nav.flex-row - if @site&.tienda? %li.nav-item = link_to t('.tienda'), @site.tienda_url, From 1130bb791c70ff008e4e85eda48528d44ba5fd86 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 26 Mar 2024 15:01:59 -0300 Subject: [PATCH 748/814] =?UTF-8?q?fix:=20borrado=20espacio=20extra=20en?= =?UTF-8?q?=20l=C3=ADnea=2014=20de=20=5Frow.haml=20#14949?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/schemas/_row.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/schemas/_row.haml b/app/views/schemas/_row.haml index 48fd0ee7..ece07727 100644 --- a/app/views/schemas/_row.haml +++ b/app/views/schemas/_row.haml @@ -11,5 +11,5 @@ - unless local_assigns[:parent_schema] - schema.schemas.each do |s| - next if s.hidden? - = render 'schemas/row', schema: s, site: site, filter: filter, - parent_schema: schema + = render 'schemas/row', schema: s, site: site, filter: filter, parent_schema: schema + From 263dce14358b2a71037f15f7a85e0f859c997bc0 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 15:29:58 -0300 Subject: [PATCH 749/814] =?UTF-8?q?feat:=20poder=20traer=20algunas=20opcio?= =?UTF-8?q?nes=20de=20configuraci=C3=B3n=20desde=20la=20plantilla=20#174?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 1 + Gemfile.lock | 1 + app/models/site.rb | 1 + app/models/site/default_options.rb | 44 ++++++++++++++++++++++++++++++ app/services/site_service.rb | 1 + 5 files changed, 48 insertions(+) create mode 100644 app/models/site/default_options.rb diff --git a/Gemfile b/Gemfile index 466ec079..c9f735a3 100644 --- a/Gemfile +++ b/Gemfile @@ -76,6 +76,7 @@ gem 'webpacker' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'kaminari' gem 'device_detector' +gem 'dry-schema' # database gem 'hairtrigger' diff --git a/Gemfile.lock b/Gemfile.lock index 78563c84..7b4ac1ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -603,6 +603,7 @@ DEPENDENCIES distributed-press-api-client (~> 0.3.0rc0) dotenv-rails down + dry-schema ed25519 email_address! exception_notification diff --git a/app/models/site.rb b/app/models/site.rb index 7b93184f..14e05e5d 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -11,6 +11,7 @@ class Site < ApplicationRecord include Site::BuildStats include Site::LayoutOrdering include Site::SocialDistributedPress + include Site::DefaultOptions include Tienda # Cifrar la llave privada que cifra y decifra campos ocultos. Sutty diff --git a/app/models/site/default_options.rb b/app/models/site/default_options.rb new file mode 100644 index 00000000..3e392782 --- /dev/null +++ b/app/models/site/default_options.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'dry-schema' + +class Site + # Las opciones por defecto se aplican durante la creación del sitio y + # luego se permite a les usuaries modificarlas según quieran. Por el + # momento las opciones nuevas que aparezcan no modifican un sitio que + # ya existe. + module DefaultOptions + extend ActiveSupport::Concern + + Schema = Dry::Schema.Params do + optional(:colaboracion_anonima).value(:bool) + optional(:contact).value(:bool) + optional(:acepta_invitades).value(:bool) + optional(:slugify_mode).value(included_in?: Jekyll::Utils::SLUGIFY_MODES) + optional(:pagination).value(:bool) + end + + included do + validate :validate_options_from_theme!, if: :persisted? + + # @return [Dry::Schema::Result] + def options_from_theme + @options_from_theme ||= Schema.call(data['sutty']) + end + + def update_options_from_theme + return true if options_from_theme.to_h.blank? + + update(**options_from_theme.to_h) + end + + private + + def validate_options_from_theme! + options_from_theme.errors.each do |error| + errors.add(:default_options, "#{error.path.map(&:to_s).join('/')} #{error} (#{error.input})") + end + end + end + end +end diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 5c37cfe3..8c3ea6b6 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -27,6 +27,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do site.locales = [usuarie.lang] + I18n.available_locales site.save && + site.update_options_from_theme && site.config.write && commit_config(action: :create) && site.reset.nil? && From 0975d8d5cf90c0af5265116d38be2051b37bd169 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Mar 2024 15:48:30 -0300 Subject: [PATCH 750/814] fix: no fallar si no hay ninguno --- ...20231101200026_add_default_to_distributed_press_publisher.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb b/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb index ada9392f..fd833acb 100644 --- a/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb +++ b/db/migrate/20231101200026_add_default_to_distributed_press_publisher.rb @@ -5,7 +5,7 @@ class AddDefaultToDistributedPressPublisher < ActiveRecord::Migration[6.1] def up add_column :distributed_press_publishers, :default, :boolean, default: false - DistributedPressPublisher.last.update(default: true) + DistributedPressPublisher.last&.update(default: true) end def down From c501107856ff21909196a024889cfae0237d047d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Mar 2024 12:56:54 -0300 Subject: [PATCH 751/814] fix: indicar que no hay que reportar el error closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 closes #15735 closes #15736 closes #15824 closes #15838 closes #15839 --- app/jobs/activity_pub/process_job.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index d94c31e2..4d9c6869 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -30,6 +30,9 @@ class ActivityPub # Al generar una excepción, en lugar de seguir intentando, enviamos # el reporte. + # + # @param error [Exception] + # @return [Bool] def handle_error(error) case error when ActiveRecord::RecordInvalid then retry_in(ApplicationJob.random_wait) @@ -44,6 +47,8 @@ class ActivityPub message: 'Esta acción se canceló automáticamente, para regenerarla, volver a correr el proceso con los mismos parámetros.' }) end + + false end private From c9ef1171382e41512ef77c61fd277c9f63014ca7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Mar 2024 13:36:56 -0300 Subject: [PATCH 752/814] fix: reportar errores de ssh una sola vez closes #14339 closes #14561 closes #14662 closes #15845 closes #15846 closes #15847 closes #15848 closes #15849 closes #15855 closes #15856 closes #15857 closes #15858 closes #15859 closes #15860 closes #15861 closes #15862 closes #15863 closes #15864 closes #15865 closes #15866 closes #15867 closes #15868 closes #15869 closes #15870 closes #15871 --- app/jobs/git_push_job.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb index 3c62bee2..91589189 100644 --- a/app/jobs/git_push_job.rb +++ b/app/jobs/git_push_job.rb @@ -6,6 +6,14 @@ class GitPushJob < ApplicationJob # @param :site [Site] # @return [nil] def perform(site) - site.repository.push if site.repository.origin + site.repository.push if site.repository.origin end -end \ No newline at end of file + + # Reportar una sola vez para que podamos resolver el problema, pero + # reportarlo igual. + # + # @return [Bool] + def handle_error(error) + expire + end +end From ba3cc9cad99db093c7583e5f5d29964e2c6897a0 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Mar 2024 13:42:27 -0300 Subject: [PATCH 753/814] chore: rubocop --- app/jobs/git_push_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb index 91589189..7c3eb236 100644 --- a/app/jobs/git_push_job.rb +++ b/app/jobs/git_push_job.rb @@ -13,7 +13,7 @@ class GitPushJob < ApplicationJob # reportarlo igual. # # @return [Bool] - def handle_error(error) + def handle_error(_) expire end end From 142962160a9f4a9f25fcc6f3dc5c842c9fe2f177 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Mar 2024 14:06:23 -0300 Subject: [PATCH 754/814] fix: reintentar en algunos errores closes #15351 closes #15352 closes #15612 closes #15618 closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 closes #15735 closes #15736 closes #15776 closes #15824 closes #15827 closes #15828 closes #15829 closes #15830 closes #15831 closes #15832 closes #15838 closes #15839 closes #15882 --- app/jobs/activity_pub/fetch_job.rb | 34 ++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index b19d5e41..54641dbf 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -11,14 +11,42 @@ class ActivityPub class FetchJob < ApplicationJob self.priority = 50 + attr_reader :site, :object, :response + + # Notificar errores de JSON con el contenido, tomar los errores de + # validación y conexión como errores temporales y notificar todo lo + # demás sin reintentar. + # + # @param error [Exception] + # @return [Bool] + def handle_error(error) + case error + when FastJsonparser::ParseError + expire + + ExceptionNotifier.notify_exception(error, data: { site: site.name, object: object.uri, body: response.body }) + + false + when ActiveRecord::RecordInvalid, SocketError, SystemCallError, Net::OpenTimeout, OpenSSL::OpenSSLError + retry_in(ApplicationJob.random_wait) + + false + else + expire + + true + end + end + def perform(site:, object_id:) ActivityPub::Object.transaction do - object = ::ActivityPub::Object.find(object_id) + @site = site + @object = ::ActivityPub::Object.find(object_id) return if object.blank? return if object.activity_pubs.where(aasm_state: 'removed').count.positive? - response = site.social_inbox.dereferencer.get(uri: object.uri) + @response = site.social_inbox.dereferencer.get(uri: object.uri) # @todo Fallar cuando la respuesta no funcione? # @todo Eliminar en 410 Gone @@ -39,8 +67,6 @@ class ActivityPub # Arreglar las relaciones con actividades también ActivityPub.where(object_id: object.id).update_all(object_type: object.type, updated_at: Time.now) - rescue FastJsonparser::ParseError => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, object: object.uri, body: response.body }) end end end From ca4017dbd0ff732b3ca6374103f04a5c178f506c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 28 Mar 2024 10:09:20 -0300 Subject: [PATCH 755/814] =?UTF-8?q?fix:=20activejob=20usa=20su=20propio=20?= =?UTF-8?q?m=C3=A9todo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 closes #15735 closes #15736 closes #15824 closes #15838 closes #15839 closes #15882 --- app/jobs/activity_pub/process_job.rb | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index 4d9c6869..dd76a928 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -3,7 +3,9 @@ class ActivityPub # Procesar las actividades a medida que llegan class ProcessJob < ApplicationJob - attr_reader :body, :initial_state + attr_reader :body + + retry_on ActivityPub::RecordInvalid # Procesa la actividad en segundo plano # @@ -12,7 +14,6 @@ class ActivityPub def perform(site:, body:, initial_state: :paused) @site = site @body = body - @initial_state = initial_state ActiveRecord::Base.connection_pool.with_connection do ::ActivityPub.transaction do @@ -28,29 +29,6 @@ class ActivityPub end end - # Al generar una excepción, en lugar de seguir intentando, enviamos - # el reporte. - # - # @param error [Exception] - # @return [Bool] - def handle_error(error) - case error - when ActiveRecord::RecordInvalid then retry_in(ApplicationJob.random_wait) - else - ExceptionNotifier.notify_exception( - error, - data: { - site: site.name, - body: body, - initial_state: initial_state, - activity: original_activity, - message: 'Esta acción se canceló automáticamente, para regenerarla, volver a correr el proceso con los mismos parámetros.' - }) - end - - false - end - private # Si el objeto ya viene incorporado en la actividad o lo tenemos From 3f7f8878417bb034f97738de38d5e094bad0e65e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 28 Mar 2024 10:13:13 -0300 Subject: [PATCH 756/814] fix: activejob gestiona errores por su cuenta closes #15351 closes #15352 closes #15612 closes #15618 closes #15621 closes #15622 closes #15623 closes #15729 closes #15730 closes #15731 closes #15735 closes #15736 closes #15776 closes #15824 closes #15827 closes #15828 closes #15829 closes #15830 closes #15831 closes #15832 closes #15838 closes #15839 closes #15882 --- app/jobs/activity_pub/fetch_job.rb | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 54641dbf..0a3ebf03 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -19,25 +19,16 @@ class ActivityPub # # @param error [Exception] # @return [Bool] - def handle_error(error) - case error - when FastJsonparser::ParseError - expire - - ExceptionNotifier.notify_exception(error, data: { site: site.name, object: object.uri, body: response.body }) - - false - when ActiveRecord::RecordInvalid, SocketError, SystemCallError, Net::OpenTimeout, OpenSSL::OpenSSLError - retry_in(ApplicationJob.random_wait) - - false - else - expire - - true - end + discard_on(FastJsonparser::ParseError) do |error| + ExceptionNotifier.notify_exception(error, data: { site: site.name, object: object.uri, body: response.body }) end + retry_on ActiveRecord::RecordInvalid + retry_on SocketError, wait: ApplicationJob.random_wait + retry_on SystemCallError, wait: ApplicationJob.random_wait + retry_on Net::OpenTimeout, wait: ApplicationJob.random_wait + retry_on OpenSSL::OpenSSLError, wait: ApplicationJob.random_wait + def perform(site:, object_id:) ActivityPub::Object.transaction do @site = site From fe51ef2193ef18e1cfcbc25bb4faef7a1a70643a Mon Sep 17 00:00:00 2001 From: f Date: Thu, 28 Mar 2024 10:15:21 -0300 Subject: [PATCH 757/814] =?UTF-8?q?fixup!=20fix:=20activejob=20usa=20su=20?= =?UTF-8?q?propio=20m=C3=A9todo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/activity_pub/process_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/process_job.rb b/app/jobs/activity_pub/process_job.rb index dd76a928..69c83e33 100644 --- a/app/jobs/activity_pub/process_job.rb +++ b/app/jobs/activity_pub/process_job.rb @@ -5,7 +5,7 @@ class ActivityPub class ProcessJob < ApplicationJob attr_reader :body - retry_on ActivityPub::RecordInvalid + retry_on ActiveRecord::RecordInvalid # Procesa la actividad en segundo plano # From 94d7b32ce6fc4e4b2fbcb89717655310876086ba Mon Sep 17 00:00:00 2001 From: f Date: Tue, 9 Apr 2024 14:16:01 -0300 Subject: [PATCH 758/814] fix: handle_error no es compatible con activejob --- app/jobs/application_job.rb | 5 +++++ app/jobs/git_push_job.rb | 12 ++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 06690c53..8b85358c 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -4,6 +4,11 @@ class ApplicationJob < ActiveJob::Base include Que::ActiveJob::JobExtensions + # Si falla por cualquier cosa informar y descartar + discard_on(Exception) do |error| + ExceptionNotifier.notify_exception(error, data: { site: site.name }) + end + private def site diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb index 7c3eb236..260e3476 100644 --- a/app/jobs/git_push_job.rb +++ b/app/jobs/git_push_job.rb @@ -3,17 +3,13 @@ # Permite pushear los cambios cada vez que se # hacen commits en un sitio class GitPushJob < ApplicationJob + attr_reader :site + # @param :site [Site] # @return [nil] def perform(site) + @site = site + site.repository.push if site.repository.origin end - - # Reportar una sola vez para que podamos resolver el problema, pero - # reportarlo igual. - # - # @return [Bool] - def handle_error(_) - expire - end end From 6dbc8fa0c12bbfcec92b16ffaa72549dd83c5c2f Mon Sep 17 00:00:00 2001 From: f Date: Tue, 9 Apr 2024 14:16:27 -0300 Subject: [PATCH 759/814] fix: reintentar compilaciones --- app/jobs/deploy_job.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 3044b59f..6765bb89 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -11,13 +11,8 @@ class DeployJob < ApplicationJob # Lanzar lo antes posible self.priority = 10 - def handle_error(error) - case error - when DeployAlreadyRunningException then retry_in 1.minute - when DeployTimedOutException then expire - else super - end - end + retry_on DeployAlreadyRunningException, wait: 1.minute + discard_on DeployTimedOutException # rubocop:disable Metrics/MethodLength def perform(site, notify: true, time: Time.now, output: false) From b0bf0c0c535b8c52ce6d4fafc5a3167c95322a4e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 11:00:18 -0300 Subject: [PATCH 760/814] BREAKING CHANGE: usar global ids en los jobs --- app/controllers/api/v1/contact_controller.rb | 2 +- app/controllers/api/v1/notices_controller.rb | 2 +- app/jobs/application_job.rb | 8 ++--- app/jobs/backtrace_job.rb | 9 ++---- app/jobs/contact_job.rb | 8 ++--- app/jobs/deploy_job.rb | 32 ++++++++++---------- app/jobs/git_push_job.rb | 4 --- app/jobs/maintenance_job.rb | 3 +- app/jobs/periodic_job.rb | 3 -- app/jobs/stat_collection_job.rb | 6 ++-- app/jobs/uri_collection_job.rb | 4 +-- app/mailers/application_mailer.rb | 2 +- app/mailers/deploy_mailer.rb | 3 +- app/mailers/invitadx_mailer.rb | 9 ------ app/models/log_entry.rb | 2 +- app/services/site_service.rb | 2 +- lib/tasks/stats.rake | 6 ++-- 17 files changed, 37 insertions(+), 68 deletions(-) delete mode 100644 app/mailers/invitadx_mailer.rb diff --git a/app/controllers/api/v1/contact_controller.rb b/app/controllers/api/v1/contact_controller.rb index d949dc30..c340097f 100644 --- a/app/controllers/api/v1/contact_controller.rb +++ b/app/controllers/api/v1/contact_controller.rb @@ -18,7 +18,7 @@ module Api # Si todo salió bien, enviar los correos y redirigir al sitio. # El sitio nos dice a dónde tenemos que ir. - ContactJob.perform_later site.id, + ContactJob.perform_later site, params[:form], contact_params.to_h.symbolize_keys, params[:redirect] diff --git a/app/controllers/api/v1/notices_controller.rb b/app/controllers/api/v1/notices_controller.rb index 8f384f1a..01bec517 100644 --- a/app/controllers/api/v1/notices_controller.rb +++ b/app/controllers/api/v1/notices_controller.rb @@ -11,7 +11,7 @@ module Api # respondemos con lo mismo. def create if (site&.airbrake_valid? airbrake_token) && !detected_device.bot? - BacktraceJob.perform_later site_id: params[:site_id], + BacktraceJob.perform_later site: site, params: airbrake_params.to_h end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 8b85358c..66345949 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -4,14 +4,10 @@ class ApplicationJob < ActiveJob::Base include Que::ActiveJob::JobExtensions + attr_reader :site + # Si falla por cualquier cosa informar y descartar discard_on(Exception) do |error| ExceptionNotifier.notify_exception(error, data: { site: site.name }) end - - private - - def site - @site ||= Site.find @params[:site_id] - end end diff --git a/app/jobs/backtrace_job.rb b/app/jobs/backtrace_job.rb index 97e6007b..830dc9b3 100644 --- a/app/jobs/backtrace_job.rb +++ b/app/jobs/backtrace_job.rb @@ -6,10 +6,9 @@ class BacktraceJob < ApplicationJob EMPTY_SOURCEMAP = { 'mappings' => '' }.freeze - attr_reader :params, :site_id + attr_reader :params - def perform(site_id:, params:) - @site_id = site_id + def perform(site:, params:) @params = params unless sources.empty? @@ -44,10 +43,6 @@ class BacktraceJob < ApplicationJob private - def site - @site ||= Site.find_by_id(site_id) - end - # Obtiene todos los archivos del backtrace solo si los puede descargar # desde fuentes seguras. # diff --git a/app/jobs/contact_job.rb b/app/jobs/contact_job.rb index c15d7eee..2ac80ce3 100644 --- a/app/jobs/contact_job.rb +++ b/app/jobs/contact_job.rb @@ -5,11 +5,7 @@ class ContactJob < ApplicationJob # @param [Integer] # @param [String] # @param [Hash] - def perform(site_id, form_name, form, origin = nil) - # Retrocompabilidad al actualizar a 2.7.1 - # @see ApplicationJob#site - @params = { site_id: site_id } - + def perform(site, form_name, form, origin = nil) # Sanitizar los valores form.each_key do |key| form[key] = ActionController::Base.helpers.sanitize form[key] @@ -23,7 +19,7 @@ class ContactJob < ApplicationJob usuaries.each_slice(10) do |u| ContactMailer.with(form_name: form_name, form: form, - site_id: site_id, + site: site, usuaries_emails: u, origin: origin) .notify_usuaries.deliver_now diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 6765bb89..103656f4 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -16,34 +16,32 @@ class DeployJob < ApplicationJob # rubocop:disable Metrics/MethodLength def perform(site, notify: true, time: Time.now, output: false) - @output = output + @site = site ActiveRecord::Base.connection_pool.with_connection do - @site = Site.find(site) - # Si ya hay una tarea corriendo, aplazar esta. Si estuvo # esperando más de 10 minutos, recuperar el estado anterior. # # Como el trabajo actual se aplaza al siguiente, arrastrar la # hora original para poder ir haciendo timeouts. - if @site.building? + if site.building? notify = false if 10.minutes.ago >= time raise DeployTimedOutException, - "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" + "#{site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" else raise DeployAlreadyRunningException end end @deployed = {} - @site.update status: 'building' - @site.deployment_list.each do |d| + site.update status: 'building' + site.deployment_list.each do |d| begin raise DeployException, 'Una dependencia falló' if failed_dependencies? d - status = d.deploy(output: @output) + status = d.deploy(output: output) seconds = d.build_stats.last.try(:seconds) || 0 size = d.size urls = d.urls.map do |url| @@ -52,7 +50,7 @@ class DeployJob < ApplicationJob nil end.compact - if d == @site.deployment_list.last && !status + if d == site.deployment_list.last && !status raise DeployException, 'Falló la compilación' end rescue StandardError => e @@ -73,7 +71,7 @@ class DeployJob < ApplicationJob } end - return unless @output + return unless output puts (Terminal::Table.new do |t| t << (%w[type] + @deployed.values.first.keys) @@ -83,12 +81,12 @@ class DeployJob < ApplicationJob end end) ensure - if @site.present? - @site.update status: 'waiting' + if site.present? + site.update status: 'waiting' notify_usuaries if notify - puts "\a" if @output + puts "\a" if output end end end @@ -118,7 +116,7 @@ class DeployJob < ApplicationJob # @param :deploy [Deploy] def notify_exception(exception, deploy = nil) data = { - site: @site.id, + site: site.name, deploy: deploy&.type, log: deploy&.build_stats&.last&.log, failed_dependencies: (failed_dependencies(deploy) if deploy) @@ -128,8 +126,10 @@ class DeployJob < ApplicationJob end def notify_usuaries - @site.roles.where(rol: 'usuarie', temporal: false).pluck(:usuarie_id).each do |usuarie| - DeployMailer.with(usuarie: usuarie, site: @site.id) + usuarie_ids = site.roles.where(rol: 'usuarie', temporal: false).pluck(:usuarie_id) + + Usuarie.where(id: usuarie_ids).find_each do |usuarie| + DeployMailer.with(usuarie_id: usuarie, site: site) .deployed(@deployed) .deliver_now end diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb index 260e3476..d8c811ba 100644 --- a/app/jobs/git_push_job.rb +++ b/app/jobs/git_push_job.rb @@ -3,13 +3,9 @@ # Permite pushear los cambios cada vez que se # hacen commits en un sitio class GitPushJob < ApplicationJob - attr_reader :site - # @param :site [Site] # @return [nil] def perform(site) - @site = site - site.repository.push if site.repository.origin end end diff --git a/app/jobs/maintenance_job.rb b/app/jobs/maintenance_job.rb index c7a962f9..02f29a77 100644 --- a/app/jobs/maintenance_job.rb +++ b/app/jobs/maintenance_job.rb @@ -15,8 +15,7 @@ # Lo mismo para salir de mantenimiento, agregando el atributo # are_we_back: true al crear el Maintenance. class MaintenanceJob < ApplicationJob - def perform(maintenance_id:) - maintenance = Maintenance.find(maintenance_id) + def perform(maintenance:) # Decidir cuál vamos a enviar según el estado de Maintenance mailer = maintenance.are_we_back ? :were_back : :notice diff --git a/app/jobs/periodic_job.rb b/app/jobs/periodic_job.rb index 2f60a2b3..f66434c9 100644 --- a/app/jobs/periodic_job.rb +++ b/app/jobs/periodic_job.rb @@ -6,9 +6,6 @@ class PeriodicJob < ApplicationJob STARTING_INTERVAL = Stat::INTERVALS.first - # Tener el sitio a mano - attr_reader :site - # Descartar y notificar si pasó algo más. # # XXX: En realidad deberíamos seguir reintentando? diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb index e402e3b5..02752901 100644 --- a/app/jobs/stat_collection_job.rb +++ b/app/jobs/stat_collection_job.rb @@ -7,8 +7,8 @@ class StatCollectionJob < PeriodicJob STAT_NAME = 'stat_collection_job' - def perform(site_id:, once: true) - @site = Site.find site_id + def perform(site:, once: true) + @site = site beginning = beginning_of_interval stat = site.stats.create! name: STAT_NAME @@ -22,7 +22,7 @@ class StatCollectionJob < PeriodicJob rollup.average(:seconds) end - dimensions = { site_id: site_id } + dimensions = { site_id: site.id } reduce_rollup(name: 'builds', operation: :sum, dimensions: dimensions) reduce_rollup(name: 'space_used', operation: :average, dimensions: dimensions) diff --git a/app/jobs/uri_collection_job.rb b/app/jobs/uri_collection_job.rb index 4cbbf593..92d788bc 100644 --- a/app/jobs/uri_collection_job.rb +++ b/app/jobs/uri_collection_job.rb @@ -16,8 +16,8 @@ class UriCollectionJob < PeriodicJob IMAGES = %w[.png .jpg .jpeg .gif .webp .jfif].freeze STAT_NAME = 'uri_collection_job' - def perform(site_id:, once: true) - @site = Site.find site_id + def perform(site:, once: true) + @site = site # Obtener el principio del intervalo anterior beginning_of_interval diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 8369550d..1f1d453e 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -10,7 +10,7 @@ class ApplicationMailer < ActionMailer::Base private def site - @site ||= Site.find @params[:site_id] + @site ||= @params[:site] end def inline_logo! diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index 37748b42..abf6932c 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -13,8 +13,7 @@ class DeployMailer < ApplicationMailer # rubocop:disable Metrics/AbcSize def deployed(deploys = {}) - usuarie = Usuarie.find(params[:usuarie]) - site = usuarie.sites.find(params[:site]) + usuarie = params[:usuarie] hostname = site.hostname deploys ||= {} diff --git a/app/mailers/invitadx_mailer.rb b/app/mailers/invitadx_mailer.rb deleted file mode 100644 index cfb80a55..00000000 --- a/app/mailers/invitadx_mailer.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class InvitadxMailer < ApplicationMailer - def confirmation_required - @invitadx = params[:invitadx] - @site = params[:site] - mail from: "#{@site.config.dig('title')} <#{ENV.fetch('DEFAULT_FROM', 'sutty@kefir.red')}>", to: @invitadx.email, subject: t('.subject') - end -end diff --git a/app/models/log_entry.rb b/app/models/log_entry.rb index 9685e0d0..7525177a 100644 --- a/app/models/log_entry.rb +++ b/app/models/log_entry.rb @@ -11,7 +11,7 @@ class LogEntry < ApplicationRecord def resend return if sent - ContactJob.perform_later site_id, params[:form], params + ContactJob.perform_later site, params[:form], params end def params diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 5c37cfe3..3a6b36f7 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -5,7 +5,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do def deploy site.enqueue! - DeployJob.perform_later site.id + DeployJob.perform_later site end # Crea un sitio, agrega un rol nuevo y guarda los cambios a la diff --git a/lib/tasks/stats.rake b/lib/tasks/stats.rake index 9461782a..fbcb5fa4 100644 --- a/lib/tasks/stats.rake +++ b/lib/tasks/stats.rake @@ -3,9 +3,9 @@ namespace :stats do desc 'Process stats' task process_all: :environment do - Site.all.pluck(:id).each do |site_id| - UriCollectionJob.perform_now site_id: site_id, once: true - StatCollectionJob.perform_now site_id: site_id, once: true + Site.all.find_each do |site| + UriCollectionJob.perform_now site: site, once: true + StatCollectionJob.perform_now site: site, once: true end end end From 629549c916d45ee79be189dbcfab536ed1396ba4 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 11:49:30 -0300 Subject: [PATCH 761/814] =?UTF-8?q?fix:=20rehabilitar=20el=20bot=C3=B3n=20?= =?UTF-8?q?tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 2 -- app/views/sites/_status.haml | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 374f06ee..29f6471f 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -4,8 +4,6 @@ = render 'sites/status', site: @site - = render 'sites/build', site: @site, class: 'btn-block' - %h3= t('posts.new') %table.table.table-sm.mb-3 %tbody diff --git a/app/views/sites/_status.haml b/app/views/sites/_status.haml index 47bed657..d3da5c73 100644 --- a/app/views/sites/_status.haml +++ b/app/views/sites/_status.haml @@ -22,3 +22,5 @@ %div{ 'hx-get': site_status_path(site), 'hx-trigger': 'every 10s', 'hx-swap': 'outerHTML' } = render 'bootstrap/alert' do = link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link' + + = render 'sites/build', site: site, class: 'btn-block' From 7cca88b4f3ce0845cdbdfb55885b406b89199d1d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 12:15:30 -0300 Subject: [PATCH 762/814] =?UTF-8?q?fix:=20al=20salir=20de=20la=20p=C3=A1gi?= =?UTF-8?q?na,=20cancelar=20todas=20las=20peticiones=20de=20htmx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #15880 closes #15881 closes #15883 closes #15884 closes #15893 closes #15894 closes #15973 closes #15974 closes #15975 closes #16003 closes #16004 --- app/javascript/etc/htmx_abort.js | 7 +++++++ app/javascript/etc/index.js | 1 + 2 files changed, 8 insertions(+) create mode 100644 app/javascript/etc/htmx_abort.js diff --git a/app/javascript/etc/htmx_abort.js b/app/javascript/etc/htmx_abort.js new file mode 100644 index 00000000..308d0315 --- /dev/null +++ b/app/javascript/etc/htmx_abort.js @@ -0,0 +1,7 @@ +// Cancela las peticiones pendientes de htmx para todos los elementos al +// cambiar de página. +document.addEventListener("turbolinks:click", () => { + for (const hx of document.querySelectorAll("[hx-get]")) { + window.htmx.trigger(hx, "htmx:abort"); + } +}); diff --git a/app/javascript/etc/index.js b/app/javascript/etc/index.js index d4b9f7a3..9ee6a95a 100644 --- a/app/javascript/etc/index.js +++ b/app/javascript/etc/index.js @@ -7,3 +7,4 @@ import './timezone' import './turbolinks-anchors' import './validation' import './new_editor' +import './htmx_abort' From 53fe2847a1ca5adb96776bb2b74730ec51de1b81 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 13:22:17 -0300 Subject: [PATCH 763/814] fixup! BREAKING CHANGE: usar global ids en los jobs --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 103656f4..f84dc55c 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -129,7 +129,7 @@ class DeployJob < ApplicationJob usuarie_ids = site.roles.where(rol: 'usuarie', temporal: false).pluck(:usuarie_id) Usuarie.where(id: usuarie_ids).find_each do |usuarie| - DeployMailer.with(usuarie_id: usuarie, site: site) + DeployMailer.with(usuarie: usuarie, site: site) .deployed(@deployed) .deliver_now end From 847af3374ce02fa352b7ce163ddebbb5d19da247 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 13:26:22 -0300 Subject: [PATCH 764/814] =?UTF-8?q?fix:=20no=20multiplicar=20el=20bot?= =?UTF-8?q?=C3=B3n!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/sites/_status.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/sites/_status.haml b/app/views/sites/_status.haml index d3da5c73..9ac27c15 100644 --- a/app/views/sites/_status.haml +++ b/app/views/sites/_status.haml @@ -23,4 +23,4 @@ = render 'bootstrap/alert' do = link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link' - = render 'sites/build', site: site, class: 'btn-block' + = render 'sites/build', site: site, class: 'btn-block' From 5e1def1028cb1946e2b2f232cc4aaa3bad9c189c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 13:32:37 -0300 Subject: [PATCH 765/814] =?UTF-8?q?feat:=20deshabilitar=20el=20bot=C3=B3n?= =?UTF-8?q?=20mientras=20est=C3=A1=20compilando=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit para no lanzar más de una compilación por vez --- app/views/sites/_build.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/sites/_build.haml b/app/views/sites/_build.haml index b0961e31..c723a3ac 100644 --- a/app/views/sites/_build.haml +++ b/app/views/sites/_build.haml @@ -6,4 +6,4 @@ class: "btn btn-secondary #{local_assigns[:class]}", title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'), data: { disable_with: t('sites.enqueued') }, - disabled: site.enqueued? + disabled: !site.waiting? From c80984888c7eb8d726c37882750c58e0ab454a0a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Apr 2024 15:16:09 -0300 Subject: [PATCH 766/814] =?UTF-8?q?feat:=20recordar=20la=20ubicaci=C3=B3n?= =?UTF-8?q?=20#15188?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2746ab10..617ce665 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -11,6 +11,7 @@ class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? before_action :notify_unconfirmed_email, unless: :devise_controller? around_action :set_locale + after_action :store_location! rescue_from Pundit::NilPolicyError, with: :page_not_found rescue_from ActionController::RoutingError, with: :page_not_found @@ -115,6 +116,16 @@ class ApplicationController < ActionController::Base def after_sign_in_path_for(resource) session[:locale] = nil - sites_path + super + end + + # Guardar la ubicación para que devise redirija a donde íbamos, a + # menos que estemos recibiendo información o intentando ingresar. + def store_location! + return if request.xhr? + return unless request.request_method_symbol == :GET + return if devise_controller? && !is_a?(Devise::RegistrationsController) && params[:action] != 'edit' + + session[:usuarie_return_to] = request.fullpath end end From 11660bc68829157b4c28235f3ad728d8001c879e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Apr 2024 10:01:53 -0300 Subject: [PATCH 767/814] fix: editor --- package.json | 2 +- yarn.lock | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7901ad41..480f3d0b 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.4.4", - "@suttyweb/editor": "^0.1.25", + "@suttyweb/editor": "^0.1.26", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", diff --git a/yarn.lock b/yarn.lock index 0c52b9d3..69cf4edf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1821,6 +1821,26 @@ resolved "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz" integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== +"@floating-ui/core@^1.0.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1" + integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g== + dependencies: + "@floating-ui/utils" "^0.2.1" + +"@floating-ui/dom@^1.5.1": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef" + integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw== + dependencies: + "@floating-ui/core" "^1.0.0" + "@floating-ui/utils" "^0.2.0" + +"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" + integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== + "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" @@ -1955,11 +1975,13 @@ resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.25": - version "0.1.25" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.25.tgz#37b38560642a49b24383473543c28be943695f9f" - integrity sha512-fxOO9LpdntWzgNZch4cZB6QL0u+jEw0NqsNahKcGBbiJaS0GNGLRrT2LUd/Djc6O8HWkQguPLcquVT5eHq2h9g== +"@suttyweb/editor@^0.1.26": + version "0.1.26" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.26.tgz#ba59db20bd6faa7b43d44b764c0bc7b25f461e06" + integrity sha512-nT1DaQjaPBwVG4FofSF0AoiPzIZfAdW6oRX9KOegM99MicvyoBZyItmuGyxl6lv9hpDKa8DwR4W8Cd5ZAD6S7w== dependencies: + "@floating-ui/dom" "^1.5.1" + linkifyjs "^4.1.1" prosemirror-svelte-nodeview "^1.0.2" "@types/caseless@*": @@ -5190,6 +5212,11 @@ linkify-it@^2.0.0: dependencies: uc.micro "^1.0.1" +linkifyjs@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.3.tgz#0edbc346428a7390a23ea2e5939f76112c9ae07f" + integrity sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg== + loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz" From 7a71e1de8856f241e271d14ff3cf04c28544ed8a Mon Sep 17 00:00:00 2001 From: f Date: Fri, 12 Apr 2024 15:31:47 -0300 Subject: [PATCH 768/814] fix: no fallar si no hay sitio #16007 --- app/jobs/application_job.rb | 2 +- app/jobs/backtrace_job.rb | 1 + app/jobs/contact_job.rb | 2 ++ app/jobs/git_pull_job.rb | 2 ++ app/jobs/git_push_job.rb | 2 ++ 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 66345949..37ec0f76 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -8,6 +8,6 @@ class ApplicationJob < ActiveJob::Base # Si falla por cualquier cosa informar y descartar discard_on(Exception) do |error| - ExceptionNotifier.notify_exception(error, data: { site: site.name }) + ExceptionNotifier.notify_exception(error, data: { site: @site&.name }) end end diff --git a/app/jobs/backtrace_job.rb b/app/jobs/backtrace_job.rb index 830dc9b3..5e9a05cf 100644 --- a/app/jobs/backtrace_job.rb +++ b/app/jobs/backtrace_job.rb @@ -9,6 +9,7 @@ class BacktraceJob < ApplicationJob attr_reader :params def perform(site:, params:) + @site = site @params = params unless sources.empty? diff --git a/app/jobs/contact_job.rb b/app/jobs/contact_job.rb index 2ac80ce3..d4c2677f 100644 --- a/app/jobs/contact_job.rb +++ b/app/jobs/contact_job.rb @@ -6,6 +6,8 @@ class ContactJob < ApplicationJob # @param [String] # @param [Hash] def perform(site, form_name, form, origin = nil) + @site = site + # Sanitizar los valores form.each_key do |key| form[key] = ActionController::Base.helpers.sanitize form[key] diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index 58a4e6b1..72e20be0 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -7,6 +7,8 @@ class GitPullJob < ApplicationJob # @param :usuarie [Usuarie] # @return [nil] def perform(site, usuarie) + @site = site + return unless site.repository.origin return unless site.repository.fetch.positive? diff --git a/app/jobs/git_push_job.rb b/app/jobs/git_push_job.rb index d8c811ba..4df9f5aa 100644 --- a/app/jobs/git_push_job.rb +++ b/app/jobs/git_push_job.rb @@ -6,6 +6,8 @@ class GitPushJob < ApplicationJob # @param :site [Site] # @return [nil] def perform(site) + @site = site + site.repository.push if site.repository.origin end end From 4ccf37c370cdb3eac19b1ae8b1d222e3a8b7d52c Mon Sep 17 00:00:00 2001 From: f Date: Mon, 15 Apr 2024 11:54:28 -0300 Subject: [PATCH 769/814] =?UTF-8?q?fix:=20informar=20la=20tarea=20que=20fa?= =?UTF-8?q?ll=C3=B3=20de=20forma=20gen=C3=A9rica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #16052 closes #16058 closes #16059 --- app/jobs/application_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 37ec0f76..d527c9b9 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -7,7 +7,7 @@ class ApplicationJob < ActiveJob::Base attr_reader :site # Si falla por cualquier cosa informar y descartar - discard_on(Exception) do |error| - ExceptionNotifier.notify_exception(error, data: { site: @site&.name }) + discard_on(Exception) do |job, error| + ExceptionNotifier.notify_exception(error, data: { job: job }) end end From fb4228b873e5e1873b82c38498c18f992df73fdb Mon Sep 17 00:00:00 2001 From: f Date: Mon, 15 Apr 2024 16:58:55 -0300 Subject: [PATCH 770/814] =?UTF-8?q?fix:=20no=20filtrar=20informaci=C3=B3n?= =?UTF-8?q?=20privada!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/application_record.rb | 7 +++++++ config/initializers/filter_parameter_logging.rb | 1 + 2 files changed, 8 insertions(+) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 71fbba5b..27ed3d56 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -2,4 +2,11 @@ class ApplicationRecord < ActiveRecord::Base self.abstract_class = true + + # Obtener una lista filtrada de atributos al momento de serializar + # + # @return [Hash] + def to_yaml(options = {}) + self.class.inspection_filter.filter attributes + end end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 2fc446ff..8ef6ca49 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -5,4 +5,5 @@ # Configure sensitive parameters which will be filtered from the log file. Rails.application.config.filter_parameters += %i[ password passw secret token _key crypt salt certificate otp ssn key + _pem _ciphertext ] From 7f437f9e0659ae648c9d90e4c3ebf1d8ac760a3f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 15 Apr 2024 17:00:58 -0300 Subject: [PATCH 771/814] =?UTF-8?q?fix:=20filtrar=20informaci=C3=B3n=20per?= =?UTF-8?q?sonal=20tambi=C3=A9n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/initializers/filter_parameter_logging.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 8ef6ca49..b1d9f2b0 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -5,5 +5,5 @@ # Configure sensitive parameters which will be filtered from the log file. Rails.application.config.filter_parameters += %i[ password passw secret token _key crypt salt certificate otp ssn key - _pem _ciphertext + _pem _ciphertext email ] From e8cf50b9d22154294b7ca03782d9ffa001273467 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 15 Apr 2024 17:10:19 -0300 Subject: [PATCH 772/814] fix: convertir a yaml --- app/models/application_record.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 27ed3d56..985df966 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -5,8 +5,8 @@ class ApplicationRecord < ActiveRecord::Base # Obtener una lista filtrada de atributos al momento de serializar # - # @return [Hash] + # @return [String] def to_yaml(options = {}) - self.class.inspection_filter.filter attributes + self.class.inspection_filter.filter(attributes).to_yaml(options) end end From 83add8dd7def7b58dfb741d5c51106576f3a0882 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 15 Apr 2024 17:26:40 -0300 Subject: [PATCH 773/814] =?UTF-8?q?fix:=20usar=20una=20versi=C3=B3n=20m?= =?UTF-8?q?=C3=A1s=20corta=20del=20hash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/application_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 985df966..f09c4dd4 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -7,6 +7,6 @@ class ApplicationRecord < ActiveRecord::Base # # @return [String] def to_yaml(options = {}) - self.class.inspection_filter.filter(attributes).to_yaml(options) + self.class.inspection_filter.filter(serializable_hash).to_yaml(options) end end From 2eb3145e1cf20581216b1ddcecebe6ee57f41e45 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 15 Apr 2024 17:28:30 -0300 Subject: [PATCH 774/814] fix: los atributos filtrados son por modelo --- app/models/site.rb | 2 ++ app/models/usuarie.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/models/site.rb b/app/models/site.rb index 7b93184f..c47a14a2 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -13,6 +13,8 @@ class Site < ApplicationRecord include Site::SocialDistributedPress include Tienda + self.filter_attributes += [/_key/, /_ciphertext\z/] + # Cifrar la llave privada que cifra y decifra campos ocultos. Sutty # tiene acceso pero los datos se guardan cifrados en el sitio. Esto # protege información privada en repositorios públicos, pero no la diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 42f20c0b..4eba314a 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -21,6 +21,8 @@ class Usuarie < ApplicationRecord has_many :blazer_audits, foreign_key: 'user_id', class_name: 'Blazer::Audit' has_many :blazer_queries, foreign_key: 'creator_id', class_name: 'Blazer::Query' + self.filter_attributes += [/\Aemail\z/, /\Aencrypted_password\z/] + def name email.split('@', 2).first end From 452ca435081af9d29af1b1a03e2d99a221588942 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 Apr 2024 13:07:49 -0300 Subject: [PATCH 775/814] =?UTF-8?q?fix:=20doble=20negaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/components/_profiles_btn_box.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index 8fc8dd39..2023de96 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -2,7 +2,7 @@ .d-flex.flex-row.w-100 - local = { report: { class: 'ml-auto', data: { confirm: t('.confirm_report') } } } - ActorModeration.events.each do |actor_event| - - possible = !actor_moderation.public_send(:"may_#{actor_event}?") + - possible = actor_moderation.public_send(:"may_#{actor_event}?") %div{ class: local.dig(actor_event, :class) } = render 'components/btn_base', text: t(".text_#{actor_event}"), From 14c5530b501edd114828d0ec0b8b0541da0b9ff1 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 22 Apr 2024 11:06:25 -0300 Subject: [PATCH 776/814] feat: editor 0.1.27 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 480f3d0b..2bff3159 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.4.4", - "@suttyweb/editor": "^0.1.26", + "@suttyweb/editor": "^0.1.27", "babel-loader": "^8.2.2", "chart.js": "^3.5.1", "chartkick": "^4.0.5", From 044b14c355c3d50a11dfdd935b31894dce1b7713 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 22 Apr 2024 11:15:09 -0300 Subject: [PATCH 777/814] fixup! feat: editor 0.1.27 --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 69cf4edf..7e1d597c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1975,10 +1975,10 @@ resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.26": - version "0.1.26" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.26.tgz#ba59db20bd6faa7b43d44b764c0bc7b25f461e06" - integrity sha512-nT1DaQjaPBwVG4FofSF0AoiPzIZfAdW6oRX9KOegM99MicvyoBZyItmuGyxl6lv9hpDKa8DwR4W8Cd5ZAD6S7w== +"@suttyweb/editor@^0.1.27": + version "0.1.27" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.27.tgz#9415a0b767e72dbe4fbf42ce87e62fb8f5125c31" + integrity sha512-Ts9TZtGiRIaHm+ffVBRl+/nuVcANWZNtFsrGacoajgEsagaIyA1cq8qjiNpPoM5ne9vTba3cAaLP04V/uEIhBw== dependencies: "@floating-ui/dom" "^1.5.1" linkifyjs "^4.1.1" From 8de05ccce6d2d7e9cfc8e509350bc0d6d1675311 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 22 Apr 2024 14:54:40 -0300 Subject: [PATCH 778/814] fix: solo permitir los mismos tipos de archivo que jekyll closes #16117 --- app/lib/jekyll/readers/data_reader_decorator.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/lib/jekyll/readers/data_reader_decorator.rb b/app/lib/jekyll/readers/data_reader_decorator.rb index 9fed7ac7..2a2a8fc2 100644 --- a/app/lib/jekyll/readers/data_reader_decorator.rb +++ b/app/lib/jekyll/readers/data_reader_decorator.rb @@ -14,6 +14,8 @@ module Jekyll extend ActiveSupport::Concern included do + DATA_EXTENSIONS = %w[.yaml .yml .json .csv .tsv].freeze + def read_data_to(dir, data) return unless File.directory?(dir) && !@entry_filter.symlink?(dir) @@ -24,7 +26,7 @@ module Jekyll if File.directory?(path) read_data_to(path, data[sanitize_filename(entry)] = {}) - else + elsif DATA_EXTENSIONS.include?(File.extname(entry)) key = sanitize_filename(File.basename(entry, ".*")) data[key] = read_data_file(path) end From 5f0672bcaebd1d68d81738c9d74f4275eb6866b9 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 30 Apr 2024 17:44:33 -0300 Subject: [PATCH 779/814] =?UTF-8?q?feat:=20recargar=20el=20bot=C3=B3n=20de?= =?UTF-8?q?=20publicar=20por=20separado=20#16180?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/sites_controller.rb | 6 ++++++ app/policies/site_policy.rb | 4 ++++ app/views/posts/index.haml | 1 + app/views/sites/_build.haml | 17 +++++++++-------- app/views/sites/_status.haml | 4 +--- app/views/sites/build.haml | 1 + config/routes.rb | 1 + 7 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 app/views/sites/build.haml diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index 49527cf7..e911daac 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -22,6 +22,12 @@ class SitesController < ApplicationController render('sites/status', layout: false) if stale? site end + def button + authorize site + + render('sites/build', layout: false) + end + # No tenemos propiedades de un sitio aún, así que vamos al listado de # artículos def show diff --git a/app/policies/site_policy.rb b/app/policies/site_policy.rb index d5465d6b..ce56a2e7 100644 --- a/app/policies/site_policy.rb +++ b/app/policies/site_policy.rb @@ -61,6 +61,10 @@ class SitePolicy show? && usuarie? end + def button? + show? + end + def enqueue? build? end diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 29f6471f..3ea82309 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -3,6 +3,7 @@ = render 'sites/header', site: @site = render 'sites/status', site: @site + = render 'sites/build', site: @site, class: 'btn-block' %h3= t('posts.new') %table.table.table-sm.mb-3 diff --git a/app/views/sites/_build.haml b/app/views/sites/_build.haml index c723a3ac..8db4d370 100644 --- a/app/views/sites/_build.haml +++ b/app/views/sites/_build.haml @@ -1,9 +1,10 @@ - if policy(site).build? - = form_tag site_enqueue_path(site), - method: :post, - class: 'form-inline inline' do - = submit_tag site.enqueued? ? t('sites.enqueued') : t('sites.enqueue'), - class: "btn btn-secondary #{local_assigns[:class]}", - title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'), - data: { disable_with: t('sites.enqueued') }, - disabled: !site.waiting? + %div{ 'hx-get': site_button_path(site, class: local_assigns[:class]), 'hx-trigger': 'every 10s', 'hx-swap': 'outerHTML' } + = form_tag site_enqueue_path(site), + method: :post, + class: 'form-inline inline' do + = submit_tag site.enqueued? ? t('sites.enqueued') : t('sites.enqueue'), + class: "btn btn-secondary #{local_assigns[:class]}", + title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'), + data: { disable_with: t('sites.enqueued') }, + disabled: !site.waiting? diff --git a/app/views/sites/_status.haml b/app/views/sites/_status.haml index 9ac27c15..a3dfd4ad 100644 --- a/app/views/sites/_status.haml +++ b/app/views/sites/_status.haml @@ -18,9 +18,7 @@ - message = t('.available') - link = true - -# TODO: Calcular cada cuanto sería óptimo recargar + -# TODO: Calcular cada cuánto sería óptimo recargar %div{ 'hx-get': site_status_path(site), 'hx-trigger': 'every 10s', 'hx-swap': 'outerHTML' } = render 'bootstrap/alert' do = link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link' - - = render 'sites/build', site: site, class: 'btn-block' diff --git a/app/views/sites/build.haml b/app/views/sites/build.haml new file mode 100644 index 00000000..c2becec0 --- /dev/null +++ b/app/views/sites/build.haml @@ -0,0 +1 @@ += render 'sites/build', site: @site, class: params.permit(:class)[:class] diff --git a/config/routes.rb b/config/routes.rb index 557439e9..d97611fd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,6 +38,7 @@ Rails.application.routes.draw do post 'pull', to: 'sites#merge' get 'status', to: 'sites#status' + get 'button', to: 'sites#button' # Gestionar usuaries get 'usuaries/invite', to: 'usuaries#invite' From 79be9538bb8ccf9350e5e4cb71150e92440fdcb6 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 30 Apr 2024 17:45:33 -0300 Subject: [PATCH 780/814] fix: ignorar los errores de abort de htmx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit el problema es que cuando se envía un abort a htmx, se loguea un mensaje de todas formas. closes #15880 closes #15881 closes #15883 closes #15884 closes #15893 closes #15894 closes #15973 closes #15974 closes #15975 closes #16003 closes #16004 closes #16015 closes #16016 closes #16023 closes #16024 closes #16050 closes #16051 closes #16063 closes #16064 closes #16073 closes #16074 closes #16116 closes #16125 closes #16126 --- app/javascript/packs/application.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index d8ff0dd1..e10e2b5d 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -9,9 +9,16 @@ try { host: window.env.PANEL_URL }); + const ignoredErrors = ["htmx:afterRequest", "htmx:sendAbort"]; + console.originalError = console.error; console.error = (...e) => { - window.airbrake.notify(e.join(" ")); + const msg = e.join(" "); + + if (!ignoredErrors.some(x => msg.includes(x))) { + window.airbrake.notify(e.join(" ")); + } + return console.originalError(...e); }; } catch(e) { From 4f12d1211824ca2cd6652001aadf5592f5396a48 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 15:49:20 -0300 Subject: [PATCH 781/814] ci: usar los locks para identificar la cache [skip ci] --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bb674844..dceb1a42 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,9 +6,15 @@ - paths: - "vendor/ruby" - ".bundle" + key: + files: + - "Gemfile.lock" .cache-node: &cache-node - paths: - "node_modules" + key: + files: + - "yarn.lock" .cache-task: &cache-task - paths: - ".task" From 9c0ea76c219fc5db9d2972e3118418bcd7f01d31 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 15:54:54 -0300 Subject: [PATCH 782/814] ci: instalar gemas [skip ci] --- Taskfile.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Taskfile.yaml b/Taskfile.yaml index 57fb0238..796ab721 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -185,9 +185,13 @@ tasks: - "test -f ../hain/usr/bin/bundler-audit" rubocop: desc: "Ruby linting" + deps: + - "gems" cmds: - "./bin/modified_files | ./bin/with_extension rb | xargs -r {{.HAINISH}} bundle exec rubocop {{.CLI_ARGS}}" haml-lint: desc: "HAML linting" + deps: + - "gems" cmds: - "./bin/modified_files | ./bin/with_extension haml | xargs -r {{.HAINISH}} bundle exec haml-lint {{.CLI_ARGS}}" From 8fba98f9fd0da1a1e5949e5a729d4de8d74059f8 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 15:57:49 -0300 Subject: [PATCH 783/814] chore: rubocop --- app/jobs/backtrace_job.rb | 4 +--- app/jobs/deploy_job.rb | 17 +++++++---------- app/models/site.rb | 18 +++++++++--------- app/models/usuarie.rb | 10 +++++----- app/services/site_service.rb | 4 +--- 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/app/jobs/backtrace_job.rb b/app/jobs/backtrace_job.rb index 5e9a05cf..4ef5287c 100644 --- a/app/jobs/backtrace_job.rb +++ b/app/jobs/backtrace_job.rb @@ -55,9 +55,7 @@ class BacktraceJob < ApplicationJob x['backtrace'] end.flatten.map do |x| x['file'].split('@').last - end.uniq.select do |x| - %r{\Ahttps://} =~ x - end + end.uniq.grep(%r{\Ahttps://}) end # Descarga y devuelve los datos de un archivo diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index f84dc55c..66cccd1b 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -27,12 +27,11 @@ class DeployJob < ApplicationJob if site.building? notify = false - if 10.minutes.ago >= time - raise DeployTimedOutException, - "#{site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" - else - raise DeployAlreadyRunningException - end + raise DeployAlreadyRunningException unless 10.minutes.ago >= time + + raise DeployTimedOutException, + "#{site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" + end @deployed = {} @@ -50,9 +49,7 @@ class DeployJob < ApplicationJob nil end.compact - if d == site.deployment_list.last && !status - raise DeployException, 'Falló la compilación' - end + raise DeployException, 'Falló la compilación' if d == site.deployment_list.last && !status rescue StandardError => e status = false seconds ||= 0 @@ -73,7 +70,7 @@ class DeployJob < ApplicationJob return unless output - puts (Terminal::Table.new do |t| + puts(Terminal::Table.new do |t| t << (%w[type] + @deployed.values.first.keys) t.add_separator @deployed.each do |type, row| diff --git a/app/models/site.rb b/app/models/site.rb index e3068734..f51d2c6f 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -292,11 +292,11 @@ class Site < ApplicationRecord # layouts. Si pasamos un layout que no existe, obtenemos un # NoMethodError @layouts_struct ||= Struct.new(*layout_keys, keyword_init: true) - @layouts ||= @layouts_struct.new(**data['layouts'].map do |name, metadata| + @layouts ||= @layouts_struct.new(**data['layouts'].to_h do |name, metadata| [name.to_sym, Layout.new(site: self, name: name.to_sym, meta: metadata.delete('meta')&.with_indifferent_access, metadata: metadata.with_indifferent_access)] - end.to_h) + end) end # TODO: Si la estructura de datos no existe, vamos a producir una @@ -389,7 +389,7 @@ class Site < ApplicationRecord end def reload - super.tap do |s| + super.tap do |_s| reload_jekyll! end self @@ -479,7 +479,7 @@ class Site < ApplicationRecord def clone_skel! return if jekyll? - Rugged::Repository.clone_at(ENV['SKEL_SUTTY'], path, checkout_branch: design.gem) + Rugged::Repository.clone_at(ENV.fetch('SKEL_SUTTY', nil), path, checkout_branch: design.gem) # Necesita un bloque repository.rugged.remotes.rename('origin', 'upstream') {} @@ -579,11 +579,11 @@ class Site < ApplicationRecord deploy_local = deploys.find_by_type('DeployLocal') deploy_local.git_lfs - if !gems_installed? || gemfile_updated? || gemfile_lock_updated? - deploy_local.bundle - touch - FileUtils.touch(gemfile_path) - end + return unless !gems_installed? || gemfile_updated? || gemfile_lock_updated? + + deploy_local.bundle + touch + FileUtils.touch(gemfile_path) end def gem_path diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 4eba314a..4856f17f 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -76,10 +76,10 @@ class Usuarie < ApplicationRecord # Si le usuarie (re)confirma su cuenta con una invitación pendiente, # considerarla aceptada también. def accept_invitation_after_confirmation! - if confirmed? - self.invitation_token = nil - self.invitation_accepted_at ||= Time.now.utc - end + return unless confirmed? + + self.invitation_token = nil + self.invitation_accepted_at ||= Time.now.utc end # Muestra un error si el idioma no está disponible al cambiar el @@ -87,7 +87,7 @@ class Usuarie < ApplicationRecord # # @return [nil] def locale_available! - return if I18n.locale_available? self.lang + return if I18n.locale_available? lang errors.add(:lang, I18n.t('activerecord.errors.models.usuarie.attributes.lang.not_available')) nil diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 3a6b36f7..a28e5ee8 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -222,9 +222,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do end end - private - - def with_all_locales(&block) + def with_all_locales site.locales.map do |locale| next unless I18n.available_locales.include? locale From b11282997b8574c093e0742b6409b4378e966df3 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:02:34 -0300 Subject: [PATCH 784/814] fix: redundante --- app/jobs/activity_pub/fetch_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 0a3ebf03..5d9e02de 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -11,7 +11,7 @@ class ActivityPub class FetchJob < ApplicationJob self.priority = 50 - attr_reader :site, :object, :response + attr_reader :object, :response # Notificar errores de JSON con el contenido, tomar los errores de # validación y conexión como errores temporales y notificar todo lo From c2cc08007e6d3018a929e61d7727f226380c074c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:05:35 -0300 Subject: [PATCH 785/814] chore: rubocop --- app/controllers/application_controller.rb | 9 +++------ app/helpers/application_helper.rb | 4 ++-- app/jobs/activity_pub/fetch_job.rb | 3 ++- app/jobs/activity_pub/sync_lists_job.rb | 4 +++- app/jobs/application_job.rb | 4 +--- app/models/activity_pub.rb | 5 +++-- app/models/activity_pub/fediblock.rb | 4 ++-- app/models/activity_pub/object.rb | 5 +++-- app/models/activity_pub/remote_flag.rb | 5 +++-- app/models/concerns/tienda.rb | 2 +- app/models/fediblock_state.rb | 3 ++- app/models/instance_moderation.rb | 4 +++- app/models/metadata_template.rb | 2 +- app/models/social_inbox.rb | 4 ++-- app/services/site_service.rb | 2 -- config/environments/production.rb | 9 +++++---- config/initializers/que_web.rb | 2 +- db/migrate/20240227142019_create_fediblock_states.rb | 4 +--- ...0313204105_brs_decompressor_corrupted_source_error.rb | 6 ++++-- db/migrate/20240314205923_fix_activity_type.rb | 4 +++- db/migrate/20240318183846_fix_duplicate_objects.rb | 2 +- db/migrate/20240319124212_add_fedipact_to_fediblocks.rb | 4 +--- db/migrate/20240319144735_add_missing_unique_indexes.rb | 6 +++--- db/seeds.rb | 4 ++-- 24 files changed, 52 insertions(+), 49 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b76238a0..117be995 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,7 +14,7 @@ class ApplicationController < ActionController::Base after_action :store_location! before_action do - Rack::MiniProfiler.authorize_request if current_usuarie&.email&.ends_with?('@' + ENV.fetch('SUTTY', 'sutty.nl')) + Rack::MiniProfiler.authorize_request if current_usuarie&.email&.ends_with?("@#{ENV.fetch('SUTTY', 'sutty.nl')}") end # No tenemos índice de sutty, vamos directamente a ver el listado de @@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base end private - + def notify_unconfirmed_email return unless current_usuarie return if current_usuarie.confirmed? @@ -58,9 +58,7 @@ class ApplicationController < ActionController::Base def current_locale locale = params[:change_locale_to] - if locale.present? && I18n.locale_available?(locale) - session[:locale] = params[:change_locale_to] - end + session[:locale] = params[:change_locale_to] if locale.present? && I18n.locale_available?(locale) session[:locale] || current_usuarie&.lang || I18n.locale end @@ -119,5 +117,4 @@ class ApplicationController < ActionController::Base session[:usuarie_return_to] = request.fullpath end - end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 146846f0..fcbd4074 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -13,7 +13,7 @@ module ApplicationHelper root = names.shift names.each do |n| - root += '[' + n.to_s + ']' + root += "[#{n}]" end [root, name] @@ -22,7 +22,7 @@ module ApplicationHelper def plain_field_name_for(*names) root, name = field_name_for(*names) - root + '[' + name.to_s + ']' + "#{root}[#{name}]" end def distance_of_time_in_words_if_more_than_a_minute(seconds) diff --git a/app/jobs/activity_pub/fetch_job.rb b/app/jobs/activity_pub/fetch_job.rb index 5d9e02de..07190c35 100644 --- a/app/jobs/activity_pub/fetch_job.rb +++ b/app/jobs/activity_pub/fetch_job.rb @@ -50,7 +50,8 @@ class ActivityPub content = FastJsonparser.parse(response.body) # Modificar atómicamente - ::ActivityPub::Object.lock.find(object_id).update!(content: content, type: ActivityPub::Object.type_from(content).name) + ::ActivityPub::Object.lock.find(object_id).update!(content: content, + type: ActivityPub::Object.type_from(content).name) object = ::ActivityPub::Object.find(object_id) # Actualiza la mención diff --git a/app/jobs/activity_pub/sync_lists_job.rb b/app/jobs/activity_pub/sync_lists_job.rb index de71fe64..e37e15be 100644 --- a/app/jobs/activity_pub/sync_lists_job.rb +++ b/app/jobs/activity_pub/sync_lists_job.rb @@ -43,7 +43,9 @@ class ActivityPub # Si alguna falló, reintentar raise if logs.present? rescue Exception => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, logs: logs, blocklist: blocklist, allowlist: allowlist, pauselist: pauselist }) + ExceptionNotifier.notify_exception(e, + data: { site: site.name, logs: logs, blocklist: blocklist, + allowlist: allowlist, pauselist: pauselist }) raise end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 4bb68359..ee4e3b2c 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -8,7 +8,7 @@ class ApplicationJob < ActiveJob::Base # superpongan tareas # # @return [Array] - RANDOM_WAIT = [3, 5, 7, 11, 13] + RANDOM_WAIT = [3, 5, 7, 11, 13].freeze # @return [ActiveSupport::Duration] def self.random_wait @@ -17,8 +17,6 @@ class ApplicationJob < ActiveJob::Base attr_reader :site - private - # Si falla por cualquier cosa informar y descartar discard_on(Exception) do |job, error| ExceptionNotifier.notify_exception(error, data: { job: job }) diff --git a/app/models/activity_pub.rb b/app/models/activity_pub.rb index cd893406..7f8155cd 100644 --- a/app/models/activity_pub.rb +++ b/app/models/activity_pub.rb @@ -64,7 +64,7 @@ class ActivityPub < ApplicationRecord # Array o mezcla y obtener el que más nos convenga o # adivinar uno. when Array - links = object['url'].map.with_index do |link, i| + links = object['url'].map.with_index do |link, _i| case link when Hash then link else { 'href' => link.to_s } @@ -93,7 +93,8 @@ class ActivityPub < ApplicationRecord # Gestionar todos los errores error_on_all_events do |e| - ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: self.id, activity: activities.first.uri }) + ExceptionNotifier.notify_exception(e, + data: { site: site.name, activity_pub: id, activity: activities.first.uri }) end # Se puede volver a pausa en caso de actualización remota, para diff --git a/app/models/activity_pub/fediblock.rb b/app/models/activity_pub/fediblock.rb index 17897d79..e66e6e60 100644 --- a/app/models/activity_pub/fediblock.rb +++ b/app/models/activity_pub/fediblock.rb @@ -35,9 +35,9 @@ class ActivityPub validates_inclusion_of :format, in: %w[mastodon fediblock none] HOSTNAME_HEADERS = { - 'mastodon' => '#domain', + 'mastodon' => '#domain', 'fediblock' => 'domain' - } + }.freeze def client @client ||= Client.new diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index d37c9b88..b10b4431 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -39,13 +39,14 @@ class ActivityPub def referenced(site) require 'distributed_press/v1/social/referenced_object' - @referenced ||= DistributedPress::V1::Social::ReferencedObject.new(object: content, dereferencer: site.social_inbox.dereferencer) + @referenced ||= DistributedPress::V1::Social::ReferencedObject.new(object: content, + dereferencer: site.social_inbox.dereferencer) end private def uri_is_content_id? - return if self.uri == content['id'] + return if uri == content['id'] errors.add(:activity_pub_objects, 'El ID del objeto no coincide con su URI') end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb index c3cc0fb0..d6348650 100644 --- a/app/models/activity_pub/remote_flag.rb +++ b/app/models/activity_pub/remote_flag.rb @@ -40,7 +40,8 @@ class ActivityPub def content { '@context' => 'https://www.w3.org/ns/activitystreams', - 'id' => Rails.application.routes.url_helpers.v1_activity_pub_remote_flag_url(self, host: site.social_inbox_hostname), + 'id' => Rails.application.routes.url_helpers.v1_activity_pub_remote_flag_url(self, + host: site.social_inbox_hostname), 'type' => 'Flag', 'actor' => main_site.social_inbox.actor_id, 'content' => message.to_s, @@ -53,7 +54,7 @@ class ActivityPub # # @return [Site] def main_site - @main_site ||= Site.find(ENV.fetch('PANEL_ACTOR_SITE_ID') { 1 }) + @main_site ||= Site.find(ENV.fetch('PANEL_ACTOR_SITE_ID', 1)) end end end diff --git a/app/models/concerns/tienda.rb b/app/models/concerns/tienda.rb index 86174c9a..a3e6007a 100644 --- a/app/models/concerns/tienda.rb +++ b/app/models/concerns/tienda.rb @@ -17,7 +17,7 @@ module Tienda return t if new_record? - t.blank? ? 'https://' + name + '.' + ENV.fetch('TIENDA', 'tienda.sutty.nl') : t + t.blank? ? "https://#{name}.#{ENV.fetch('TIENDA', 'tienda.sutty.nl')}" : t end end end diff --git a/app/models/fediblock_state.rb b/app/models/fediblock_state.rb index 82912f76..02dee2d8 100644 --- a/app/models/fediblock_state.rb +++ b/app/models/fediblock_state.rb @@ -45,7 +45,8 @@ class FediblockState < ApplicationRecord private def block_instances! - ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames, perform_remotely: false) + ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames, + perform_remotely: false) end # Pausar todas las moderaciones de las instancias que no estén diff --git a/app/models/instance_moderation.rb b/app/models/instance_moderation.rb index 5a1a5ed6..c1192615 100644 --- a/app/models/instance_moderation.rb +++ b/app/models/instance_moderation.rb @@ -16,7 +16,9 @@ class InstanceModeration < ApplicationRecord state :blocked error_on_all_events do |e| - ExceptionNotifier.notify_exception(e, data: { site: site.name, instance: instance.hostname, instance_moderation: id }) + ExceptionNotifier.notify_exception(e, + data: { site: site.name, instance: instance.hostname, + instance_moderation: id }) end after_all_events do diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index a9765918..78989e15 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -134,7 +134,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, # En caso de que algún campo necesite realizar acciones antes de ser # guardado def save - if !changed? + unless changed? self[:value] = document_value if private? return true diff --git a/app/models/social_inbox.rb b/app/models/social_inbox.rb index 183ebfb0..adeedffc 100644 --- a/app/models/social_inbox.rb +++ b/app/models/social_inbox.rb @@ -45,7 +45,7 @@ class SocialInbox # @param url [String] # @return [DistributedPress::V1::Social::Client] def client_for(url) - raise "Falló generar un cliente" if url.blank? + raise 'Falló generar un cliente' if url.blank? @client_for ||= {} @client_for[url] ||= @@ -54,7 +54,7 @@ class SocialInbox public_key_url: public_key_url, private_key_pem: site.private_key_pem, logger: Rails.logger, - cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER']) + cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV.fetch('REDIS_SERVER', nil)) ) end diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 53e953f3..1a85d401 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -222,8 +222,6 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do end end - private - # Asignar un rol a cada deploy si no lo tenía ya def add_role_to_deploys!(role = current_role) site.deploys.each do |deploy| diff --git a/config/environments/production.rb b/config/environments/production.rb index bc7cecd7..5b0667a5 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -62,7 +62,7 @@ Rails.application.configure do config.log_tags = %i[request_id] # Use a different cache store in production. - config.cache_store = :redis_cache_store, { url: ENV['REDIS_SERVER'] } + config.cache_store = :redis_cache_store, { url: ENV.fetch('REDIS_SERVER', nil) } config.action_mailer.perform_caching = false @@ -87,7 +87,7 @@ Rails.application.configure do config.lograge.enabled = true # Use default logging formatter so that PID and timestamp are not # suppressed. - config.log_formatter = ::Logger::Formatter.new + config.log_formatter = Logger::Formatter.new # Use a different logger for distributed setups. require 'syslog/logger' @@ -140,9 +140,10 @@ Rails.application.configure do domain: ENV.fetch('SUTTY', 'sutty.nl'), enable_starttls_auto: false } - config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl") } + config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', 'noreply@sutty.nl') } - config.middleware.use ExceptionNotification::Rack, gitlab: {}, error_grouping: true, ignore_exceptions: ['DeployJob::DeployAlreadyRunningException'] + config.middleware.use ExceptionNotification::Rack, gitlab: {}, error_grouping: true, + ignore_exceptions: ['DeployJob::DeployAlreadyRunningException'] Rails.application.routes.default_url_options[:host] = "panel.#{ENV.fetch('SUTTY', 'sutty.nl')}" Rails.application.routes.default_url_options[:protocol] = 'https' diff --git a/config/initializers/que_web.rb b/config/initializers/que_web.rb index 192256db..a6b87cf8 100644 --- a/config/initializers/que_web.rb +++ b/config/initializers/que_web.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true Que::Web.use(Rack::Auth::Basic) do |user, password| - [user, password] == [ENV['HTTP_BASIC_USER'], ENV['HTTP_BASIC_PASSWORD']] + [user, password] == [ENV.fetch('HTTP_BASIC_USER', nil), ENV.fetch('HTTP_BASIC_PASSWORD', nil)] end diff --git a/db/migrate/20240227142019_create_fediblock_states.rb b/db/migrate/20240227142019_create_fediblock_states.rb index c99cf63d..1e718343 100644 --- a/db/migrate/20240227142019_create_fediblock_states.rb +++ b/db/migrate/20240227142019_create_fediblock_states.rb @@ -16,9 +16,7 @@ class CreateFediblockStates < ActiveRecord::Migration[6.1] # Todas las listas están activas por defecto DeploySocialDistributedPress.find_each do |deploy| ActivityPub::Fediblock.find_each do |fediblock| - FediblockState.create(site: deploy.site, fediblock: fediblock, aasm_state: 'disabled').tap do |f| - f.enable! - end + FediblockState.create(site: deploy.site, fediblock: fediblock, aasm_state: 'disabled').tap(&:enable!) end end end diff --git a/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb b/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb index a0c29311..e22d759b 100644 --- a/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb +++ b/db/migrate/20240313204105_brs_decompressor_corrupted_source_error.rb @@ -4,9 +4,11 @@ # decompresión class BrsDecompressorCorruptedSourceError < ActiveRecord::Migration[6.1] def up - raise unless HTTParty.get("https://mas.to/api/v2/instance", headers: { "Accept-Encoding": "br;q=1.0,gzip;q=1.0,deflate;q=0.6,identity;q=0.3" }).ok? + raise unless HTTParty.get('https://mas.to/api/v2/instance', + headers: { 'Accept-Encoding': 'br;q=1.0,gzip;q=1.0,deflate;q=0.6,identity;q=0.3' }).ok? - QueJob.where("last_error_message like '%BRS::DecompressorCorruptedSourceError%'").update_all(error_count: 0, run_at: Time.now) + QueJob.where("last_error_message like '%BRS::DecompressorCorruptedSourceError%'").update_all(error_count: 0, + run_at: Time.now) end def down; end diff --git a/db/migrate/20240314205923_fix_activity_type.rb b/db/migrate/20240314205923_fix_activity_type.rb index 042de8eb..e6640ff8 100644 --- a/db/migrate/20240314205923_fix_activity_type.rb +++ b/db/migrate/20240314205923_fix_activity_type.rb @@ -4,7 +4,9 @@ class FixActivityType < ActiveRecord::Migration[6.1] def up %w[Like Announce].each do |type| - ActivityPub::Activity.where(Arel.sql("content->>'type' = '#{type}'")).update_all(type: "ActivityPub::Activity::#{type}", updated_at: Time.now) + ActivityPub::Activity.where(Arel.sql("content->>'type' = '#{type}'")).update_all( + type: "ActivityPub::Activity::#{type}", updated_at: Time.now + ) end end diff --git a/db/migrate/20240318183846_fix_duplicate_objects.rb b/db/migrate/20240318183846_fix_duplicate_objects.rb index 88d23c6f..9f02c3db 100644 --- a/db/migrate/20240318183846_fix_duplicate_objects.rb +++ b/db/migrate/20240318183846_fix_duplicate_objects.rb @@ -3,7 +3,7 @@ # De alguna forma se guardaron objetos duplicados! class FixDuplicateObjects < ActiveRecord::Migration[6.1] def up - ActivityPub::Object.group(:uri).count.select { |_, v| v > 1 }.keys.each do |uri| + ActivityPub::Object.group(:uri).count.select { |_, v| v > 1 }.each_key do |uri| objects = ActivityPub::Object.where(uri: uri) deleted_ids = objects[1..].map(&:delete).map(&:id) diff --git a/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb b/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb index d78439b2..f751123a 100644 --- a/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb +++ b/db/migrate/20240319124212_add_fedipact_to_fediblocks.rb @@ -14,9 +14,7 @@ class AddFedipactToFediblocks < ActiveRecord::Migration[6.1] ) DeploySocialDistributedPress.find_each do |deploy| - FediblockState.create(site: deploy.site, fediblock: fedipact, aasm_state: 'disabled').tap do |f| - f.enable! - end + FediblockState.create(site: deploy.site, fediblock: fedipact, aasm_state: 'disabled').tap(&:enable!) end end diff --git a/db/migrate/20240319144735_add_missing_unique_indexes.rb b/db/migrate/20240319144735_add_missing_unique_indexes.rb index 7d18c8e8..2f6ef1aa 100644 --- a/db/migrate/20240319144735_add_missing_unique_indexes.rb +++ b/db/migrate/20240319144735_add_missing_unique_indexes.rb @@ -4,14 +4,14 @@ # no es válida y por eso teníamos objetos duplicados. class AddMissingUniqueIndexes < ActiveRecord::Migration[6.1] def up - ActivityPub::Object.group(:uri).count.select { |_, v| v > 1 }.keys.each do |uri| + ActivityPub::Object.group(:uri).count.select { |_, v| v > 1 }.each_key do |uri| objects = ActivityPub::Object.where(uri: uri) deleted_ids = objects[1..].map(&:delete).map(&:id) ActivityPub.where(object_id: deleted_ids).update_all(object_id: objects.first.id, updated_at: Time.now) end - ActivityPub::Actor.group(:uri).count.select { |_, v| v > 1 }.keys.each do |uri| + ActivityPub::Actor.group(:uri).count.select { |_, v| v > 1 }.each_key do |uri| objects = ActivityPub::Actor.where(uri: uri) deleted_ids = objects[1..].map(&:delete).map(&:id) @@ -21,7 +21,7 @@ class AddMissingUniqueIndexes < ActiveRecord::Migration[6.1] ActivityPub::RemoteFlag.where(actor_id: deleted_ids).update_all(actor_id: objects.first.id, updated_at: Time.now) end - ActivityPub::Instance.group(:hostname).count.select { |_, v| v > 1 }.keys.each do |hostname| + ActivityPub::Instance.group(:hostname).count.select { |_, v| v > 1 }.each_key do |hostname| objects = ActivityPub::Instance.where(hostname: hostname) deleted_ids = objects[1..].map(&:delete).map(&:id) diff --git a/db/seeds.rb b/db/seeds.rb index 8e8c291f..41474883 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -20,13 +20,13 @@ if CodeOfConduct.count.zero? YAML.safe_load(File.read('db/seeds/codes_of_conduct.yml')).each do |coc| CodeOfConduct.new(**coc).save! end -end +end if PrivacyPolicy.count.zero? YAML.safe_load(File.read('db/seeds/privacy_policies.yml')).each do |pp| PrivacyPolicy.new(**pp).save! end -end +end YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| ActivityPub::Fediblock.find_or_create_by(id: fediblock['id']).tap do |f| From fe78c354a77e55668d235e6a68df66c72b4aa86b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:18:34 -0300 Subject: [PATCH 786/814] ci: instalar dependencias antes de usarlas --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dceb1a42..2830cd86 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,6 +36,7 @@ assets: - *cache-node - *cache-task before_script: + - *apk-add - "gitlab_ci_log_section --name git --header=\"Configuring git\"" - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" @@ -43,7 +44,6 @@ assets: - "gitlab_ci_log_section --name git --end" - "gitlab_ci_log_section --name apk --header=\"Installing dependencies\"" - "apk add brotli" - - *apk-add - *disable-hainish - "gitlab_ci_log_section --name apk --end" script: From 6ceef5465fa4a75b163f684cd5479d5e06d05d54 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:25:20 -0300 Subject: [PATCH 787/814] chore: haml-lint --- app/views/sites/index.haml | 39 ++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/app/views/sites/index.haml b/app/views/sites/index.haml index 840efb76..1befa2d0 100644 --- a/app/views/sites/index.haml +++ b/app/views/sites/index.haml @@ -4,7 +4,7 @@ %p.lead= t('.help') - if policy(Site).new? = link_to t('sites.new.title'), new_site_path, - class: 'btn btn-secondary' + class: 'btn btn-secondary' %section.col - if @sites.empty? @@ -15,11 +15,14 @@ %tbody - @sites.each do |site| - next unless site.jekyll? + %tr %td %h2 - if policy(site).show? - = link_to site.title, site_posts_path(site, locale: site.default_locale) + = link_to site.title, + site_posts_path(site, + locale: site.default_locale) - else = site.title %p.lead= site.description @@ -27,27 +30,27 @@ = 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' + 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' + 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') + 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) + tooltip: t('usuaries.index.help.self'), + text: t('usuaries.index.title'), + type: 'info', + link: site_usuaries_path(site) From 074549613c90df65359d798a2b58a99ea7afda05 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:34:41 -0300 Subject: [PATCH 788/814] =?UTF-8?q?ci:=20compilar=20assets=20en=20producci?= =?UTF-8?q?=C3=B3n=20y=20testing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2830cd86..262e127a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,7 +28,8 @@ assets: stage: "deploy" only: - "rails" - - "17.3.alpine.panel.sutty.nl" + - "production.panel.sutty.nl" + - "panel.sutty.nl" except: - "schedules" cache: From 5810d0c3df67db68c24d69d5afdd473f56541baf Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:34:54 -0300 Subject: [PATCH 789/814] ci: pushear de vuelta a la rama --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 262e127a..9dff2f3a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,7 +52,7 @@ assets: - "go-task assets" after_script: - "git add public && git commit -m \"ci: assets [skip ci]\"" - - "git push -o ci.skip" + - "git push -o ci.skip origin HEAD:${CI_COMMIT_BRANCH}" gem-audit: stage: "test" only: From f8e281141a03f2a8b555cd65427e1a93cfe0349a Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 16:40:46 -0300 Subject: [PATCH 790/814] =?UTF-8?q?ci:=20forzar=20recompilaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/packs/application.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index e10e2b5d..d634a64e 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -42,3 +42,5 @@ Turbolinks.start() ActiveStorage.start() window.htmx = require('htmx.org/dist/htmx.js') + +// rebuild From 5334a2e046a41138ead1a0f3841228b987c7cd65 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 17:05:09 -0300 Subject: [PATCH 791/814] =?UTF-8?q?ci:=20forzar=20compilaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/packs/application.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index d634a64e..e10e2b5d 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -42,5 +42,3 @@ Turbolinks.start() ActiveStorage.start() window.htmx = require('htmx.org/dist/htmx.js') - -// rebuild From 368cb065ea890eab57df858fc2a42c6fff7330a0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 17:13:15 -0300 Subject: [PATCH 792/814] ci: el token correcto [skip ci] --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9dff2f3a..a906fc2a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -41,7 +41,7 @@ assets: - "gitlab_ci_log_section --name git --header=\"Configuring git\"" - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" + - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_CI_PUSH_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" - "gitlab_ci_log_section --name git --end" - "gitlab_ci_log_section --name apk --header=\"Installing dependencies\"" - "apk add brotli" From 330e82041bbd4d6fc1831ba7234e4ed149aff0d3 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 May 2024 18:49:29 -0300 Subject: [PATCH 793/814] =?UTF-8?q?fix:=20no=20filtrar=20informaci=C3=B3n?= =?UTF-8?q?=20privada=20en=20YAML.dump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/application_record.rb | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index f09c4dd4..6662ddeb 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -7,6 +7,23 @@ class ApplicationRecord < ActiveRecord::Base # # @return [String] def to_yaml(options = {}) - self.class.inspection_filter.filter(serializable_hash).to_yaml(options) + pruned_attributes.to_yaml(options) + end + + # Devuelve todos los atributos menos los filtrados + # + # @return [Hash] + def pruned_attributes + self.class.inspection_filter.filter(serializable_hash) + end + + # @param coder [Psych::Coder] + # @return nil + def encode_with(coder) + pruned_attributes.each_pair do |attr, value| + coder[attr] = value + end + + nil end end From 08b07a51581ced69509e84eef95b4c91ce36e171 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 3 May 2024 12:42:05 -0300 Subject: [PATCH 794/814] fix: permitir sitios sin layouts #14329 --- app/models/site.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/site.rb b/app/models/site.rb index d47a8e50..9c94c31b 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -289,6 +289,8 @@ class Site < ApplicationRecord # # @return [Hash] { post: Layout } def layouts + return {} if data['layouts'].blank? + # Crea un Struct dinámico cuyas llaves son los nombres de todos los # layouts. Si pasamos un layout que no existe, obtenemos un # NoMethodError From eb80a83ddd17b31d7dcf0a2cff634a3b593d8230 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 May 2024 12:01:34 -0300 Subject: [PATCH 795/814] fix: editor 0.1.29 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index eea0473f..088316bc 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "@rails/activestorage": "^6.1.3-1", "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.4.4", - "@suttyweb/editor": "^0.1.27", + "@suttyweb/editor": "^0.1.29", "babel-loader": "^8.2.2", "bs-custom-file-input": "^1.3.4", "chart.js": "^3.5.1", diff --git a/yarn.lock b/yarn.lock index 7a81a221..fc6ae7cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1975,10 +1975,10 @@ resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz" integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A== -"@suttyweb/editor@^0.1.27": - version "0.1.27" - resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.27.tgz#9415a0b767e72dbe4fbf42ce87e62fb8f5125c31" - integrity sha512-Ts9TZtGiRIaHm+ffVBRl+/nuVcANWZNtFsrGacoajgEsagaIyA1cq8qjiNpPoM5ne9vTba3cAaLP04V/uEIhBw== +"@suttyweb/editor@^0.1.29": + version "0.1.29" + resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.29.tgz#8b5c6ae4e4d546002a96ecd65765d77d2a88d415" + integrity sha512-GshI8wE5UqXge2RhwAUxUXTRLPoOX7US9xVu1aLqT/deT/hDyN9S3PxVn9cJBf7uPHEqBzYXGDKWWF79PLqGHw== dependencies: "@floating-ui/dom" "^1.5.1" linkifyjs "^4.1.1" From 6972aafa75dd64e2195194c78d8bee2842754d33 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 May 2024 12:03:38 -0300 Subject: [PATCH 796/814] ci: pushear assets --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a906fc2a..0cf09b87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -41,7 +41,7 @@ assets: - "gitlab_ci_log_section --name git --header=\"Configuring git\"" - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" - - "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_CI_PUSH_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" + - "git remote set-url --push origin \"https://GITLAB_CI_PUSH_TOKEN:${GITLAB_CI_PUSH_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" - "gitlab_ci_log_section --name git --end" - "gitlab_ci_log_section --name apk --header=\"Installing dependencies\"" - "apk add brotli" From 0d1ca35e6b4da250b73e4a247f23a0f454573038 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 May 2024 12:18:25 -0300 Subject: [PATCH 797/814] ci: probar que podemos pushear! --- .gitlab-ci.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0cf09b87..f736a316 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,19 @@ variables: LC_ALL: "C.UTF-8" HAINISH: "" cache: +push: + stage: "deploy" + only: + - "rails" + except: + - "schedules" + before_script: + - "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\"" + - "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\"" + - "git remote set-url --push origin \"https://GITLAB_CI_PUSH_TOKEN:${GITLAB_CI_PUSH_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\"" + script: + - "git commit --allow-empty -m \"ci: test [skip ci]\"" + - "git push -o ci.skip origin HEAD:${CI_COMMIT_BRANCH}" assets: stage: "deploy" only: From 2407ec11d9766297cac44eb3675f4792cf2559b2 Mon Sep 17 00:00:00 2001 From: fauno Date: Thu, 9 May 2024 15:19:09 +0000 Subject: [PATCH 798/814] ci: test [skip ci] From 088b495ed394b07ca65b1c74aed255e1088da55a Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 May 2024 12:20:55 -0300 Subject: [PATCH 799/814] ci: fallar temprano si ya no se puede pushear --- .gitlab-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f736a316..c72a632d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,6 @@ +stages: +- "test" +- "deploy" .apk-add: &apk-add - "apk add go-task diffutils gitlab_ci_log_section" .disable-hainish: &disable-hainish @@ -25,7 +28,7 @@ variables: HAINISH: "" cache: push: - stage: "deploy" + stage: "test" only: - "rails" except: From 186f979157723c0514d7ae7592d98958a2afb026 Mon Sep 17 00:00:00 2001 From: fauno Date: Sat, 18 May 2024 14:22:34 +0000 Subject: [PATCH 800/814] ci: test [skip ci] From e04640c8c6d794a7b30164747b0335c41c235007 Mon Sep 17 00:00:00 2001 From: fauno Date: Sat, 18 May 2024 14:24:14 +0000 Subject: [PATCH 801/814] ci: test [skip ci] From eef6ff58c88bec560d59d7d3b9bc3f497f859f54 Mon Sep 17 00:00:00 2001 From: fauno Date: Sat, 18 May 2024 14:32:08 +0000 Subject: [PATCH 802/814] ci: test [skip ci] From 9d87da2e5436bebb812129bcef82ac41db13a354 Mon Sep 17 00:00:00 2001 From: fauno Date: Wed, 29 May 2024 19:40:17 +0000 Subject: [PATCH 803/814] ci: test [skip ci] From 50a4823dad3e1c93a2e1b34373584cbe92376941 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 May 2024 10:06:44 -0300 Subject: [PATCH 804/814] =?UTF-8?q?fix:=20arreglar=20migraci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20240227134845_create_fediblocks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20240227134845_create_fediblocks.rb b/db/migrate/20240227134845_create_fediblocks.rb index 03f65f7c..1a61ccba 100644 --- a/db/migrate/20240227134845_create_fediblocks.rb +++ b/db/migrate/20240227134845_create_fediblocks.rb @@ -12,7 +12,7 @@ class CreateFediblocks < ActiveRecord::Migration[6.1] t.string :url, null: false t.string :download_url, null: false t.string :format, null: false - t.jsonb :instances, default: [] + t.jsonb :hostnames, default: [] end YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| From 78fd8c933a35fcbf839ab783bcc892d4062b57fd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 May 2024 10:06:44 -0300 Subject: [PATCH 805/814] =?UTF-8?q?fix:=20arreglar=20migraci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20240227134845_create_fediblocks.rb | 2 +- ...0228171335_rename_fediblock_instances_to_hostnames.rb | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb diff --git a/db/migrate/20240227134845_create_fediblocks.rb b/db/migrate/20240227134845_create_fediblocks.rb index 03f65f7c..1a61ccba 100644 --- a/db/migrate/20240227134845_create_fediblocks.rb +++ b/db/migrate/20240227134845_create_fediblocks.rb @@ -12,7 +12,7 @@ class CreateFediblocks < ActiveRecord::Migration[6.1] t.string :url, null: false t.string :download_url, null: false t.string :format, null: false - t.jsonb :instances, default: [] + t.jsonb :hostnames, default: [] end YAML.safe_load(File.read('db/seeds/activity_pub/fediblocks.yml')).each do |fediblock| diff --git a/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb b/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb deleted file mode 100644 index bad343f2..00000000 --- a/db/migrate/20240228171335_rename_fediblock_instances_to_hostnames.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -# Cambia el nombre de la columna para que podamos obtener todas las -# instancias de un fediblock -class RenameFediblockInstancesToHostnames < ActiveRecord::Migration[6.1] - def change - rename_column :activity_pub_fediblocks, :instances, :hostnames - end -end From 12dfd1e9e71519fd124b767085563bf76d3a659e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 31 May 2024 10:16:04 -0300 Subject: [PATCH 806/814] fix: oliphant blocklist --- db/seeds/activity_pub/fediblocks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/seeds/activity_pub/fediblocks.yml b/db/seeds/activity_pub/fediblocks.yml index c977f9bf..35fe38cd 100644 --- a/db/seeds/activity_pub/fediblocks.yml +++ b/db/seeds/activity_pub/fediblocks.yml @@ -6,7 +6,7 @@ id: "9046789a-5de8-4b16-beed-796060f8f3cc" - title: "Oliphant Tier 0" url: "https://writer.oliphant.social/oliphant/the-oliphant-social-blocklist" - download_url: "https://codeberg.org/oliphant/blocklists/raw/branch/main/blocklists/mastodon/tier0.csv" + download_url: "https://codeberg.org/oliphant/blocklists/raw/branch/main/blocklists/mastodon/seirdy-tier0.csv" format: "mastodon" id: "fc1efcb8-7e68-4a76-ae9e-0c447752b12b" - title: "The Bad Space (90%)" From e35fa8746436fdd62caa3b10c3314a4de8cd260d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 18 Jun 2024 10:45:57 -0300 Subject: [PATCH 807/814] fix: ya no es necesario estimar visitas #16542 --- app/controllers/stats_controller.rb | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index c2c7bc58..bc5bb962 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -59,9 +59,6 @@ class StatsController < ApplicationController .order('sum(value) desc') .sum(:value) .transform_values(&:to_i) - .transform_values do |v| - v * nodes - end end end end @@ -73,9 +70,6 @@ class StatsController < ApplicationController stats = rollup_scope.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| series.each do |serie| serie[:name] = serie.dig(:dimensions, 'host') - serie[:data].transform_values! do |value| - value * nodes - end end end @@ -99,9 +93,6 @@ class StatsController < ApplicationController stats = rollup_scope.where_dimensions(**options).multi_series('host|uri', interval: interval).tap do |series| series.each do |serie| serie[:name] = serie[:dimensions].slice('host', 'uri').values.join.sub('/index.html', '/') - serie[:data].transform_values! do |value| - value * nodes - end end end @@ -197,21 +188,6 @@ class StatsController < ApplicationController end end - # Obtiene la cantidad de nodos de Sutty, para poder calcular la - # cantidad de visitas. - # - # Como repartimos las visitas por nodo rotando las IPs en el - # nameserver y los resolvedores de DNS eligen un nameserver - # aleatoriamente, la cantidad de visitas se reparte - # equitativamente. - # - # XXX: Remover cuando podamos centralizar los AccessLog - # - # @return [Integer] - def nodes - @nodes ||= ENV.fetch('NODES', 1).to_i - end - def period @period ||= begin p = params.permit(:period_start, :period_end) From 11e2353c2fdebcbddb7a18ad02342852cd84ba11 Mon Sep 17 00:00:00 2001 From: fauno Date: Tue, 18 Jun 2024 15:14:57 +0000 Subject: [PATCH 808/814] ci: test [skip ci] From 31a2ca630ff9799e8114f60dc2b7ac4954e31796 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 30 Jul 2024 11:37:58 -0300 Subject: [PATCH 809/814] fix: soportar actores de micropub #16939 --- app/validators/url_validator.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb index 291f9288..8cfc5fcc 100644 --- a/app/validators/url_validator.rb +++ b/app/validators/url_validator.rb @@ -14,7 +14,6 @@ class UrlValidator < ActiveModel::EachValidator record.errors.add(attribute, :scheme_missing) if uri.scheme.blank? record.errors.add(attribute, :host_missing) if uri.host.blank? - record.errors.add(attribute, :path_missing) if uri.path.blank? rescue URI::Error record.errors.add(attribute, :invalid) end From 89fb303227cbcc520e6638a73ba2678668b227f7 Mon Sep 17 00:00:00 2001 From: fauno Date: Wed, 7 Aug 2024 14:48:24 +0000 Subject: [PATCH 810/814] ci: test [skip ci] From 31fa9933f8146803de2be2951400584c323ed27f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 3 Oct 2024 12:02:40 -0300 Subject: [PATCH 811/814] =?UTF-8?q?fix:=20actualizaci=C3=B3n=20de=20cuidad?= =?UTF-8?q?os?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 2 +- Gemfile.lock | 158 +++++++++++++++++++++++++-------------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/Gemfile b/Gemfile index 3677d738..5d673dd0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ # frozen_string_literal: true -source ENV.fetch('GEMS_SOURCE', 'https://17.3.alpine.gems.sutty.nl') +source ENV.fetch('GEMS_SOURCE', 'https://gems.sutty.nl') ruby "~> #{ENV.fetch('RUBY_VERSION', '3.1')}" diff --git a/Gemfile.lock b/Gemfile.lock index 2adf2f1b..33cd65a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -25,64 +25,64 @@ GIT groupdate (>= 5.2) GEM - remote: https://17.3.alpine.gems.sutty.nl/ + remote: https://gems.sutty.nl/ specs: aasm (5.5.0) concurrent-ruby (~> 1.0) - actioncable (6.1.7.4) - actionpack (= 6.1.7.4) - activesupport (= 6.1.7.4) + actioncable (6.1.7.8) + actionpack (= 6.1.7.8) + activesupport (= 6.1.7.8) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.4) - actionpack (= 6.1.7.4) - activejob (= 6.1.7.4) - activerecord (= 6.1.7.4) - activestorage (= 6.1.7.4) - activesupport (= 6.1.7.4) + actionmailbox (6.1.7.8) + actionpack (= 6.1.7.8) + activejob (= 6.1.7.8) + activerecord (= 6.1.7.8) + activestorage (= 6.1.7.8) + activesupport (= 6.1.7.8) mail (>= 2.7.1) - actionmailer (6.1.7.4) - actionpack (= 6.1.7.4) - actionview (= 6.1.7.4) - activejob (= 6.1.7.4) - activesupport (= 6.1.7.4) + actionmailer (6.1.7.8) + actionpack (= 6.1.7.8) + actionview (= 6.1.7.8) + activejob (= 6.1.7.8) + activesupport (= 6.1.7.8) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.7.4) - actionview (= 6.1.7.4) - activesupport (= 6.1.7.4) + actionpack (6.1.7.8) + actionview (= 6.1.7.8) + activesupport (= 6.1.7.8) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.4) - actionpack (= 6.1.7.4) - activerecord (= 6.1.7.4) - activestorage (= 6.1.7.4) - activesupport (= 6.1.7.4) + actiontext (6.1.7.8) + actionpack (= 6.1.7.8) + activerecord (= 6.1.7.8) + activestorage (= 6.1.7.8) + activesupport (= 6.1.7.8) nokogiri (>= 1.8.5) - actionview (6.1.7.4) - activesupport (= 6.1.7.4) + actionview (6.1.7.8) + activesupport (= 6.1.7.8) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.7.4) - activesupport (= 6.1.7.4) + activejob (6.1.7.8) + activesupport (= 6.1.7.8) globalid (>= 0.3.6) - activemodel (6.1.7.4) - activesupport (= 6.1.7.4) - activerecord (6.1.7.4) - activemodel (= 6.1.7.4) - activesupport (= 6.1.7.4) - activestorage (6.1.7.4) - actionpack (= 6.1.7.4) - activejob (= 6.1.7.4) - activerecord (= 6.1.7.4) - activesupport (= 6.1.7.4) + activemodel (6.1.7.8) + activesupport (= 6.1.7.8) + activerecord (6.1.7.8) + activemodel (= 6.1.7.8) + activesupport (= 6.1.7.8) + activestorage (6.1.7.8) + actionpack (= 6.1.7.8) + activejob (= 6.1.7.8) + activerecord (= 6.1.7.8) + activesupport (= 6.1.7.8) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.4) + activesupport (6.1.7.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -114,7 +114,7 @@ GEM sassc-rails (>= 2.0.0) brakeman (6.1.1) racc - builder (3.2.4) + builder (3.3.0) bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) @@ -213,7 +213,7 @@ GEM eventmachine (>= 0.12.9) http_parser.rb (~> 0) errbase (0.2.2) - erubi (1.12.0) + erubi (1.13.0) eventmachine (1.2.7-x86_64-linux-musl) exception_notification (4.5.0) actionmailer (>= 5.2, < 8) @@ -226,7 +226,7 @@ GEM railties (>= 5.0.0) fast_blank (1.0.1-x86_64-linux-musl) fast_jsonparser (0.5.0-x86_64-linux-musl) - ffi (1.15.5-x86_64-linux-musl) + ffi (1.17.0-x86_64-linux-musl) flamegraph (0.9.5) forwardable-extended (2.6.0) friendly_id (5.5.0) @@ -276,7 +276,7 @@ GEM multi_xml (>= 0.5.2) httparty-cache (0.0.6) httparty (~> 0.18) - i18n (1.14.1) + i18n (1.14.6) concurrent-ruby (~> 1.0) icalendar (2.8.0) ice_cube (~> 0.16) @@ -359,34 +359,34 @@ GEM net-imap net-pop net-smtp - marcel (1.0.2) + marcel (1.0.4) memory_profiler (1.0.1) mercenary (0.4.0) - method_source (1.0.0) + method_source (1.1.0) mini_histogram (0.3.1) mini_magick (4.12.0) mini_mime (1.1.5) - mini_portile2 (2.8.5) - minitest (5.21.1) + mini_portile2 (2.8.6) + minitest (5.25.1) mobility (1.2.9) i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) mustermann (3.0.0) ruby2_keywords (~> 0.0.1) - net-imap (0.4.9) + net-imap (0.4.16) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.4.0) + net-smtp (0.5.0) net-protocol net-ssh (7.2.1) netaddr (2.0.6) - nio4r (2.7.0-x86_64-linux-musl) - nokogiri (1.16.0-x86_64-linux-musl) + nio4r (2.7.3-x86_64-linux-musl) + nokogiri (1.16.7-x86_64-linux-musl) mini_portile2 (~> 2.8.2) racc (~> 1.4) orm_adapter (0.5.0) @@ -407,8 +407,8 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.4) - puma (6.4.2-x86_64-linux-musl) + public_suffix (5.0.5) + puma (6.4.3-x86_64-linux-musl) nio4r (~> 2.0) pundit (2.3.1) activesupport (>= 3.0.0) @@ -416,9 +416,9 @@ GEM que-web (0.10.0) que (>= 1) sinatra - racc (1.7.3-x86_64-linux-musl) - rack (2.2.8) - rack-cors (2.0.1) + racc (1.8.1-x86_64-linux-musl) + rack (2.2.9) + rack-cors (2.0.2) rack (>= 2.0.0) rack-mini-profiler (3.1.0) rack (>= 1.2.0) @@ -429,20 +429,20 @@ GEM rack rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.4) - actioncable (= 6.1.7.4) - actionmailbox (= 6.1.7.4) - actionmailer (= 6.1.7.4) - actionpack (= 6.1.7.4) - actiontext (= 6.1.7.4) - actionview (= 6.1.7.4) - activejob (= 6.1.7.4) - activemodel (= 6.1.7.4) - activerecord (= 6.1.7.4) - activestorage (= 6.1.7.4) - activesupport (= 6.1.7.4) + rails (6.1.7.8) + actioncable (= 6.1.7.8) + actionmailbox (= 6.1.7.8) + actionmailer (= 6.1.7.8) + actionpack (= 6.1.7.8) + actiontext (= 6.1.7.8) + actionview (= 6.1.7.8) + activejob (= 6.1.7.8) + activemodel (= 6.1.7.8) + activerecord (= 6.1.7.8) + activestorage (= 6.1.7.8) + activesupport (= 6.1.7.8) bundler (>= 1.15.0) - railties (= 6.1.7.4) + railties (= 6.1.7.8) sprockets-rails (>= 2.0.0) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) @@ -456,14 +456,14 @@ GEM railties (>= 6.0.0, < 8) rails_warden (0.6.0) warden (>= 1.2.0) - railties (6.1.7.4) - actionpack (= 6.1.7.4) - activesupport (= 6.1.7.4) + railties (6.1.7.8) + actionpack (= 6.1.7.8) + activesupport (= 6.1.7.8) method_source rake (>= 12.2) thor (~> 1.0) rainbow (3.1.1) - rake (13.1.0) + rake (13.2.1) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) @@ -492,7 +492,7 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.6) + rexml (3.3.7) rgl (0.6.3) pairing_heap (>= 0.3.0) rexml (~> 3.2, >= 3.2.4) @@ -563,9 +563,9 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) sqlite3 (1.7.0-x86_64-linux-musl) mini_portile2 (~> 2.8.0) @@ -579,8 +579,8 @@ GEM temple (0.10.3) terminal-table (2.0.0) unicode-display_width (~> 1.1, >= 1.1.1) - thor (1.3.0) - tilt (2.3.0) + thor (1.3.2) + tilt (2.4.0) timecop (0.9.6) timeout (0.4.1) turbolinks (5.2.1) @@ -618,7 +618,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.34) - zeitwerk (2.6.12) + zeitwerk (2.6.18) PLATFORMS x86_64-linux-musl From cd78052bf5ff1ab14dc47e7907099095aa79ea0e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 4 Oct 2024 11:04:33 -0300 Subject: [PATCH 812/814] fix: no usamos js de bootstrap --- .bundler-audit.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .bundler-audit.yml diff --git a/.bundler-audit.yml b/.bundler-audit.yml new file mode 100644 index 00000000..cf3af0b3 --- /dev/null +++ b/.bundler-audit.yml @@ -0,0 +1,3 @@ +--- +ignore: +- "CVE-2024-6531" From 63d2e7af46929df844ba106a2097e9b01189a184 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 4 Oct 2024 11:15:37 -0300 Subject: [PATCH 813/814] fix: actualizaciones de cuidados --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 33cd65a1..775332ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -610,14 +610,14 @@ GEM rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) - webrick (1.8.1) + webrick (1.8.2) websocket (1.2.9) websocket-driver (0.7.6-x86_64-linux-musl) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.34) + yard (0.9.36) zeitwerk (2.6.18) PLATFORMS From 538f941f77ac96ab593fa4460d0ab90ed91acd8a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 9 Oct 2024 13:52:22 -0300 Subject: [PATCH 814/814] feat: poder crear sitios en testing los sitios en testing no se sincronizan con otros servidores y siempre son locales al panel --- app/views/sites/_form.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index ec2712bf..8d909d79 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -23,7 +23,7 @@ = f.text_field :name, class: form_control(site, :name), required: true, - pattern: '^([a-z0-9][a-z0-9\-]*)?[a-z0-9\.]$', + pattern: '^([a-z0-9][a-z0-9\-]*)?[a-z0-9\.](\.testing)?$', minlength: 1, maxlength: 63 - if invalid? site, :name