decidim-core 0.31.7 → 0.31.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/content_blocks/participatory_space_main_data/title.erb +1 -14
  3. data/app/cells/decidim/following_cell.rb +1 -1
  4. data/app/cells/decidim/nav_links/show.erb +3 -1
  5. data/app/cells/decidim/participatory_space_private_user/show.erb +1 -1
  6. data/app/cells/decidim/share_text_widget/modal.erb +1 -0
  7. data/app/cells/decidim/share_widget/modal.erb +1 -0
  8. data/app/cells/decidim/share_widget/qr_code_modal.erb +2 -4
  9. data/app/commands/decidim/create_omniauth_registration.rb +17 -2
  10. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +4 -0
  11. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -0
  12. data/app/controllers/concerns/decidim/disable_redirection_to_external_host.rb +2 -0
  13. data/app/controllers/concerns/decidim/filter_resource.rb +2 -0
  14. data/app/controllers/concerns/decidim/impersonate_users.rb +2 -2
  15. data/app/controllers/concerns/decidim/locale_switcher.rb +62 -11
  16. data/app/controllers/concerns/decidim/needs_permission.rb +22 -10
  17. data/app/controllers/concerns/decidim/onboarding_action_methods.rb +2 -0
  18. data/app/controllers/concerns/decidim/paginable.rb +7 -3
  19. data/app/controllers/concerns/decidim/payload_info.rb +2 -0
  20. data/app/controllers/concerns/decidim/resource_versions_concern.rb +14 -0
  21. data/app/controllers/decidim/application_controller.rb +0 -6
  22. data/app/controllers/decidim/authorization_modals_controller.rb +2 -0
  23. data/app/controllers/decidim/components/base_controller.rb +2 -0
  24. data/app/controllers/decidim/devise/passwords_controller.rb +8 -0
  25. data/app/controllers/decidim/favicon_controller.rb +9 -0
  26. data/app/controllers/decidim/free_resource_authorization_modals_controller.rb +2 -0
  27. data/app/controllers/decidim/gamification/badges_controller.rb +2 -0
  28. data/app/controllers/decidim/homepage_controller.rb +4 -1
  29. data/app/controllers/decidim/likes_controller.rb +1 -1
  30. data/app/controllers/decidim/links_controller.rb +2 -0
  31. data/app/controllers/decidim/manifests_controller.rb +2 -0
  32. data/app/controllers/decidim/messaging/conversations_controller.rb +10 -4
  33. data/app/controllers/decidim/newsletters_controller.rb +4 -0
  34. data/app/controllers/decidim/notifications_subscriptions_controller.rb +4 -0
  35. data/app/controllers/decidim/offline_controller.rb +5 -1
  36. data/app/controllers/decidim/open_data_controller.rb +5 -1
  37. data/app/controllers/decidim/pages_controller.rb +31 -3
  38. data/app/controllers/decidim/private_downloads_controller.rb +2 -0
  39. data/app/controllers/decidim/profiles_controller.rb +10 -0
  40. data/app/controllers/decidim/qr_controller.rb +3 -1
  41. data/app/controllers/decidim/resource_autocomplete_controller.rb +2 -0
  42. data/app/controllers/decidim/searches_controller.rb +2 -0
  43. data/app/controllers/decidim/short_links_controller.rb +4 -0
  44. data/app/controllers/decidim/static_map_controller.rb +2 -0
  45. data/app/controllers/decidim/timeouts_controller.rb +4 -0
  46. data/app/controllers/decidim/tos_controller.rb +2 -0
  47. data/app/controllers/decidim/upload_validations_controller.rb +4 -2
  48. data/app/controllers/decidim/user_activities_controller.rb +2 -0
  49. data/app/forms/decidim/upload_validation_form.rb +16 -10
  50. data/app/helpers/concerns/decidim/user_role_checker.rb +35 -10
  51. data/app/helpers/decidim/sanitize_helper.rb +11 -1
  52. data/app/jobs/decidim/application_job.rb +4 -0
  53. data/app/models/decidim/authorization.rb +24 -0
  54. data/app/models/decidim/oauth_application.rb +1 -0
  55. data/app/models/decidim/user.rb +1 -0
  56. data/app/models/decidim/user_base_entity.rb +1 -1
  57. data/app/packs/src/decidim/callout.js +10 -0
  58. data/app/packs/src/decidim/callout.test.js +32 -0
  59. data/app/packs/src/decidim/controllers/accordion/accordion.test.js +64 -0
  60. data/app/packs/src/decidim/controllers/accordion/controller.js +43 -0
  61. data/app/packs/src/decidim/datepicker/datepicker_functions.js +34 -23
  62. data/app/packs/src/decidim/datepicker/generate_datepicker.js +4 -4
  63. data/app/packs/src/decidim/datepicker/test/time.test.js +39 -24
  64. data/app/packs/src/decidim/utilities/dom.js +2 -2
  65. data/app/packs/stylesheets/decidim/_content_blocks.scss +4 -10
  66. data/app/packs/stylesheets/decidim/_conversations.scss +0 -8
  67. data/app/packs/stylesheets/decidim/_modal.scss +16 -8
  68. data/app/packs/stylesheets/decidim/_modal_share.scss +0 -22
  69. data/app/packs/stylesheets/decidim/_participatory_spaces.scss +11 -1
  70. data/app/packs/stylesheets/decidim/_rich_text.scss +12 -9
  71. data/app/packs/stylesheets/decidim/_typography.scss +5 -2
  72. data/app/packs/stylesheets/decidim/legacy/email.scss +0 -5
  73. data/app/permissions/decidim/permissions.rb +20 -0
  74. data/app/presenters/decidim/admin_log/component_presenter.rb +1 -1
  75. data/app/presenters/decidim/log/base_presenter.rb +10 -1
  76. data/app/presenters/decidim/log/user_presenter.rb +2 -2
  77. data/app/serializers/decidim/exporters/open_data_blocked_user_serializer.rb +11 -2
  78. data/app/serializers/decidim/exporters/open_data_moderation_serializer.rb +25 -1
  79. data/app/services/decidim/svg_content_validator.rb +554 -0
  80. data/app/uploaders/decidim/application_uploader.rb +2 -2
  81. data/app/validators/uploader_image_content_validator.rb +278 -0
  82. data/app/views/decidim/application/_radio_accordion.html.erb +1 -5
  83. data/app/views/decidim/messaging/conversations/create.js.erb +1 -3
  84. data/app/views/decidim/shared/_login_modal.html.erb +12 -14
  85. data/app/views/layouts/decidim/_mailer_logo.html.erb +1 -1
  86. data/config/initializers/rack_attack.rb +10 -0
  87. data/config/locales/bg.yml +0 -1
  88. data/config/locales/ca-IT.yml +3 -1
  89. data/config/locales/ca.yml +3 -1
  90. data/config/locales/cs.yml +7 -1
  91. data/config/locales/de.yml +61 -3
  92. data/config/locales/en.yml +3 -1
  93. data/config/locales/es-MX.yml +3 -1
  94. data/config/locales/es-PY.yml +3 -1
  95. data/config/locales/es.yml +7 -5
  96. data/config/locales/eu.yml +155 -156
  97. data/config/locales/fi-plain.yml +1 -1
  98. data/config/locales/fi.yml +1 -1
  99. data/config/locales/fr-CA.yml +3 -1
  100. data/config/locales/fr.yml +3 -1
  101. data/config/locales/gl.yml +1441 -33
  102. data/config/locales/hu.yml +0 -1
  103. data/config/locales/ja.yml +1 -1
  104. data/config/locales/pl.yml +0 -1
  105. data/config/locales/pt-BR.yml +0 -1
  106. data/config/locales/ro-RO.yml +0 -1
  107. data/config/locales/sk.yml +2 -1
  108. data/config/locales/sv.yml +47 -10
  109. data/config/locales/tr-TR.yml +0 -2
  110. data/db/migrate/20260909000000_add_failed_attempts_and_locked_at_to_decidim_authorizations.rb +8 -0
  111. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +77 -0
  112. data/lib/decidim/core/test/shared_examples/participatory_space_members_shared_examples.rb +85 -6
  113. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +23 -1
  114. data/lib/decidim/core/version.rb +1 -1
  115. data/lib/decidim/core.rb +9 -0
  116. data/lib/decidim/has_upload_validations.rb +1 -0
  117. data/lib/decidim/legacy_form_builder.rb +4 -0
  118. data/lib/decidim/query_extensions.rb +2 -0
  119. metadata +10 -6
@@ -1385,7 +1385,6 @@ hu:
1385
1385
  layouts:
1386
1386
  decidim:
1387
1387
  announcements:
1388
- view_less: Kevesebb mutatása
1389
1388
  view_more: További információk
1390
1389
  data_consent:
1391
1390
  details:
@@ -240,6 +240,7 @@ ja:
240
240
  create: "%{user_name} は、 %{resource_name} コンポーネントを %{space_name} スペースに追加しました"
241
241
  delete: "%{user_name} が %{resource_name} スペースから %{space_name} コンポーネントを削除しました"
242
242
  export_component: "%{user_name} は%{space_name} の %{resource_name} %{component_name} を %{format_name} としてエクスポートしました"
243
+ menu_hidden: "%{user_name} がコンポーネント %{resource_name} をスペース %{space_name} のメニューから非表示にしました"
243
244
  publish: "%{user_name} が %{resource_name} スペースで %{space_name} コンポーネントを公開しました"
244
245
  restore: "%{user_name} がコンポーネント %{resource_name} をスコープ %{space_name} に復元しました。"
245
246
  soft_delete: "%{user_name} が %{space_name} スペースの %{resource_name} コンポーネントをゴミ箱に移動しました"
@@ -2043,7 +2044,6 @@ ja:
2043
2044
  layouts:
2044
2045
  decidim:
2045
2046
  announcements:
2046
- view_less: 一部のみ表示
2047
2047
  view_more: 詳しい情報
2048
2048
  data_consent:
2049
2049
  details:
@@ -1520,7 +1520,6 @@ pl:
1520
1520
  layouts:
1521
1521
  decidim:
1522
1522
  announcements:
1523
- view_less: Pokaż mniej
1524
1523
  view_more: Więcej informacji
1525
1524
  data_consent:
1526
1525
  details:
@@ -2019,7 +2019,6 @@ pt-BR:
2019
2019
  layouts:
2020
2020
  decidim:
2021
2021
  announcements:
2022
- view_less: Exibir menos
2023
2022
  view_more: Mais informações
2024
2023
  data_consent:
2025
2024
  details:
@@ -1849,7 +1849,6 @@ ro:
1849
1849
  layouts:
1850
1850
  decidim:
1851
1851
  announcements:
1852
- view_less: Afișați mai puțin
1853
1852
  view_more: Mai multe informații
1854
1853
  data_consent:
1855
1854
  details:
@@ -885,6 +885,8 @@ sk:
885
885
  errors:
886
886
  files:
887
887
  file_cannot_be_processed: Súbor nie je možné spracovať
888
+ file_contains_unsafe_content: Potenciálny nebezpečný obsah
889
+ file_is_not_a_valid_image: Nie je v platnom formáte obrázka
888
890
  file_resolution_too_large: Rozlíšenie súboru je príliš veľké
889
891
  not_inside_organization: Súbor nie je pripojený k žiadnej organizácii.
890
892
  internal_server_error:
@@ -2076,7 +2078,6 @@ sk:
2076
2078
  layouts:
2077
2079
  decidim:
2078
2080
  announcements:
2079
- view_less: Zobraziť menej
2080
2081
  view_more: Viac informácií
2081
2082
  data_consent:
2082
2083
  details:
@@ -253,6 +253,7 @@ sv:
253
253
  create: "%{user_name} lade till komponenten %{resource_name} till utrymmet %{space_name}"
254
254
  delete: "%{user_name} tog bort komponenten %{resource_name} från utrymmet %{space_name}"
255
255
  export_component: "%{user_name} exporterade %{resource_name} %{component_name} i %{space_name} som %{format_name}"
256
+ menu_hidden: "%{user_name} dolde komponenten %{resource_name} i menyn i utrymmet %{space_name}"
256
257
  publish: "%{user_name} publicerade komponenten %{resource_name} i utrymmet %{space_name}"
257
258
  restore: "%{user_name} återställde komponenten %{resource_name} i utrymmet %{space_name}"
258
259
  soft_delete: "%{user_name} tog bort komponenten %{resource_name} från utrymmet %{space_name}"
@@ -422,8 +423,8 @@ sv:
422
423
  success: Ändringsförslaget har dragits tillbaka.
423
424
  wizard_step_form:
424
425
  steps:
425
- '1': Skapa din korrigering
426
- '2': Publicera din korrigering
426
+ '1': Skapa ändringsförslag
427
+ '2': Publicera ditt ändringsförslag
427
428
  anonymous_user: Anonym
428
429
  application:
429
430
  document:
@@ -556,6 +557,7 @@ sv:
556
557
  global:
557
558
  amendments_enabled: Aktivera ändringsförslag
558
559
  comments_enabled: Aktivera kommentarer
560
+ comments_max_length: Max antal tecken per kommentar
559
561
  define_taxonomy_filters: Ställ in filter innan du använder den här inställningen.
560
562
  dummy_global_attribute1: Dummy Attribut 1
561
563
  dummy_global_attribute2: Dummy Attribut 2
@@ -662,6 +664,13 @@ sv:
662
664
  all: Alla
663
665
  filter_taxonomy_values:
664
666
  all: Alla
667
+ delete_user_mailer:
668
+ delete:
669
+ body_1: Ditt konto har inaktiverats och är inte längre tillgängligt. Dina personuppgifter kommer att raderas permanent i enlighet med våra rutiner för datalagring.
670
+ body_2: Av säkerhetsskäl behålls vissa uppgifter som rör behörigheter. Om du skapar ett nytt konto och godkänner behörigheter igen kan uppgifterna kopplas till ditt nya konto.
671
+ greetings_html: Vänliga hälsningar,<br/><a href="%{organization_url}">%{organization_name}</a>
672
+ hello: Hej %{username},
673
+ subject: Ditt konto har raderats
665
674
  devise:
666
675
  omniauth_registrations:
667
676
  create:
@@ -875,13 +884,13 @@ sv:
875
884
  affected_user:
876
885
  email_intro: 'Ett ändringsförslag har godkänts för %{amendable_title}. Visa det från den här sidan:'
877
886
  email_outro: Du har fått det här meddelandet eftersom du är en författare av %{amendable_title}.
878
- email_subject: Accepterad förbättring av %{amendable_title} från %{emendation_author_name}
879
- notification_title: <a href="%{emendation_path}">Förbättringen</a> gjord av <a href="%{emendation_author_path}">%{emendation_author_name}</a> accepterades för <a href="%{amendable_path}">%{amendable_title}</a>.
887
+ email_subject: Godkänd ändring av %{amendable_title} från %{emendation_author_nickname}
888
+ notification_title: <a href="%{emendation_path}">Ändringsförslaget</a> från av <a href="%{emendation_author_path}">%{emendation_author_name}</a> till <a href="%{amendable_path}">%{amendable_title}</a> har godkänts.
880
889
  follower:
881
890
  email_intro: 'Ett ändringsförslag har bifallits för %{amendable_title}. Läs det på den här sidan:'
882
891
  email_outro: Du har fått det här meddelandet eftersom du följer %{amendable_title}. Du kan sluta att ta emot meddelanden genom att följa föregående länk.
883
- email_subject: Accepterad förbättring av %{amendable_title} från %{emendation_author_name}
884
- notification_title: <a href="%{emendation_path}">Förbättringen</a> gjord av <a href="%{emendation_author_path}">%{emendation_author_name}</a> accepterades för <a href="%{amendable_path}">%{amendable_title}</a>.
892
+ email_subject: Godkänd ändring av %{amendable_title} från %{emendation_author_nickname}
893
+ notification_title: <a href="%{emendation_path}">Ändringsförslaget</a> av <a href="%{emendation_author_path}">%{emendation_author_name}</a> till <a href="%{amendable_path}">%{amendable_title}</a> har godkänts.
885
894
  amendment_created:
886
895
  affected_user:
887
896
  email_intro: 'Ett nytt ändringsförslag har skapats för %{amendable_title}. Du kan se det från den här sidan:'
@@ -897,20 +906,29 @@ sv:
897
906
  affected_user:
898
907
  email_intro: 'Ett avslaget ändringsförslag till %{amendable_title} har publicerats som en ny %{amendable_type}. Du kan se det på den här sidan:'
899
908
  email_outro: Du har fått det här meddelandet eftersom du är en författare av %{amendable_title}.
909
+ email_subject: Ett ändringsförslag från %{emendation_author_name} har publicerats som en ny %{amendable_type}
910
+ notification_title: Ett <a href="%{emendation_path}">avslaget ändringsförslag</a> till <a href="%{amendable_path}">%{amendable_title}</a> har publicerats som en ny %{amendable_type} av <a href="%{emendation_author_path}">%{emendation_author_name}</a>.
900
911
  follower:
901
912
  email_intro: 'En avslaget ändringsförslag till %{amendable_title} har lagts fram som ett nytt %{amendable_type}. Du kan se det på den här sidan:'
902
913
  email_outro: Du har fått det här meddelandet eftersom du följer %{amendable_title}. Du kan sluta att ta emot meddelanden via föregående länk.
914
+ email_subject: Ett ändringsförslag från %{emendation_author_name} har publicerats som en ny %{amendable_type}
915
+ notification_title: Ett <a href="%{emendation_path}">avslaget ändringsförslag</a> till <a href="%{amendable_path}">%{amendable_title}</a> har publicerats som en ny %{amendable_type} av <a href="%{emendation_author_path}">%{emendation_author_name}</a>.
903
916
  amendment_rejected:
904
917
  affected_user:
905
918
  email_intro: 'En ändringsförslag till %{amendable_title} har avslagits. Du kan se det från den här sidan:'
906
919
  email_outro: Du har fått det här meddelandet eftersom du är en författare till %{amendable_title}.
920
+ email_subject: Ändringsförslag till %{amendable_title} från %{emendation_author_name} avslogs
921
+ notification_title: <a href="%{emendation_path}">Ändringsförslaget</a> till <a href="%{amendable_path}">%{amendable_title}</a> som skapades av <a href="%{emendation_author_path}">%{emendation_author_name}</a> har avslagits.
907
922
  follower:
908
923
  email_intro: 'Ett ändringsförslag till %{amendable_title} har avslagits. Du kan se det från den här sidan:'
909
924
  email_outro: Du har fått det här meddelandet eftersom du följer %{amendable_title}. Du kan sluta ta emot meddelanden via föregående länk.
925
+ email_subject: Ändringsförslag till %{amendable_title} från %{emendation_author_name} avslogs
926
+ notification_title: <a href="%{emendation_path}">Ändringsförslaget</a> till <a href="%{amendable_path}">%{amendable_title}</a> som skapades av <a href="%{emendation_author_path}">%{emendation_author_name}</a> har avslagits.
910
927
  emendation_promoted:
911
928
  follower:
912
929
  email_intro: 'Ett ändringsförslag till %{amendable_title} har avslagits. Du kan se det från den här sidan:'
913
930
  email_outro: Du har fått det här meddelandet eftersom du är en författare till %{amendable_title}.
931
+ email_subject: Ett ändringsförslag från %{emendation_author_name} har publicerats som en ny %{amendable_type}
914
932
  attachments:
915
933
  attachment_created:
916
934
  email_intro: 'Ett nytt dokument har lagts till i %{resource_title}. Du kan se det från den här sidan:'
@@ -962,13 +980,25 @@ sv:
962
980
  En administratör tog bort din %{resource_type} eftersom den har rapporterats som %{report_reasons}.
963
981
  </br>
964
982
  <i>%{resource_content}</i>
983
+ resource_liked:
984
+ email_intro: '%{liker_name}, som du följer, har precis gillat ”%{resource_title}” och vi tror att det kan intressera dig. Ta en titt och bidra:'
985
+ email_outro: Du har fått det här meddelandet eftersom du följer %{liker_name}. Du kan sluta ta emot meddelandena genom att följa länken ovan.
986
+ email_subject: "%{liker_name} har gillat något"
987
+ notification_title: <a href="%{liker_path}">%{liker_name} </a> gillar %{resource_type} <a href="%{resource_path}">%{resource_title}</a>.
965
988
  resources:
966
989
  soft_deleted:
967
990
  notification_title: En administratör har tagit bort ditt "%{resource_type}" "%{resource_title}".
968
991
  users:
992
+ profile_updated:
993
+ email_intro: <a href="%{resource_url}">Profilsidan</a> för %{name}, som du följer, har uppdaterats.
994
+ email_outro: Du har fått det här meddelandet eftersom du följer %{name}. Du kan sluta ta emot meddelandena genom att följa länken ovan.
995
+ email_subject: "%{name} uppdaterade sin profil"
996
+ notification_title: <a href="%{resource_path}">Profilsidan</a> för %{name}, som du följer, har uppdaterats.
969
997
  user_officialized:
998
+ email_intro: Deltagaren %{name} har fått officiell status.
970
999
  email_outro: Du har fått detta meddelande eftersom du är administratör i organisationen.
971
1000
  email_subject: "%{name} har fått officiell status"
1001
+ notification_title: Deltagaren %{name} har fått officiell status.
972
1002
  export_mailer:
973
1003
  download_your_data_export:
974
1004
  click_button_html: Klicka på nästa länk för att ladda ner dina data.<br/>Filen kommer att finnas tillgänglig för nedladdning fram till %{date}.
@@ -1163,6 +1193,8 @@ sv:
1163
1193
  dynamic:
1164
1194
  screen_reader_explanation: Följande element är en karta som presenterar objekten på denna sida som kartpunkter. Elementet kan användas med en skärmläsare men det kan vara svårt att förstå.
1165
1195
  skip_button: Hoppa över karta
1196
+ zoom_in: Zooma in
1197
+ zoom_out: Zooma ut
1166
1198
  static:
1167
1199
  latlng_text: 'latitud: %{latitude}, longitud: %{longitude}'
1168
1200
  map_service_brand: OpenStreetMap
@@ -1504,6 +1536,9 @@ sv:
1504
1536
  log_in: logga in
1505
1537
  never_logged_in: har aldrig loggat in
1506
1538
  subject: Varning om inaktivt konto
1539
+ participatory_space:
1540
+ labels:
1541
+ reference: Utrymmets referens
1507
1542
  passwords:
1508
1543
  update:
1509
1544
  error: Det gick inte att uppdatera lösenordet.
@@ -1692,6 +1727,9 @@ sv:
1692
1727
  help_text: "<strong>Obs:</strong> Innehåll kan ha översatts automatiskt och inte vara 100% korrekt."
1693
1728
  show_original: Visa originaltexten
1694
1729
  show_translated: Visa maskinöversatt text
1730
+ user_activity:
1731
+ index:
1732
+ no_activities_warning: Den här deltagaren har ingen aktivitet ännu.
1695
1733
  user_contact_disabled: Deltagaren tar inte emot inte direktmeddelanden.
1696
1734
  user_conversations:
1697
1735
  index:
@@ -1790,7 +1828,7 @@ sv:
1790
1828
  nickname_help: Ditt användarnamn i %{organization}. Kan bara innehålla små bokstäver a-z, siffror, '-' och '_'.
1791
1829
  submit_button: Spara
1792
1830
  subtitle: Om du godkänner inbjudan väljer du ditt användarnamn och lösenord.
1793
- subtitle_no_password: Om du accepterar inbjudan var vänlig ange ditt alias.
1831
+ subtitle_no_password: Om du accepterar inbjudan var vänlig ange ditt användarnamn.
1794
1832
  invitation_removed: Din inbjudan har tagits bort.
1795
1833
  invitation_token_invalid: Ogiltig token för inbjudan!
1796
1834
  new:
@@ -1798,8 +1836,8 @@ sv:
1798
1836
  submit_button: Skicka en inbjudan
1799
1837
  no_invitations_remaining: Inga inbjudningar kvar
1800
1838
  send_instructions: Ett e-brev med inbjudan har skickats till %{email}.
1801
- updated: Inbjudan godtogs. Du är nu inloggad.
1802
- updated_not_active: Inbjudan godtogs.
1839
+ updated: Inbjudan accepterades. Du är nu inloggad.
1840
+ updated_not_active: Inbjudan accepterades.
1803
1841
  mailer:
1804
1842
  confirmation_instructions:
1805
1843
  action: Bekräfta mitt konto
@@ -2031,7 +2069,6 @@ sv:
2031
2069
  layouts:
2032
2070
  decidim:
2033
2071
  announcements:
2034
- view_less: Visa mindre
2035
2072
  view_more: Mer information
2036
2073
  data_consent:
2037
2074
  details:
@@ -968,8 +968,6 @@ tr:
968
968
  timestamp_error_message: Üzgünüm, bu çok hızlıydı! Lütfen yeniden gönderin.
969
969
  layouts:
970
970
  decidim:
971
- announcements:
972
- view_less: Daha Az Göster
973
971
  data_consent:
974
972
  details:
975
973
  columns:
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddFailedAttemptsAndLockedAtToDecidimAuthorizations < ActiveRecord::Migration[7.0]
4
+ def change
5
+ add_column :decidim_authorizations, :failed_attempts, :integer, default: 0, null: false
6
+ add_column :decidim_authorizations, :locked_at, :datetime
7
+ end
8
+ end
@@ -42,5 +42,82 @@ shared_examples "participatory space members page examples" do
42
42
  end
43
43
  end
44
44
  end
45
+
46
+ context "when participatory space has paginated members" do
47
+ let(:users) { create_list(:user, 30, organization: privatable_to.organization) }
48
+ let!(:members) do
49
+ users.map do |user|
50
+ create(:participatory_space_private_user, privatable_to:, user:, published: true)
51
+ end
52
+ end
53
+
54
+ context "with default pagination" do
55
+ it "returns first page with 25 members" do
56
+ get :index, params: { slug_param => slug, :locale => I18n.locale }
57
+
58
+ expect(assigns(:members).count).to eq(25)
59
+ expect(assigns(:members).current_page).to eq(1)
60
+ expect(assigns(:members).total_count).to eq(30)
61
+ end
62
+ end
63
+
64
+ context "with page parameter" do
65
+ it "returns second page with remaining members" do
66
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :page => 2 }
67
+
68
+ expect(assigns(:members).count).to eq(5)
69
+ expect(assigns(:members).current_page).to eq(2)
70
+ expect(assigns(:members).total_count).to eq(30)
71
+ end
72
+
73
+ it "returns empty collection for out-of-range page" do
74
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :page => 999 }
75
+
76
+ expect(assigns(:members).count).to eq(0)
77
+ expect(assigns(:members).current_page).to eq(999)
78
+ expect(assigns(:members).total_count).to eq(30)
79
+ end
80
+ end
81
+
82
+ context "with per_page parameter" do
83
+ it "returns all members when per_page is 50" do
84
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :per_page => 50 }
85
+
86
+ expect(assigns(:members).count).to eq(30)
87
+ expect(assigns(:members).current_page).to eq(1)
88
+ expect(assigns(:members).limit_value).to eq(50)
89
+ expect(assigns(:members).total_count).to eq(30)
90
+ end
91
+
92
+ it "returns first 25 members when per_page is 25" do
93
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :per_page => 25 }
94
+
95
+ expect(assigns(:members).count).to eq(25)
96
+ expect(assigns(:members).limit_value).to eq(25)
97
+ end
98
+
99
+ it "limits per_page to maximum allowed value" do
100
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :per_page => 200 }
101
+
102
+ expect(assigns(:members).limit_value).to eq(100)
103
+ end
104
+
105
+ it "limit per_page to minimum allowed value" do
106
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :per_page => 5 }
107
+
108
+ expect(assigns(:members).limit_value).to eq(25)
109
+ end
110
+ end
111
+
112
+ context "with both page and per_page parameters" do
113
+ it "returns correct page with custom per_page" do
114
+ get :index, params: { slug_param => slug, :locale => I18n.locale, :page => 2, :per_page => 50 }
115
+
116
+ expect(assigns(:members).count).to eq(0)
117
+ expect(assigns(:members).current_page).to eq(2)
118
+ expect(assigns(:members).limit_value).to eq(50)
119
+ end
120
+ end
121
+ end
45
122
  end
46
123
  end
@@ -3,8 +3,16 @@
3
3
  shared_examples "participatory space members" do
4
4
  let(:blocks_manifests) { [] }
5
5
  let(:organization) { create(:organization) }
6
- let(:user) { create(:user, organization: participatory_space.organization) }
6
+ let(:user) { create(:user, :confirmed, organization: participatory_space.organization) }
7
7
  let(:unpublished_user) { create(:user, organization: participatory_space.organization) }
8
+ # A visitor allowed to reach the space homepage even when the space is
9
+ # private (e.g. an organization admin). Homepage checks use it so that they
10
+ # inspect the actual homepage instead of a redirect target.
11
+ let(:allowed_visitor) { create(:user, :admin, :confirmed, organization: participatory_space.organization) }
12
+ # Spaces whose members page is not publicly accessible (e.g. private
13
+ # participatory processes) require a logged in member. Host specs can opt in
14
+ # by overriding this to true.
15
+ let(:login_as_member) { false }
8
16
 
9
17
  before do
10
18
  switch_to_host(organization.host)
@@ -17,10 +25,15 @@ shared_examples "participatory space members" do
17
25
  end
18
26
 
19
27
  context "when there are no members and accessing from the space homepage" do
28
+ before do
29
+ login_as allowed_visitor, scope: :user
30
+ end
31
+
20
32
  context "and the main data content block is disabled" do
21
33
  it "the menu nav is not shown" do
22
34
  visit participatory_space_homepage_path
23
35
 
36
+ expect(page).to have_current_path participatory_space_homepage_path
24
37
  expect(page).to have_no_css(".participatory-space__nav-container")
25
38
  end
26
39
  end
@@ -31,6 +44,7 @@ shared_examples "participatory space members" do
31
44
  it "the menu link is not shown" do
32
45
  visit participatory_space_homepage_path
33
46
 
47
+ expect(page).to have_current_path participatory_space_homepage_path
34
48
  expect(page).to have_no_content("Members")
35
49
  end
36
50
  end
@@ -44,7 +58,7 @@ shared_examples "participatory space members" do
44
58
 
45
59
  context "when there are some members and all are unpublished" do
46
60
  before do
47
- create(:member, user:, participatory_space:, published: false)
61
+ create(:participatory_space_private_user, user:, privatable_to: participatory_space, published: false)
48
62
  end
49
63
 
50
64
  context "and directly accessing from URL" do
@@ -54,10 +68,15 @@ shared_examples "participatory space members" do
54
68
  end
55
69
 
56
70
  context "and accessing from the homepage" do
71
+ before do
72
+ login_as allowed_visitor, scope: :user
73
+ end
74
+
57
75
  context "and the main data content block is disabled" do
58
76
  it "the menu nav is not shown" do
59
77
  visit participatory_space_homepage_path
60
78
 
79
+ expect(page).to have_current_path participatory_space_homepage_path
61
80
  expect(page).to have_no_css(".participatory-space__nav-container")
62
81
  end
63
82
  end
@@ -68,6 +87,7 @@ shared_examples "participatory space members" do
68
87
  it "the menu link is not shown" do
69
88
  visit participatory_space_homepage_path
70
89
 
90
+ expect(page).to have_current_path participatory_space_homepage_path
71
91
  expect(page).to have_no_content("Members")
72
92
  end
73
93
  end
@@ -75,10 +95,11 @@ shared_examples "participatory space members" do
75
95
  end
76
96
 
77
97
  context "when there are some published members" do
78
- let!(:member) { create(:member, user:, participatory_space:, published: true) }
79
- let!(:unpublished_member) { create(:member, user: unpublished_user, participatory_space:, published: false) }
98
+ let!(:member) { create(:participatory_space_private_user, user:, privatable_to: participatory_space, published: true) }
99
+ let!(:unpublished_member) { create(:participatory_space_private_user, user: unpublished_user, privatable_to: participatory_space, published: false) }
80
100
 
81
101
  before do
102
+ login_as(member.user, scope: :user) if login_as_member
82
103
  visit members_path
83
104
  end
84
105
 
@@ -107,9 +128,9 @@ shared_examples "participatory space members" do
107
128
  end
108
129
 
109
130
  it "lists all the members" do
110
- within ".layout-main__section" do
131
+ within "#assembly_members-grid" do
111
132
  expect(page).to have_css(".profile__user", count: 1)
112
- expect(page).to have_no_content(Decidim::ParticipatorySpace::MemberPresenter.new(unpublished_member).name)
133
+ expect(page).to have_no_content(Decidim::ParticipatorySpacePrivateUserPresenter.new(unpublished_member).name)
113
134
  end
114
135
 
115
136
  click_on(member.name)
@@ -117,5 +138,63 @@ shared_examples "participatory space members" do
117
138
  expect(page).to have_content("Profile")
118
139
  end
119
140
  end
141
+
142
+ context "when there are more members than the pagination per_page limit" do
143
+ let(:per_page) { Decidim::Paginable::OPTIONS.first }
144
+ let(:users) { create_list(:user, per_page + 5, organization: participatory_space.organization) }
145
+ let!(:extra_members) do
146
+ users.map do |user|
147
+ create(:participatory_space_private_user, privatable_to: participatory_space, user:, published: true)
148
+ end
149
+ end
150
+
151
+ before do
152
+ visit members_path
153
+ end
154
+
155
+ it "paginates the members list" do
156
+ within "#assembly_members-grid" do
157
+ expect(page).to have_css(".profile__user", count: per_page)
158
+ end
159
+ end
160
+
161
+ it "shows pagination controls" do
162
+ within("div[data-pagination]") do
163
+ expect(page).to have_css('nav[aria-label="Pagination"]')
164
+ end
165
+ end
166
+
167
+ it "navigates to the next page" do
168
+ within "nav[aria-label=\"Pagination\"]" do
169
+ click_on "Next"
170
+ end
171
+
172
+ within "#assembly_members-grid" do
173
+ expect(page).to have_css(".profile__user", count: 6)
174
+ end
175
+ end
176
+
177
+ it "maintains pagination when navigating back" do
178
+ within "nav[aria-label=\"Pagination\"]" do
179
+ click_on "Next"
180
+ end
181
+
182
+ within "nav[aria-label=\"Pagination\"]" do
183
+ click_on "Prev"
184
+ end
185
+
186
+ within "#assembly_members-grid" do
187
+ expect(page).to have_css(".profile__user", count: per_page)
188
+ end
189
+ end
190
+
191
+ it "shows the correct page number in the URL" do
192
+ within "nav[aria-label=\"Pagination\"]" do
193
+ click_on "Next"
194
+ end
195
+
196
+ expect(page).to have_current_path(/page=2/)
197
+ end
198
+ end
120
199
  end
121
200
  end
@@ -28,7 +28,7 @@ shared_examples "a version of a hidden object" do
28
28
  end
29
29
  end
30
30
 
31
- shared_examples "versions controller" do
31
+ shared_context "versions controller resource" do
32
32
  let(:base_params) do
33
33
  if resource.is_a?(Decidim::Participable)
34
34
  { :"#{resource.model_name.singular_route_key}_slug" => resource.slug }
@@ -45,6 +45,10 @@ shared_examples "versions controller" do
45
45
  request.env["decidim.current_component"] = resource.component
46
46
  end
47
47
  end
48
+ end
49
+
50
+ shared_examples "versions controller" do
51
+ include_context "versions controller resource"
48
52
 
49
53
  describe "GET show" do
50
54
  context "with an existing version" do
@@ -64,3 +68,21 @@ shared_examples "versions controller" do
64
68
  end
65
69
  end
66
70
  end
71
+
72
+ # The versions of a resource must be readable with the same `:read` permission
73
+ # as the resource itself. This ensures that a resource that is hidden, private,
74
+ # deleted or unpublished cannot be reached through its versions.
75
+ #
76
+ # Requires a `resource` that is not readable through its public `:read`
77
+ # permission.
78
+ shared_examples "versions controller denying unreadable resources" do
79
+ include_context "versions controller resource"
80
+
81
+ it "does not expose the versions" do
82
+ get :show, params: base_params.merge(id: 1)
83
+
84
+ expect(response).not_to have_http_status(:ok)
85
+ rescue ActiveRecord::RecordNotFound
86
+ # The resource is filtered out before the permission is evaluated.
87
+ end
88
+ end
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.31.7"
7
+ "0.31.8"
8
8
  end
9
9
  end
10
10
  end
data/lib/decidim/core.rb CHANGED
@@ -486,6 +486,15 @@ module Decidim
486
486
  Decidim::Env.new("DECIDIM_THROTTLING_PERIOD", "1").to_i.minutes
487
487
  end
488
488
 
489
+ # Max failed attempts for verification code confirmation before lockout.
490
+ mattr_accessor :verification_max_failed_attempts, default: Decidim::Env.new("DECIDIM_VERIFICATION_MAX_FAILED_ATTEMPTS", "5").to_i
491
+
492
+ # Time window after which a locked verification is automatically unlocked.
493
+ mattr_accessor :verification_unlock_in, default: Decidim::Env.new("DECIDIM_VERIFICATION_UNLOCK_IN", "30").to_i.minutes
494
+
495
+ # Time window (in minutes) after which a verification code expires (SMS only).
496
+ mattr_accessor :verification_code_expiry_minutes, default: Decidim::Env.new("DECIDIM_VERIFICATION_CODE_EXPIRY_MINUTES", "10").to_i
497
+
489
498
  # Time window were users can access the website even if their email is not confirmed.
490
499
  config_accessor :unconfirmed_access_for do
491
500
  Decidim::Env.new("DECIDIM_UNCONFIRMED_ACCESS_FOR", "0").to_i.days
@@ -15,6 +15,7 @@ module Decidim
15
15
  file_size: { less_than_or_equal_to: max_size },
16
16
  organization_present: true,
17
17
  uploader_content_type: true,
18
+ uploader_image_content: true,
18
19
  uploader_image_dimensions: true
19
20
  )
20
21
 
@@ -31,6 +31,10 @@ module Decidim
31
31
  options[:data][:controller] ||= ""
32
32
  options[:data][:controller] += " date-picker"
33
33
 
34
+ if (default_time = options.delete(:default_time))
35
+ options[:data][:default_time] = default_time
36
+ end
37
+
34
38
  field(attribute, options) do |opts|
35
39
  super(attribute, opts)
36
40
  end
@@ -54,6 +54,8 @@ module Decidim
54
54
  end
55
55
 
56
56
  def user(id: nil, nickname: nil)
57
+ return nil if id.blank? && nickname.blank?
58
+
57
59
  Core::UserEntityFinder.new.call(object, { id:, nickname: }, context)
58
60
  end
59
61