decidim-core 0.25.2 → 0.26.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/cells/decidim/activity_cell.rb +2 -1
- data/app/cells/decidim/author/flag_user.erb +1 -1
- data/app/cells/decidim/author/profile_inline.erb +1 -1
- data/app/cells/decidim/author/withdraw.erb +2 -2
- data/app/cells/decidim/author_cell.rb +32 -0
- data/app/cells/decidim/card_m_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/cta_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/hero_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_content_banner/show.erb +1 -1
- data/app/cells/decidim/content_blocks/last_activity_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/stats_cell.rb +12 -0
- data/app/cells/decidim/endorsers_list_cell.rb +3 -1
- data/app/cells/decidim/flag_modal/flag_user.erb +2 -2
- data/app/cells/decidim/flag_modal/show.erb +2 -2
- data/app/cells/decidim/flag_modal_cell.rb +10 -0
- data/app/cells/decidim/notification/show.erb +31 -0
- data/app/cells/decidim/notification_cell.rb +20 -0
- data/app/cells/decidim/notifications/show.erb +1 -24
- data/app/cells/decidim/notifications_cell.rb +0 -1
- data/app/cells/decidim/user_conversation/conversation_header.erb +1 -1
- data/app/cells/decidim/user_conversation/show.erb +4 -2
- data/app/cells/decidim/user_conversations/conversation_item.erb +1 -1
- data/app/commands/decidim/create_editor_image.rb +41 -0
- data/app/controllers/decidim/cookie_policy_controller.rb +2 -0
- data/app/controllers/decidim/editor_images_controller.rb +47 -0
- data/app/controllers/decidim/user_activities_controller.rb +2 -1
- data/app/forms/decidim/editor_image_form.rb +16 -0
- data/app/helpers/decidim/amendments_helper.rb +1 -1
- data/app/helpers/decidim/application_helper.rb +2 -2
- data/app/helpers/decidim/messaging/conversation_helper.rb +32 -3
- data/app/helpers/decidim/resource_versions_helper.rb +1 -1
- data/app/helpers/decidim/sanitize_helper.rb +65 -0
- data/app/models/decidim/editor_image.rb +14 -0
- data/app/models/decidim/messaging/conversation.rb +9 -0
- data/app/models/decidim/participatory_space_private_user.rb +16 -0
- data/app/models/decidim/user.rb +3 -3
- data/app/models/decidim/user_group.rb +40 -0
- data/app/packs/entrypoints/decidim_core.js +1 -0
- data/app/packs/src/decidim/dialog_mode.js +143 -0
- data/app/packs/src/decidim/dialog_mode.test.js +168 -0
- data/app/packs/src/decidim/editor.js +56 -14
- data/app/packs/src/decidim/form_attachments.js +5 -0
- data/app/packs/src/decidim/index.js +4 -0
- data/app/packs/src/decidim/vendor/image-resize.min.js +3 -0
- data/app/packs/src/decidim/vendor/image-upload.min.js +8 -0
- data/app/packs/stylesheets/decidim/extras/_extras.scss +0 -1
- data/app/packs/stylesheets/decidim/extras/_quill.scss +7 -0
- data/app/packs/stylesheets/decidim/modules/_buttons.scss +11 -4
- data/app/packs/stylesheets/decidim/modules/_cards.scss +4 -0
- data/app/packs/stylesheets/decidim/modules/_layout.scss +1 -1
- data/app/presenters/decidim/nil_presenter.rb +2 -2
- data/app/presenters/decidim/notification_presenter.rb +25 -0
- data/app/presenters/decidim/official_author_presenter.rb +1 -1
- data/app/presenters/decidim/validation_errors_presenter.rb +27 -0
- data/app/queries/decidim/similar_emendations.rb +1 -1
- data/app/resolvers/decidim/core/metric_resolver.rb +1 -1
- data/app/services/decidim/activity_search.rb +2 -2
- data/app/services/decidim/email_notification_generator.rb +4 -1
- data/app/services/decidim/html_truncation.rb +130 -0
- data/app/services/decidim/open_data_exporter.rb +29 -5
- data/app/services/decidim/resource_search.rb +1 -1
- data/app/uploaders/decidim/editor_image_uploader.rb +6 -0
- data/app/validators/password_validator.rb +123 -0
- data/app/views/decidim/account/_password_fields.html.erb +1 -1
- data/app/views/decidim/devise/passwords/edit.html.erb +1 -1
- data/app/views/decidim/devise/registrations/new.html.erb +1 -1
- data/app/views/decidim/devise/shared/_omniauth_buttons_mini.html.erb +6 -4
- data/app/views/decidim/messaging/conversations/_conversation.html.erb +3 -3
- data/app/views/decidim/messaging/conversations/_messages.html.erb +8 -2
- data/app/views/decidim/messaging/conversations/_show.html.erb +10 -12
- data/app/views/decidim/messaging/conversations/show.html.erb +4 -2
- data/app/views/decidim/newsletters/show.html.erb +1 -1
- data/app/views/decidim/notification_mailer/event_received.html.erb +17 -0
- data/app/views/decidim/pages/_tabbed.html.erb +1 -1
- data/app/views/decidim/searches/_filters_small_view.html.erb +3 -3
- data/app/views/decidim/shared/_login_modal.html.erb +5 -5
- data/app/views/decidim/shared/_orders.html.erb +1 -1
- data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
- data/app/views/decidim/shared/participatory_space_filters/_filters_small_view.html.erb +3 -3
- data/app/views/layouts/decidim/_application.html.erb +1 -12
- data/app/views/layouts/decidim/_head.html.erb +4 -0
- data/app/views/layouts/decidim/_language_chooser.html.erb +1 -1
- data/app/views/layouts/decidim/_meta_tags_config.html.erb +11 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +1 -1
- data/config/brakeman.ignore +149 -0
- data/config/initializers/devise.rb +1 -1
- data/config/initializers/rack_attack.rb +23 -21
- data/config/locales/ca.yml +2 -0
- data/config/locales/cs.yml +60 -0
- data/config/locales/en.yml +45 -0
- data/config/locales/es.yml +45 -0
- data/config/locales/eu.yml +5 -0
- data/config/locales/fi-plain.yml +6 -0
- data/config/locales/fi.yml +45 -0
- data/config/locales/fr-CA.yml +38 -0
- data/config/locales/fr.yml +44 -6
- data/config/locales/gl.yml +5 -0
- data/config/locales/it.yml +11 -0
- data/config/locales/ja.yml +72 -36
- data/config/locales/lb-LU.yml +1354 -0
- data/config/locales/lb.yml +1 -1
- data/config/locales/nl.yml +54 -0
- data/config/locales/pl.yml +5 -5
- data/config/locales/pt-BR.yml +1 -1
- data/config/locales/ro-RO.yml +8 -0
- data/config/locales/sv.yml +5 -0
- data/config/locales/val-ES.yml +1 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20210730112319_create_decidim_editor_images.rb +12 -0
- data/db/migrate/20211126183540_add_timestamps_to_content_blocks.rb +14 -0
- data/db/seeds.rb +16 -14
- data/lib/decidim/api/functions/user_entity_list.rb +1 -0
- data/lib/decidim/api/input_sorts/component_input_sort.rb +1 -1
- data/lib/decidim/common_passwords.rb +56 -0
- data/lib/decidim/content_parsers/inline_images_parser.rb +68 -0
- data/lib/decidim/content_parsers.rb +1 -0
- data/lib/decidim/content_renderers/link_renderer.rb +85 -1
- data/lib/decidim/content_renderers/user_group_renderer.rb +1 -1
- data/lib/decidim/content_renderers/user_renderer.rb +1 -1
- data/lib/decidim/core/engine.rb +3 -12
- data/lib/decidim/core/test/factories.rb +7 -1
- data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +131 -0
- data/lib/decidim/core/test.rb +1 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/core.rb +22 -5
- data/lib/decidim/db/common-passwords.txt +128420 -0
- data/lib/decidim/etherpad/pad.rb +48 -0
- data/lib/decidim/etherpad.rb +7 -0
- data/lib/decidim/events/base_event.rb +18 -0
- data/lib/decidim/events/machine_translated_event.rb +36 -0
- data/lib/decidim/events/user_group_event.rb +1 -3
- data/lib/decidim/events.rb +1 -0
- data/lib/decidim/exporters/csv.rb +7 -7
- data/lib/decidim/faker/localized.rb +15 -6
- data/lib/decidim/form_builder.rb +14 -4
- data/lib/decidim/has_attachments.rb +11 -4
- data/lib/decidim/importers/import_manifest.rb +103 -3
- data/lib/decidim/paddable.rb +1 -9
- data/lib/decidim/searchable.rb +2 -2
- data/lib/decidim/settings_manifest.rb +2 -0
- data/lib/decidim/translatable_attributes.rb +6 -6
- data/lib/decidim/view_model.rb +10 -0
- data/lib/tasks/decidim_active_storage_migration_tasks.rake +68 -0
- metadata +56 -65
- data/app/packs/stylesheets/decidim/extras/_social_icons_mini.scss +0 -11
data/config/locales/lb.yml
CHANGED
data/config/locales/nl.yml
CHANGED
|
@@ -75,6 +75,33 @@ nl:
|
|
|
75
75
|
decidim_with_day_and_month_name: "%A %d %b %Y"
|
|
76
76
|
decidim_with_month_name: "%d %B %Y"
|
|
77
77
|
decidim_with_month_name_short: "%d %b"
|
|
78
|
+
datetime:
|
|
79
|
+
distance_in_words:
|
|
80
|
+
about_x_hours:
|
|
81
|
+
one: ongeveer 1 uur
|
|
82
|
+
other: ongeveer %{count} uren
|
|
83
|
+
about_x_months:
|
|
84
|
+
one: ongeveer 1 maand
|
|
85
|
+
other: ongeveer %{count} maanden
|
|
86
|
+
half_a_minute: een halve minuut
|
|
87
|
+
less_than_x_minutes:
|
|
88
|
+
one: minder dan een minuut
|
|
89
|
+
other: minder dan %{count} minuten
|
|
90
|
+
less_than_x_seconds:
|
|
91
|
+
one: nu meteen
|
|
92
|
+
other: minder dan %{count} seconden
|
|
93
|
+
x_days:
|
|
94
|
+
one: 1 dag geleden
|
|
95
|
+
other: "%{count} dagen geleden"
|
|
96
|
+
x_hours:
|
|
97
|
+
one: 1 uur geleden
|
|
98
|
+
other: "%{count} uren geleden"
|
|
99
|
+
x_minutes:
|
|
100
|
+
one: 1 minuut geleden
|
|
101
|
+
other: "%{count} minuten geleden"
|
|
102
|
+
x_seconds:
|
|
103
|
+
one: 1 seconde geleden
|
|
104
|
+
other: "%{count} seconden geleden"
|
|
78
105
|
decidim:
|
|
79
106
|
accessibility:
|
|
80
107
|
external_link: Externe link
|
|
@@ -495,6 +522,11 @@ nl:
|
|
|
495
522
|
this_application_will_not_be_able_to: 'Deze applicatie krijgt geen toegang tot:'
|
|
496
523
|
update_profile: update je profiel
|
|
497
524
|
wants_to_use_your_account_html: "<strong>%{application_name}</strong> wil toegang tot je account"
|
|
525
|
+
editor_images:
|
|
526
|
+
create:
|
|
527
|
+
error: Fout bij het uploaden van een afbeelding
|
|
528
|
+
success: Afbeelding met succes geüploaded
|
|
529
|
+
drag_and_drop_help: Voeg afbeeldingen toe door ze te slepen of te plakken.
|
|
498
530
|
endorsable:
|
|
499
531
|
endorsements: Aanbevelingen
|
|
500
532
|
endorsements_count: Aantal suggesties
|
|
@@ -677,6 +709,7 @@ nl:
|
|
|
677
709
|
no_followers: Nog geen volgers.
|
|
678
710
|
following:
|
|
679
711
|
no_followings: Volgt nog niets of niemand.
|
|
712
|
+
non_public_followings: Sommige van de gevolgde bronnen zijn niet openbaar.
|
|
680
713
|
follows:
|
|
681
714
|
create:
|
|
682
715
|
button: Volgen
|
|
@@ -837,6 +870,15 @@ nl:
|
|
|
837
870
|
index:
|
|
838
871
|
last_activity: Laatste Activiteit
|
|
839
872
|
resource_type: Type
|
|
873
|
+
links:
|
|
874
|
+
invalid_url: Ongeldige URL
|
|
875
|
+
warning:
|
|
876
|
+
body_1: Je staat op het punt om een externe link te bezoeken, wees voorzichtig met de inhoud van de externe site.
|
|
877
|
+
body_2: Controleer de link, zorg ervoor dat je deze herkent als een veilige site voor je verdergaat.
|
|
878
|
+
cancel: Annuleer
|
|
879
|
+
close_modal: Sluit venster
|
|
880
|
+
proceed: Doorgaan
|
|
881
|
+
title: Externe link openen
|
|
840
882
|
log:
|
|
841
883
|
base_presenter:
|
|
842
884
|
create: "%{user_name} gemaakt %{resource_name}"
|
|
@@ -939,6 +981,7 @@ nl:
|
|
|
939
981
|
show:
|
|
940
982
|
back: Terug naar alle gesprekken
|
|
941
983
|
chat_with: Gesprek met
|
|
984
|
+
deleted_accounts: Je kunt geen gesprek voeren met verwijderde accounts.
|
|
942
985
|
not_allowed: Deze deelnemer aanvaardt geen rechtstreekse berichten.
|
|
943
986
|
title: Gesprek met %{usernames}
|
|
944
987
|
start:
|
|
@@ -1006,6 +1049,12 @@ nl:
|
|
|
1006
1049
|
greetings: Groeten,<br/>%{organization_name}<br/><a href="%{organization_url}">%{organization_url}</a>
|
|
1007
1050
|
hello: Hallo,
|
|
1008
1051
|
subject: Wilt u relevante informatie over %{organization_name}blijven ontvangen?
|
|
1052
|
+
notification_mailer:
|
|
1053
|
+
event_received:
|
|
1054
|
+
no_translation_available: Sorry, de geautomatiseerde vertaling kon niet worden opgehaald toen de e-mail is verzonden. Je kan de vertaling van de oorspronkelijke tekst controleren via de volgende link %{link}.
|
|
1055
|
+
original_text: 'Originele tekst:'
|
|
1056
|
+
same_language: De inhoud werd in je voorkeurstaal (%{language}) geplaatst. Dit is de reden waarom er geen automatische vertaling wordt weergegeven in deze e-mail.
|
|
1057
|
+
translated_text: 'Automatisch vertaalde tekst:'
|
|
1009
1058
|
notifications:
|
|
1010
1059
|
no_notifications: Nog geen meldingen.
|
|
1011
1060
|
notifications_settings:
|
|
@@ -1289,6 +1338,7 @@ nl:
|
|
|
1289
1338
|
title_reply: Beantwoorden
|
|
1290
1339
|
show:
|
|
1291
1340
|
back: Toon alle gesprekken
|
|
1341
|
+
deleted_accounts: Je kunt geen gesprek voeren met verwijderde accounts.
|
|
1292
1342
|
not_allowed: Deze gebruiker accepteert geen directe berichten meer.
|
|
1293
1343
|
title: Gesprek met %{usernames}
|
|
1294
1344
|
update:
|
|
@@ -1573,10 +1623,12 @@ nl:
|
|
|
1573
1623
|
name: Nederlands
|
|
1574
1624
|
name_with_error: Engels (fout!)
|
|
1575
1625
|
password_validator:
|
|
1626
|
+
blacklisted: staat op de zwarte lijst
|
|
1576
1627
|
domain_included_in_password: lijkt te veel op deze domeinnaam
|
|
1577
1628
|
email_included_in_password: lijkt te veel op uw e-mail
|
|
1578
1629
|
fallback: is niet geldig
|
|
1579
1630
|
name_included_in_password: lijkt te veel op uw naam
|
|
1631
|
+
nickname_included_in_password: lijkt te veel op jouw bijnaam
|
|
1580
1632
|
not_enough_unique_characters: heeft niet genoeg unieke tekens
|
|
1581
1633
|
password_not_allowed: is niet toegestaan
|
|
1582
1634
|
password_too_common: te algemeen
|
|
@@ -1611,6 +1663,8 @@ nl:
|
|
|
1611
1663
|
day_of_week: "%a"
|
|
1612
1664
|
day_of_week_long: "%a %e"
|
|
1613
1665
|
day_of_year: "%d.%m.%y"
|
|
1666
|
+
ddmm: "%d.%m"
|
|
1667
|
+
ddmmyyyy: "%d.%m.%Y"
|
|
1614
1668
|
decidim_day_of_year: "%d %B %Y"
|
|
1615
1669
|
decidim_short: "%d/%m/%Y %H:%M"
|
|
1616
1670
|
default: "%a, %d %b %Y %H:%M:%S %z"
|
data/config/locales/pl.yml
CHANGED
|
@@ -412,7 +412,7 @@ pl:
|
|
|
412
412
|
button_url: Adres url przycisku CTA
|
|
413
413
|
description: Opis
|
|
414
414
|
footer_sub_hero:
|
|
415
|
-
name:
|
|
415
|
+
name: Baner podrzędny stopki
|
|
416
416
|
hero:
|
|
417
417
|
name: Obraz główny
|
|
418
418
|
hero_settings_form:
|
|
@@ -439,7 +439,7 @@ pl:
|
|
|
439
439
|
stats:
|
|
440
440
|
name: Statystyki organizacji
|
|
441
441
|
sub_hero:
|
|
442
|
-
name:
|
|
442
|
+
name: Baner podrzędny
|
|
443
443
|
core:
|
|
444
444
|
actions:
|
|
445
445
|
login_before_access: Zaloguj się na swoje konto, żeby mieć dostęp
|
|
@@ -469,7 +469,7 @@ pl:
|
|
|
469
469
|
newsletter: Chcę otrzymywać okazjonalne newslettery z istotnymi informacjami
|
|
470
470
|
newsletter_title: Zgoda na subskrybcję
|
|
471
471
|
nickname_help: Twój pseudonim w %{organization}. Może zawierać tylko litery, cyfry, '-' i '_'.
|
|
472
|
-
password_help: "Minimalna liczba znaków: %{minimun_characters}; nie może być zbyt
|
|
472
|
+
password_help: "Minimalna liczba znaków: %{minimun_characters}; nie może być zbyt powszechne (np. 123456) i musi różnić się od Twojego pseudonimu i adresu e-mail."
|
|
473
473
|
sign_in: Zaloguj się
|
|
474
474
|
sign_up: Zarejestruj się
|
|
475
475
|
sign_up_as:
|
|
@@ -682,7 +682,7 @@ pl:
|
|
|
682
682
|
click_button: 'Kliknij poniższy przycisk, aby pobrać swoje dane. <br/>Plik będzie dostępny do %{date}. <br/>Będziesz potrzebował <a href=''''https://www.7-zip.org/''''>7-Zip</a> (Windows), <a href="https://www.keka.io/en/">Keka</a> (MacOS) lub <a href="https://peazip.github.io">PeaZip</a> (Linux) do otwarcia pliku. Hasło: %{password}'
|
|
683
683
|
download: Pobieranie
|
|
684
684
|
export:
|
|
685
|
-
ready:
|
|
685
|
+
ready: Mail zawiera załączony plik eksportu.
|
|
686
686
|
subject: Twój eksport "%{name}" jest gotowy
|
|
687
687
|
filters:
|
|
688
688
|
linked_classes:
|
|
@@ -1487,7 +1487,7 @@ pl:
|
|
|
1487
1487
|
change_your_password: Zmień swoje hasło
|
|
1488
1488
|
confirm_new_password: Potwierdź nowe hasło
|
|
1489
1489
|
new_password: Nowe hasło
|
|
1490
|
-
password_help: "Minimalna liczba znaków: %{minimun_characters}; nie może być zbyt
|
|
1490
|
+
password_help: "Minimalna liczba znaków: %{minimun_characters}; nie może być zbyt powszechne (np. 123456) i musi różnić się od Twojego pseudonimu i adresu e-mail."
|
|
1491
1491
|
new:
|
|
1492
1492
|
forgot_your_password: Zapomniałeś hasła?
|
|
1493
1493
|
send_me_reset_password_instructions: Wyślij mi instrukcje resetowania hasła
|
data/config/locales/pt-BR.yml
CHANGED
data/config/locales/ro-RO.yml
CHANGED
|
@@ -80,6 +80,9 @@ ro:
|
|
|
80
80
|
decidim_with_day_and_month_name: "%A %d %b %Y"
|
|
81
81
|
decidim_with_month_name: "%d %B %Y"
|
|
82
82
|
decidim_with_month_name_short: "%d %b"
|
|
83
|
+
datetime:
|
|
84
|
+
distance_in_words:
|
|
85
|
+
half_a_minute: jumătate de minut
|
|
83
86
|
decidim:
|
|
84
87
|
accessibility:
|
|
85
88
|
external_link: Link extern
|
|
@@ -518,6 +521,11 @@ ro:
|
|
|
518
521
|
this_application_will_not_be_able_to: 'Această aplicație nu va putea să:'
|
|
519
522
|
update_profile: Actualizeză-ți profilul
|
|
520
523
|
wants_to_use_your_account_html: "<strong>%{application_name}</strong> vrea să folosească contul tău"
|
|
524
|
+
editor_images:
|
|
525
|
+
create:
|
|
526
|
+
error: Eroare la încărcarea imaginii
|
|
527
|
+
success: Imaginea a fost încărcată cu succes
|
|
528
|
+
drag_and_drop_help: Adaugă imagini prin tragere & plasare sau lipirea lor.
|
|
521
529
|
endorsable:
|
|
522
530
|
endorsements: Susținători
|
|
523
531
|
endorsements_count: Număr de susțineri
|
data/config/locales/sv.yml
CHANGED
|
@@ -505,6 +505,11 @@ sv:
|
|
|
505
505
|
this_application_will_not_be_able_to: 'Det här programmet kommer inte att kunna:'
|
|
506
506
|
update_profile: Uppdatera din profil
|
|
507
507
|
wants_to_use_your_account_html: "<strong>%{application_name}</strong> vill använda ditt konto"
|
|
508
|
+
editor_images:
|
|
509
|
+
create:
|
|
510
|
+
error: Fel vid uppladdning av bild
|
|
511
|
+
success: Bilden har laddats upp
|
|
512
|
+
drag_and_drop_help: Lägg till bilder genom att dra och släppa eller klistra in dem.
|
|
508
513
|
endorsable:
|
|
509
514
|
endorsements: Instämmanden
|
|
510
515
|
endorsements_count: Antal Endorsements
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
val:
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateDecidimEditorImages < ActiveRecord::Migration[6.0]
|
|
4
|
+
def change
|
|
5
|
+
create_table :decidim_editor_images do |t|
|
|
6
|
+
t.references :decidim_author, null: false, foreign_key: { to_table: :decidim_users }, index: { name: "decidim_editor_images_author" }
|
|
7
|
+
t.references :decidim_organization, null: false, foreign_key: true, index: { name: "decidim_editor_images_constraint_organization" }
|
|
8
|
+
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddTimestampsToContentBlocks < ActiveRecord::Migration[6.0]
|
|
4
|
+
def up
|
|
5
|
+
add_timestamps :decidim_content_blocks, default: Time.zone.now
|
|
6
|
+
change_column_default :decidim_content_blocks, :created_at, nil
|
|
7
|
+
change_column_default :decidim_content_blocks, :updated_at, nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def down
|
|
11
|
+
remove_column :decidim_content_blocks, :updated_at
|
|
12
|
+
remove_column :decidim_content_blocks, :created_at
|
|
13
|
+
end
|
|
14
|
+
end
|
data/db/seeds.rb
CHANGED
|
@@ -132,21 +132,23 @@ if !Rails.env.production? || ENV["SEED"]
|
|
|
132
132
|
admin_terms_accepted_at: Time.current
|
|
133
133
|
)
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
["user@example.org", "user2@example.org"].each do |email|
|
|
136
|
+
Decidim::User.find_or_initialize_by(email: email).update!(
|
|
137
|
+
name: Faker::Name.name,
|
|
138
|
+
nickname: Faker::Twitter.unique.screen_name,
|
|
139
|
+
password: "decidim123456",
|
|
140
|
+
password_confirmation: "decidim123456",
|
|
141
|
+
confirmed_at: Time.current,
|
|
142
|
+
locale: I18n.default_locale,
|
|
143
|
+
organization: organization,
|
|
144
|
+
tos_agreement: true,
|
|
145
|
+
personal_url: Faker::Internet.url,
|
|
146
|
+
about: Faker::Lorem.paragraph(sentence_count: 2),
|
|
147
|
+
accepted_tos_version: organization.tos_version
|
|
148
|
+
)
|
|
149
|
+
end
|
|
136
150
|
|
|
137
|
-
regular_user.
|
|
138
|
-
name: Faker::Name.name,
|
|
139
|
-
nickname: Faker::Twitter.unique.screen_name,
|
|
140
|
-
password: "decidim123456",
|
|
141
|
-
password_confirmation: "decidim123456",
|
|
142
|
-
confirmed_at: Time.current,
|
|
143
|
-
locale: I18n.default_locale,
|
|
144
|
-
organization: organization,
|
|
145
|
-
tos_agreement: true,
|
|
146
|
-
personal_url: Faker::Internet.url,
|
|
147
|
-
about: Faker::Lorem.paragraph(sentence_count: 2),
|
|
148
|
-
accepted_tos_version: organization.tos_version
|
|
149
|
-
)
|
|
151
|
+
regular_user = Decidim::User.find_or_initialize_by(email: "user@example.org")
|
|
150
152
|
|
|
151
153
|
locked_user = Decidim::User.find_or_initialize_by(email: "locked_user@example.org")
|
|
152
154
|
|
|
@@ -23,7 +23,7 @@ module Decidim
|
|
|
23
23
|
prepare: lambda { |direction, ctx|
|
|
24
24
|
lambda { |locale|
|
|
25
25
|
locale = ctx[:current_organization].default_locale if locale.blank?
|
|
26
|
-
[Arel.sql("name->? #{direction.upcase}"), locale]
|
|
26
|
+
[Arel.sql("name->? #{direction.upcase}").to_s, locale]
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
class CommonPasswords
|
|
5
|
+
include Singleton
|
|
6
|
+
|
|
7
|
+
attr_reader :passwords
|
|
8
|
+
|
|
9
|
+
URLS = %w(
|
|
10
|
+
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/xato-net-10-million-passwords-1000000.txt
|
|
11
|
+
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/darkweb2017-top10000.txt
|
|
12
|
+
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt
|
|
13
|
+
).freeze
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
raise FileNotFoundError unless File.exist?(self.class.common_passwords_path)
|
|
17
|
+
|
|
18
|
+
File.open(self.class.common_passwords_path, "r") do |file|
|
|
19
|
+
@passwords = file.read.split
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.update_passwords!
|
|
24
|
+
File.open(common_passwords_path, "w") do |file|
|
|
25
|
+
common_password_list.each { |item| file.puts(item) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.common_password_list
|
|
30
|
+
@common_password_list ||= begin
|
|
31
|
+
list = []
|
|
32
|
+
URLS.each do |url|
|
|
33
|
+
URI.open(url) do |data|
|
|
34
|
+
data.read.split.each do |line|
|
|
35
|
+
list << line if line.length >= min_length
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
list.uniq
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.min_length
|
|
45
|
+
return ::PasswordValidator::MINIMUM_LENGTH if defined?(::PasswordValidator)
|
|
46
|
+
|
|
47
|
+
10
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.common_passwords_path
|
|
51
|
+
File.join(__dir__, "db", "common-passwords.txt")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class FileNotFoundError < StandardError; end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
module ContentParsers
|
|
5
|
+
# A parser that searches for inline images in an html content and
|
|
6
|
+
# replaces them with EditorImage attachments. Note that rewrite method may
|
|
7
|
+
# create EditorImage instances
|
|
8
|
+
#
|
|
9
|
+
# @see BaseParser Examples of how to use a content parser
|
|
10
|
+
class InlineImagesParser < BaseParser
|
|
11
|
+
# @return [String] the content with the inline images replaced.
|
|
12
|
+
def rewrite
|
|
13
|
+
return content unless inline_images?
|
|
14
|
+
|
|
15
|
+
replace_inline_images
|
|
16
|
+
parsed_content.to_html
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def inline_images?
|
|
20
|
+
parsed_content.search(:img).find do |image|
|
|
21
|
+
image.attr(:src).start_with?(%r{data:image/[a-z]{3,4};base64,})
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def parsed_content
|
|
28
|
+
@parsed_content ||= Nokogiri::HTML(content)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def replace_inline_images
|
|
32
|
+
parsed_content.search(:img).each do |image|
|
|
33
|
+
next unless image.attr(:src).start_with?(%r{data:image/[a-z]{3,4};base64,})
|
|
34
|
+
|
|
35
|
+
file = base64_tempfile(image.attr(:src))
|
|
36
|
+
editor_image = EditorImage.create!(
|
|
37
|
+
decidim_author_id: context[:user]&.id,
|
|
38
|
+
organization: context[:user].organization,
|
|
39
|
+
file: file
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
image.set_attribute(:src, editor_image.attached_uploader(:file).path)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def base64_tempfile(base64_data, filename = nil)
|
|
47
|
+
return base64_data unless base64_data.is_a? String
|
|
48
|
+
|
|
49
|
+
start_regex = %r{data:image/[a-z]{3,4};base64,}
|
|
50
|
+
filename ||= SecureRandom.hex
|
|
51
|
+
|
|
52
|
+
regex_result = start_regex.match(base64_data)
|
|
53
|
+
|
|
54
|
+
return unless base64_data && regex_result
|
|
55
|
+
|
|
56
|
+
start = regex_result.to_s
|
|
57
|
+
tempfile = Tempfile.new(filename)
|
|
58
|
+
tempfile.binmode
|
|
59
|
+
tempfile.write(Base64.decode64(base64_data[start.length..-1]))
|
|
60
|
+
ActionDispatch::Http::UploadedFile.new(
|
|
61
|
+
tempfile: tempfile,
|
|
62
|
+
filename: filename,
|
|
63
|
+
original_filename: filename
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -8,5 +8,6 @@ module Decidim
|
|
|
8
8
|
autoload :HashtagParser, "decidim/content_parsers/hashtag_parser"
|
|
9
9
|
autoload :NewlineParser, "decidim/content_parsers/newline_parser"
|
|
10
10
|
autoload :LinkParser, "decidim/content_parsers/link_parser"
|
|
11
|
+
autoload :InlineImagesParser, "decidim/content_parsers/inline_images_parser"
|
|
11
12
|
end
|
|
12
13
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Decidim
|
|
4
4
|
module ContentRenderers
|
|
5
|
+
# Original: https://github.com/neighborland/anchored/
|
|
5
6
|
# A renderer that converts URLs to links and strips attributes in anchors.
|
|
6
7
|
#
|
|
7
8
|
# Examples:
|
|
@@ -20,7 +21,90 @@ module Decidim
|
|
|
20
21
|
return content unless content.is_a?(String)
|
|
21
22
|
|
|
22
23
|
options = { target: "_blank", rel: "nofollow noopener" }.merge(options)
|
|
23
|
-
|
|
24
|
+
auto_link(content, options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def auto_link(text, options = {}, &block)
|
|
28
|
+
return "" if text.to_s.empty?
|
|
29
|
+
|
|
30
|
+
auto_link_urls(text, options, &block)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# remove_target_if_local("http://same.com/x", "same.com", target: "_blank")
|
|
34
|
+
# => <a href="http://same.com/x">http://same.com/x</a>
|
|
35
|
+
#
|
|
36
|
+
# remove_target_if_local("http://same.com/x", "different.com", target: "_blank")
|
|
37
|
+
# => <a href="http://same.com/x" target="_blank">http://same.com/x</a>
|
|
38
|
+
#
|
|
39
|
+
# modifies options in place
|
|
40
|
+
def remove_target_if_local(href, domain, options)
|
|
41
|
+
return unless options[:target]
|
|
42
|
+
|
|
43
|
+
options.delete(:target) if href.include?("//#{domain}")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
AUTO_LINK_RE = %r{(?: ((?:ftp|http|https):)// | www\. )[^\s<\u00A0"]+}ix.freeze
|
|
49
|
+
|
|
50
|
+
# # regexps for determining context, used high-volume
|
|
51
|
+
AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, %r{</a>}i].freeze
|
|
52
|
+
|
|
53
|
+
PUNCTUATION_RE = %r{[^\p{Word}/=&]$}.freeze
|
|
54
|
+
|
|
55
|
+
BRACKETS = { "]" => "[", ")" => "(", "}" => "{" }.freeze
|
|
56
|
+
|
|
57
|
+
# Turns all urls into clickable links. If a block is given, each url
|
|
58
|
+
# is yielded and the result is used as the link text.
|
|
59
|
+
def auto_link_urls(text, options = {})
|
|
60
|
+
# to_str is for SafeBuffer objects (text marked html_safe)
|
|
61
|
+
text.to_str.gsub(AUTO_LINK_RE) do
|
|
62
|
+
match = Regexp.last_match
|
|
63
|
+
href = match[0]
|
|
64
|
+
scheme = match[1]
|
|
65
|
+
punctuation = []
|
|
66
|
+
|
|
67
|
+
if auto_linked?(match)
|
|
68
|
+
# do not change string; URL is already linked
|
|
69
|
+
href
|
|
70
|
+
else
|
|
71
|
+
# don't include trailing punctuation character as part of the URL
|
|
72
|
+
while href.sub!(PUNCTUATION_RE, "")
|
|
73
|
+
punctuation.push Regexp.last_match(0)
|
|
74
|
+
if (opening = BRACKETS[punctuation.last]) && href.scan(opening).size > href.scan(punctuation.last).size
|
|
75
|
+
href << punctuation.pop
|
|
76
|
+
break
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
link_text = block_given? ? yield(href) : href
|
|
81
|
+
href = "http://#{href}" unless scheme
|
|
82
|
+
|
|
83
|
+
# content_tag(:a, link_text, html.merge(href: href)) + punctuation.reverse.join('')
|
|
84
|
+
anchor_tag(href, link_text, options) + punctuation.reverse.join
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Detects already linked context or position in the middle of a tag
|
|
90
|
+
# Note: this changes the current Regexp
|
|
91
|
+
def auto_linked?(match)
|
|
92
|
+
left = match.pre_match
|
|
93
|
+
right = match.post_match
|
|
94
|
+
(left =~ AUTO_LINK_CRE[0] && right =~ AUTO_LINK_CRE[1]) ||
|
|
95
|
+
(left.rindex(AUTO_LINK_CRE[2]) && Regexp.last_match.post_match !~ AUTO_LINK_CRE[3])
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def anchor_attrs(options)
|
|
99
|
+
options.map { |k, v| %(#{k}="#{v}") }.unshift("").join(" ")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def anchor_tag(href, text, options)
|
|
103
|
+
options = options.dup
|
|
104
|
+
if (domain = options.delete(:domain))
|
|
105
|
+
remove_target_if_local href, domain, options
|
|
106
|
+
end
|
|
107
|
+
%(<a href="#{href}"#{anchor_attrs(options)}>#{text}</a>)
|
|
24
108
|
end
|
|
25
109
|
end
|
|
26
110
|
end
|
|
@@ -10,7 +10,7 @@ module Decidim
|
|
|
10
10
|
# @see BaseRenderer Examples of how to use a content renderer
|
|
11
11
|
class UserGroupRenderer < BaseRenderer
|
|
12
12
|
# Matches a global id representing a Decidim::UserGroup
|
|
13
|
-
GLOBAL_ID_REGEX = %r{gid
|
|
13
|
+
GLOBAL_ID_REGEX = %r{gid://[\w-]+/Decidim::UserGroup/\d+}.freeze
|
|
14
14
|
|
|
15
15
|
# Replaces found Global IDs matching an existing user with
|
|
16
16
|
# a link to their profile. The Global IDs representing an
|
|
@@ -10,7 +10,7 @@ module Decidim
|
|
|
10
10
|
# @see BaseRenderer Examples of how to use a content renderer
|
|
11
11
|
class UserRenderer < BaseRenderer
|
|
12
12
|
# Matches a global id representing a Decidim::User
|
|
13
|
-
GLOBAL_ID_REGEX = %r{gid
|
|
13
|
+
GLOBAL_ID_REGEX = %r{gid://[\w-]+/Decidim::User/\d+}.freeze
|
|
14
14
|
|
|
15
15
|
# Replaces found Global IDs matching an existing user with
|
|
16
16
|
# a link to their profile. The Global IDs representing an
|
data/lib/decidim/core/engine.rb
CHANGED
|
@@ -17,7 +17,6 @@ require "rectify"
|
|
|
17
17
|
require "carrierwave"
|
|
18
18
|
require "rails-i18n"
|
|
19
19
|
require "date_validator"
|
|
20
|
-
require "truncato"
|
|
21
20
|
require "file_validators"
|
|
22
21
|
require "omniauth"
|
|
23
22
|
require "omniauth-facebook"
|
|
@@ -34,11 +33,9 @@ require "cell/partial"
|
|
|
34
33
|
require "kaminari"
|
|
35
34
|
require "doorkeeper"
|
|
36
35
|
require "doorkeeper-i18n"
|
|
37
|
-
require "nobspw"
|
|
38
36
|
require "batch-loader"
|
|
39
|
-
require "
|
|
37
|
+
require "mime-types"
|
|
40
38
|
require "diffy"
|
|
41
|
-
require "anchored"
|
|
42
39
|
require "social-share-button"
|
|
43
40
|
require "ransack"
|
|
44
41
|
require "searchlight"
|
|
@@ -85,8 +82,6 @@ module Decidim
|
|
|
85
82
|
end
|
|
86
83
|
|
|
87
84
|
initializer "decidim.graphql_api" do
|
|
88
|
-
# Enable them method `!` everywhere for compatibility, this line will be removed when upgrading to GraphQL 2.0
|
|
89
|
-
GraphQL::DeprecatedDSL.activate
|
|
90
85
|
Decidim::Api::QueryType.include Decidim::QueryExtensions
|
|
91
86
|
|
|
92
87
|
Decidim::Api.add_orphan_type Decidim::Core::UserType
|
|
@@ -304,7 +299,7 @@ module Decidim
|
|
|
304
299
|
|
|
305
300
|
initializer "SSL and HSTS" do
|
|
306
301
|
Rails.application.configure do
|
|
307
|
-
config.force_ssl =
|
|
302
|
+
config.force_ssl = Decidim.config.force_ssl
|
|
308
303
|
end
|
|
309
304
|
end
|
|
310
305
|
|
|
@@ -315,7 +310,7 @@ module Decidim
|
|
|
315
310
|
end
|
|
316
311
|
|
|
317
312
|
initializer "Expire sessions" do
|
|
318
|
-
Rails.application.config.session_store :cookie_store, expire_after: Decidim.config.expire_session_after
|
|
313
|
+
Rails.application.config.session_store :cookie_store, secure: Decidim.config.force_ssl, expire_after: Decidim.config.expire_session_after
|
|
319
314
|
end
|
|
320
315
|
|
|
321
316
|
initializer "decidim.core.register_resources" do
|
|
@@ -542,10 +537,6 @@ module Decidim
|
|
|
542
537
|
end
|
|
543
538
|
end
|
|
544
539
|
|
|
545
|
-
initializer "nbspw" do
|
|
546
|
-
NOBSPW.configuration.use_ruby_grep = true
|
|
547
|
-
end
|
|
548
|
-
|
|
549
540
|
initializer "decidim.premailer" do
|
|
550
541
|
Premailer::Adapter.use = :decidim
|
|
551
542
|
end
|
|
@@ -248,7 +248,7 @@ FactoryBot.define do
|
|
|
248
248
|
end
|
|
249
249
|
|
|
250
250
|
factory :user_group_membership, class: "Decidim::UserGroupMembership" do
|
|
251
|
-
user
|
|
251
|
+
user { create(:user, :confirmed, organization: user_group.organization) }
|
|
252
252
|
role { :creator }
|
|
253
253
|
user_group
|
|
254
254
|
end
|
|
@@ -749,4 +749,10 @@ FactoryBot.define do
|
|
|
749
749
|
last_used_at { 1.hour.ago }
|
|
750
750
|
end
|
|
751
751
|
end
|
|
752
|
+
|
|
753
|
+
factory :editor_image, class: "Decidim::EditorImage" do
|
|
754
|
+
organization
|
|
755
|
+
author { create(:user, :admin, :confirmed, organization: organization) }
|
|
756
|
+
file { Decidim::Dev.test_file("city.jpeg", "image/jpeg") }
|
|
757
|
+
end
|
|
752
758
|
end
|