decidim-core 0.31.2 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -13
- data/app/cells/decidim/amendable/amend_button_card/show.erb +2 -2
- data/app/cells/decidim/amendable/amend_button_card_cell.rb +1 -1
- data/app/cells/decidim/author_cell.rb +0 -4
- data/app/cells/decidim/card_metadata_cell.rb +1 -1
- data/app/cells/decidim/comments_button_cell.rb +9 -1
- data/app/cells/decidim/content_blocks/announcement_settings_form/show.erb +5 -0
- data/app/cells/decidim/content_blocks/announcement_settings_form_cell.rb +17 -0
- data/app/cells/decidim/content_blocks/cta_settings_form/show.erb +1 -1
- data/app/cells/decidim/content_blocks/hero_settings_form/show.erb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_content_banner_settings_form/show.erb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_elements_with_cell_for_list_cell.rb +5 -1
- data/app/cells/decidim/content_blocks/highlighted_participatory_spaces_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
- data/app/cells/decidim/content_blocks/html_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/participatory_space_announcement_cell.rb +1 -3
- data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +1 -5
- data/app/cells/decidim/content_blocks/participatory_space_hero_settings_form/show.erb +1 -1
- data/app/cells/decidim/content_blocks/static_page/section_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/section_settings_form/show.erb +3 -1
- data/app/cells/decidim/content_blocks/static_page/summary_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/summary_settings_form/show.erb +3 -1
- data/app/cells/decidim/content_blocks/static_page/two_pane_section_cell.rb +2 -2
- data/app/cells/decidim/content_blocks/static_page/two_pane_section_settings_form/show.erb +4 -2
- data/app/cells/decidim/data_consent/category.erb +25 -38
- data/app/cells/decidim/footer_topics/show.erb +5 -8
- data/app/cells/decidim/{participatory_space_private_user → member}/show.erb +6 -6
- data/app/cells/decidim/{participatory_space_private_user_cell.rb → member_cell.rb} +1 -5
- data/app/cells/decidim/nav_links/show.erb +3 -3
- data/app/cells/decidim/onboarding_action_message_cell.rb +1 -0
- data/app/cells/decidim/profile/details.erb +1 -1
- data/app/cells/decidim/profile_cell.rb +1 -0
- data/app/cells/decidim/profile_member_of/show.erb +13 -0
- data/app/cells/decidim/profile_member_of_cell.rb +35 -0
- data/app/cells/decidim/report_button/already_reported_modal.erb +1 -1
- data/app/cells/decidim/report_button/flag_modal.erb +1 -1
- data/app/cells/decidim/report_user_button/already_reported_modal.erb +1 -1
- data/app/cells/decidim/report_user_button/flag_modal.erb +1 -1
- data/app/cells/decidim/resource_types_filter/show.erb +2 -2
- data/app/cells/decidim/share_text_widget/modal.erb +1 -1
- data/app/cells/decidim/share_widget/qr_code_modal.erb +1 -1
- data/app/cells/decidim/tags_cell.rb +1 -1
- data/app/cells/decidim/upload_modal/files.erb +5 -1
- data/app/cells/decidim/upload_modal_cell.rb +15 -1
- data/app/cells/decidim/versions_list/show.erb +25 -0
- data/app/commands/decidim/create_follow.rb +3 -5
- data/app/commands/decidim/create_user_report.rb +1 -1
- data/app/commands/decidim/destroy_account.rb +15 -4
- data/app/commands/decidim/multiple_attachments_methods.rb +42 -24
- data/app/commands/decidim/search.rb +5 -5
- data/app/controllers/concerns/decidim/ajax_permission_handler.rb +1 -1
- data/app/controllers/concerns/decidim/devise_controllers.rb +9 -0
- data/app/controllers/concerns/decidim/direct_upload.rb +3 -2
- data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +1 -1
- data/app/controllers/concerns/decidim/force_authentication.rb +10 -1
- data/app/controllers/concerns/decidim/impersonate_users.rb +4 -0
- data/app/controllers/concerns/decidim/locale_switcher.rb +52 -2
- data/app/controllers/concerns/decidim/needs_tos_accepted.rb +1 -1
- data/app/controllers/concerns/decidim/participatory_space/has_members_page.rb +27 -0
- data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -5
- data/app/controllers/decidim/account_controller.rb +1 -1
- data/app/controllers/decidim/amendments_controller.rb +5 -4
- data/app/controllers/decidim/components/base_controller.rb +20 -3
- data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
- data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
- data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
- data/app/controllers/decidim/devise/sessions_controller.rb +1 -1
- data/app/controllers/decidim/download_your_data_controller.rb +2 -2
- data/app/controllers/decidim/editor_images_controller.rb +1 -1
- data/app/controllers/decidim/follows_controller.rb +4 -3
- data/app/controllers/decidim/geolocation_controller.rb +1 -1
- data/app/controllers/decidim/likes_controller.rb +2 -1
- data/app/controllers/decidim/locales_controller.rb +3 -11
- data/app/controllers/decidim/messaging/conversations_controller.rb +3 -3
- data/app/controllers/decidim/newsletters_controller.rb +1 -1
- data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
- data/app/controllers/decidim/notifications_subscriptions_controller.rb +8 -0
- data/app/controllers/decidim/open_data_controller.rb +1 -1
- data/app/controllers/decidim/private_downloads_controller.rb +29 -0
- data/app/controllers/decidim/report_users_controller.rb +2 -2
- data/app/controllers/decidim/reports_controller.rb +1 -1
- data/app/controllers/decidim/user_activities_controller.rb +1 -2
- data/app/events/decidim/amendable/amendment_base_event.rb +7 -1
- data/app/events/decidim/welcome_notification_event.rb +1 -1
- data/app/forms/decidim/upload_validation_form.rb +1 -1
- data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -0
- data/app/helpers/decidim/active_link_to_helper.rb +136 -0
- data/app/helpers/decidim/amendments_helper.rb +3 -3
- data/app/helpers/decidim/check_boxes_tree_helper.rb +2 -2
- data/app/helpers/decidim/component_path_helper.rb +9 -4
- data/app/helpers/decidim/filters_helper.rb +0 -2
- data/app/helpers/decidim/mailer_helper.rb +36 -0
- data/app/helpers/decidim/menu_helper.rb +4 -5
- data/app/helpers/decidim/meta_tags_helper.rb +0 -2
- data/app/helpers/decidim/newsletters_helper.rb +4 -22
- data/app/helpers/decidim/paginate_helper.rb +14 -1
- data/app/helpers/decidim/sanitize_helper.rb +1 -0
- data/app/helpers/decidim/short_link_helper.rb +5 -5
- data/app/helpers/decidim/translations_helper.rb +4 -4
- data/app/jobs/decidim/delete_inactive_participants_job.rb +2 -2
- data/app/jobs/decidim/find_and_update_descendants_job.rb +8 -2
- data/app/jobs/decidim/process_inactive_participant_job.rb +0 -7
- data/app/jobs/decidim/update_search_indexes_job.rb +2 -2
- data/app/mailers/decidim/application_mailer.rb +11 -2
- data/app/mailers/decidim/decidim_devise_mailer.rb +1 -0
- data/app/mailers/decidim/delete_user_mailer.rb +14 -0
- data/app/mailers/decidim/participants_account_mailer.rb +0 -16
- data/app/mailers/decidim/reported_mailer.rb +4 -1
- data/app/models/decidim/action_log.rb +1 -1
- data/app/models/decidim/attachment.rb +20 -2
- data/app/models/decidim/authorization.rb +7 -0
- data/app/models/decidim/authorization_transfer.rb +1 -1
- data/app/models/decidim/component.rb +6 -9
- data/app/models/decidim/content_block.rb +3 -3
- data/app/models/decidim/moderation.rb +1 -1
- data/app/models/decidim/newsletter.rb +2 -2
- data/app/models/decidim/participatory_space/member.rb +55 -0
- data/app/models/decidim/private_download.rb +61 -0
- data/app/models/decidim/private_export.rb +6 -0
- data/app/models/decidim/resource_link.rb +1 -1
- data/app/models/decidim/short_link.rb +1 -1
- data/app/models/decidim/user.rb +2 -2
- data/app/models/decidim/user_base_entity.rb +17 -2
- data/app/models/decidim/user_moderation.rb +1 -1
- data/app/packs/src/decidim/a11y.js +29 -0
- data/app/packs/src/decidim/a11y.test.js +81 -0
- data/app/packs/src/decidim/confirm.js +8 -1
- data/app/packs/src/decidim/confirm.test.js +225 -0
- data/app/packs/src/decidim/controllers/accordion/accordion.test.js +272 -0
- data/app/packs/src/decidim/controllers/accordion/controller.js +117 -17
- data/app/packs/src/decidim/controllers/assign_role/assign_role.test.js +80 -0
- data/app/packs/src/decidim/controllers/assign_role/controller.js +27 -0
- data/app/packs/src/decidim/controllers/breadcrumb_truncate/breadcrumb_truncate.test.js +230 -0
- data/app/packs/src/decidim/controllers/breadcrumb_truncate/controller.js +172 -0
- data/app/packs/src/decidim/controllers/dropdown/controller.js +32 -0
- data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +215 -0
- data/app/packs/src/decidim/controllers/form_validator/form_validator.js +9 -8
- data/app/packs/src/decidim/controllers/form_validator/form_validator.test.js +28 -1
- data/app/packs/src/decidim/controllers/language_change/controller.js +1 -0
- data/app/packs/src/decidim/controllers/language_change/language_change.test.js +13 -0
- data/app/packs/src/decidim/controllers/main_menu/controller.js +152 -0
- data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +285 -0
- data/app/packs/src/decidim/controllers/mention/controller.js +296 -140
- data/app/packs/src/decidim/controllers/mention/input_mentions.test.js +120 -457
- data/app/packs/src/decidim/controllers/multiple_mentions/controller.js +68 -32
- data/app/packs/src/decidim/controllers/multiple_mentions/input_multiple_mentions.test.js +30 -23
- data/app/packs/src/decidim/controllers/password_toggler/controller.js +22 -1
- data/app/packs/src/decidim/controllers/password_toggler/password_toggler.test.js +11 -20
- data/app/packs/src/decidim/datepicker/datepicker_functions.js +26 -0
- data/app/packs/src/decidim/datepicker/generate_datepicker.js +3 -14
- data/app/packs/src/decidim/datepicker/generate_timepicker.js +3 -2
- data/app/packs/src/decidim/datepicker/test/datepicker_functions_adjust_picker_position.test.js +234 -0
- data/app/packs/src/decidim/direct_uploads/upload_field.js +4 -4
- data/app/packs/src/decidim/direct_uploads/upload_modal.js +12 -7
- data/app/packs/src/decidim/editor/common/suggestion.js +4 -2
- data/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +4 -1
- data/app/packs/src/decidim/editor/extensions/image/index.js +57 -16
- data/app/packs/src/decidim/editor/extensions/image/node_view.js +9 -1
- data/app/packs/src/decidim/editor/extensions/indent/index.js +9 -0
- data/app/packs/src/decidim/editor/extensions/link/bubble_menu.js +34 -6
- data/app/packs/src/decidim/editor/extensions/link/index.js +53 -12
- data/app/packs/src/decidim/editor/extensions/mention/index.js +18 -5
- data/app/packs/src/decidim/editor/extensions/mention_resource/index.js +16 -7
- data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +13 -4
- data/app/packs/src/decidim/editor/test/extensions/heading.test.js +1 -1
- data/app/packs/src/decidim/editor/test/extensions/image.test.js +26 -28
- data/app/packs/src/decidim/editor/test/extensions/image_links.test.js +161 -0
- data/app/packs/src/decidim/editor/test/extensions/mention.test.js +6 -2
- data/app/packs/src/decidim/editor/test/extensions/video_embed.test.js +27 -15
- data/app/packs/src/decidim/editor/test/helpers.js +8 -10
- data/app/packs/src/decidim/editor/test/toolbar/full.test.js +15 -4
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_block.js +8 -4
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_formatting.js +5 -1
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_indent.js +9 -5
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +5 -1
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_list.js +8 -4
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_styling.js +13 -9
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_content_styling.js +6 -2
- data/app/packs/src/decidim/geocoding/reverse_geocoding.js +15 -5
- data/app/packs/src/decidim/geocoding/reverse_geocoding.test.js +197 -0
- data/app/packs/src/decidim/index.js +4 -4
- data/app/packs/src/decidim/map/controller.js +10 -1
- data/app/packs/src/decidim/refactor/moved/focus_guard.js +16 -16
- data/app/packs/src/decidim/refactor/moved/focus_guard.test.js +136 -0
- data/app/packs/src/decidim/sw/push-permissions.js +48 -13
- data/app/packs/src/decidim/sw/sw.js +1 -1
- data/app/packs/src/decidim/utilities/text.js +6 -6
- data/app/packs/stylesheets/decidim/_cards.scss +15 -6
- data/app/packs/stylesheets/decidim/_conversations.scss +14 -0
- data/app/packs/stylesheets/decidim/_cookies.scss +13 -5
- data/app/packs/stylesheets/decidim/_datepicker.scss +0 -8
- data/app/packs/stylesheets/decidim/_documents.scss +1 -1
- data/app/packs/stylesheets/decidim/_dropdown.scss +22 -32
- data/app/packs/stylesheets/decidim/_editor_suggestions.scss +49 -0
- data/app/packs/stylesheets/decidim/_flash.scss +1 -1
- data/app/packs/stylesheets/decidim/_floating_help.scss +1 -1
- data/app/packs/stylesheets/decidim/_footer.scss +27 -31
- data/app/packs/stylesheets/decidim/_forms.scss +5 -1
- data/app/packs/stylesheets/decidim/_header.scss +183 -48
- data/app/packs/stylesheets/decidim/_language_chooser.scss +79 -0
- data/app/packs/stylesheets/decidim/_participatory_spaces.scss +1 -1
- data/app/packs/stylesheets/decidim/_rich_text.scss +17 -0
- data/app/packs/stylesheets/decidim/_tom_select.scss +23 -0
- data/app/packs/stylesheets/decidim/application.scss +3 -0
- data/app/packs/stylesheets/decidim/editor.scss +12 -33
- data/app/packs/stylesheets/decidim/geocoding_addons.scss +10 -2
- data/app/presenters/decidim/admin_log/participatory_space/member_presenter.rb +40 -0
- data/app/presenters/decidim/admin_log/static_page_resource_presenter.rb +1 -1
- data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
- data/app/presenters/decidim/breadcrumb_root_menu_item_presenter.rb +3 -3
- data/app/presenters/decidim/footer_menu_presenter.rb +2 -4
- data/app/presenters/decidim/log/user_presenter.rb +1 -0
- data/app/presenters/decidim/log/value_types/access_mode_presenter.rb +45 -0
- data/app/presenters/decidim/menu_item_presenter.rb +15 -3
- data/app/presenters/decidim/participatory_space/member_presenter.rb +48 -0
- data/app/presenters/decidim/resource_locator_presenter.rb +22 -3
- data/app/presenters/decidim/stats_presenter.rb +1 -1
- data/app/queries/decidim/last_activity.rb +1 -1
- data/app/resolvers/decidim/meta_image_url_resolver.rb +7 -0
- data/app/serializers/decidim/exporters/participatory_space_serializer.rb +15 -1
- data/app/services/decidim/email_notification_generator.rb +2 -0
- data/app/services/decidim/notification_generator.rb +4 -0
- data/app/services/decidim/notifications_subscriptions_persistor.rb +6 -0
- data/app/services/decidim/push_subscription_endpoint_validator.rb +34 -0
- data/app/services/decidim/send_push_notification.rb +5 -1
- data/app/uploaders/decidim/image_uploader.rb +1 -1
- data/app/uploaders/decidim/organization_favicon_uploader.rb +4 -9
- data/app/validators/uploader_image_dimensions_validator.rb +13 -11
- data/app/views/decidim/delete_user_mailer/delete.html.erb +6 -0
- data/app/views/decidim/devise/invitations/edit.html.erb +3 -3
- data/app/views/decidim/devise/registrations/new.html.erb +1 -0
- data/app/views/decidim/devise/shared/_tos_fields.html.erb +3 -3
- data/app/views/decidim/gamification/badges/index.html.erb +1 -1
- data/app/views/decidim/homepage/show.html.erb +2 -2
- data/app/views/decidim/last_activities/index.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/_error_modal.html.erb +11 -19
- data/app/views/decidim/messaging/conversations/_new_conversation_button.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/_reply.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/error.js.erb +12 -7
- data/app/views/decidim/messaging/conversations/new.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/show.html.erb +2 -2
- data/app/views/decidim/newsletters/unsubscribe.html.erb +1 -1
- data/app/views/decidim/notification_mailer/event_received.html.erb +3 -3
- data/app/views/decidim/notifications_settings/show.html.erb +5 -5
- data/app/views/decidim/offline/show.html.erb +1 -1
- data/app/views/decidim/pages/_tabbed.html.erb +3 -3
- data/app/views/decidim/pages/index.html.erb +1 -1
- data/app/views/decidim/participatory_space/members/_member.html.erb +1 -0
- data/app/views/decidim/profiles/show.html.erb +1 -1
- data/app/views/decidim/searches/_filters.html.erb +1 -1
- data/app/views/decidim/shared/_filters.html.erb +5 -5
- data/app/views/decidim/shared/_resource_actions.html.erb +4 -4
- data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
- data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +2 -2
- data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
- data/app/views/decidim/shared/filters/_dropdown_label.html.erb +4 -3
- data/app/views/decidim/user_activities/index.html.erb +1 -1
- data/app/views/devise/mailer/{invite_private_user.html.erb → invite_member.html.erb} +2 -2
- data/app/views/devise/mailer/{invite_private_user.text.erb → invite_member.text.erb} +2 -2
- data/app/views/layouts/decidim/_head.html.erb +2 -2
- data/app/views/layouts/decidim/_wrapper.html.erb +3 -3
- data/app/views/layouts/decidim/footer/_focus_mode_main.html.erb +0 -1
- data/app/views/layouts/decidim/footer/_main.html.erb +1 -2
- data/app/views/layouts/decidim/footer/_main_links.html.erb +56 -28
- data/app/views/layouts/decidim/header/_focus_mode_back_button.html.erb +4 -1
- data/app/views/layouts/decidim/header/_main.html.erb +17 -8
- data/app/views/layouts/decidim/header/_main_language_chooser.html.erb +24 -0
- data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +56 -56
- data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +2 -2
- data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +3 -1
- data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +18 -5
- data/app/views/layouts/decidim/header/_main_search.html.erb +3 -3
- data/app/views/layouts/decidim/header/_menu.html.erb +5 -5
- data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +40 -12
- data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile.html.erb +33 -0
- data/app/views/layouts/decidim/shared/_layout_center.html.erb +1 -1
- data/app/views/layouts/decidim/shared/_layout_item.html.erb +1 -1
- data/app/views/layouts/decidim/shared/_layout_two_col.html.erb +1 -1
- data/config/initializers/decidim_locale_aware_named_route_helper.rb +16 -0
- data/config/initializers/devise.rb +6 -0
- data/config/initializers/invisible_captcha.rb +1 -0
- data/config/locales/ar.yml +6 -38
- data/config/locales/bg.yml +3 -39
- data/config/locales/ca-IT.yml +91 -58
- data/config/locales/ca.yml +91 -58
- data/config/locales/cs.yml +54 -58
- data/config/locales/de.yml +45 -68
- data/config/locales/el.yml +3 -31
- data/config/locales/en.yml +88 -55
- data/config/locales/es-MX.yml +93 -60
- data/config/locales/es-PY.yml +93 -60
- data/config/locales/es.yml +95 -62
- data/config/locales/eu.yml +124 -92
- data/config/locales/fi-plain.yml +93 -55
- data/config/locales/fi.yml +96 -58
- data/config/locales/fr-CA.yml +70 -52
- data/config/locales/fr.yml +71 -54
- data/config/locales/ga-IE.yml +3 -1
- data/config/locales/gl.yml +3 -31
- data/config/locales/hu.yml +7 -40
- data/config/locales/id-ID.yml +3 -30
- data/config/locales/is-IS.yml +0 -6
- data/config/locales/it.yml +15 -33
- data/config/locales/ja.yml +105 -71
- data/config/locales/lb.yml +3 -33
- data/config/locales/lt.yml +4 -37
- data/config/locales/lv.yml +3 -30
- data/config/locales/nl.yml +3 -33
- data/config/locales/no.yml +3 -33
- data/config/locales/pl.yml +7 -41
- data/config/locales/pt-BR.yml +24 -65
- data/config/locales/pt.yml +3 -33
- data/config/locales/ro-RO.yml +12 -55
- data/config/locales/ru.yml +0 -16
- data/config/locales/sk.yml +1417 -32
- data/config/locales/sv.yml +44 -62
- data/config/locales/tr-TR.yml +20 -37
- data/config/locales/uk.yml +0 -9
- data/config/locales/zh-CN.yml +3 -30
- data/config/locales/zh-TW.yml +4 -35
- data/config/routes.rb +140 -76
- data/db/data/20251213075429_rename_members_in_action_log.rb +22 -0
- data/db/data/20260319145808_rename_send_to_members_in_newsletter.rb +27 -0
- data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +13 -15
- data/db/migrate/20250217192438_convert_user_groups_into_users.rb +3 -2
- data/db/migrate/20250523104311_move_cta_to_hero_content_block.rb +1 -1
- data/db/migrate/20250527122040_move_highlighted_content_banner_settings_to_content_block.rb +1 -1
- data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +2 -2
- data/db/migrate/20251112132305_remove_legacy_images_from_core_module.rb +27 -0
- data/db/migrate/20251205122428_rename_participatory_space_private_users_to_members.rb +9 -0
- data/db/migrate/20251216185133_rename_privatable_to_to_participatory_space_in_members.rb +10 -0
- data/db/migrate/20260208201405_remove_user_group_core.rb +21 -0
- data/db/migrate/20260208201406_remove_user_group_memberships.rb +30 -0
- data/db/migrate/20260208201407_remove_user_group_organizations.rb +11 -0
- data/db/migrate/20260217152425_remove_enable_participatory_space_filters_from_decidim_organizations.rb +7 -0
- data/db/migrate/20260314081619_add_index_on_decidim_members.rb +25 -0
- data/decidim-core.gemspec +28 -28
- data/lib/decidim/acts_as_tree.rb +12 -12
- data/lib/decidim/admin_filters_registry.rb +1 -1
- data/lib/decidim/amendable.rb +5 -1
- data/lib/decidim/api/functions/category_list.rb +1 -0
- data/lib/decidim/api/functions/component_finder_base.rb +1 -1
- data/lib/decidim/api/functions/component_list.rb +3 -1
- data/lib/decidim/api/functions/component_list_base.rb +1 -0
- data/lib/decidim/api/functions/participatory_space_finder_base.rb +1 -1
- data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -0
- data/lib/decidim/api/functions/user_entity_list.rb +2 -1
- data/lib/decidim/api/interfaces/amendable_entity_interface.rb +1 -0
- data/lib/decidim/api/interfaces/amendable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/attachable_collection_interface.rb +1 -0
- data/lib/decidim/api/interfaces/attachable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/author_interface.rb +2 -1
- data/lib/decidim/api/interfaces/authorable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/categories_container_interface.rb +1 -0
- data/lib/decidim/api/interfaces/categorizable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/coauthorable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/component_interface.rb +9 -8
- data/lib/decidim/api/interfaces/fingerprint_interface.rb +1 -0
- data/lib/decidim/api/interfaces/followable_interface.rb +2 -0
- data/lib/decidim/api/interfaces/likeable_interface.rb +2 -2
- data/lib/decidim/api/interfaces/localizable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -0
- data/lib/decidim/api/interfaces/referable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/scopable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/taxonomizable_interface.rb +1 -0
- data/lib/decidim/api/interfaces/timestamps_interface.rb +1 -0
- data/lib/decidim/api/interfaces/traceable_interface.rb +1 -0
- data/lib/decidim/api/types/attachment_collection_type.rb +5 -3
- data/lib/decidim/api/types/attachment_type.rb +11 -4
- data/lib/decidim/api/types/badge_score_type.rb +28 -0
- data/lib/decidim/api/types/moderation_type.rb +25 -0
- data/lib/decidim/api/types/participant_details_type.rb +17 -0
- data/lib/decidim/api/types/reportable_type.rb +18 -0
- data/lib/decidim/api/types/reportable_user_type.rb +17 -0
- data/lib/decidim/api/types/static_page_topic_type.rb +16 -0
- data/lib/decidim/api/types/static_page_type.rb +22 -0
- data/lib/decidim/api/types/taxonomy_type.rb +2 -0
- data/lib/decidim/api/types/user_moderation_type.rb +36 -0
- data/lib/decidim/api/types/user_type.rb +13 -0
- data/lib/decidim/asset_router/pipeline.rb +1 -1
- data/lib/decidim/asset_router/storage.rb +9 -9
- data/lib/decidim/assets/tailwind/tailwind.config.js.erb +4 -1
- data/lib/decidim/attachment_attributes.rb +58 -9
- data/lib/decidim/attribute_encryptor.rb +51 -10
- data/lib/decidim/attribute_object/model.rb +0 -5
- data/lib/decidim/block_registry.rb +1 -1
- data/lib/decidim/coauthorable.rb +2 -1
- data/lib/decidim/command.rb +2 -1
- data/lib/decidim/content_parsers/blob_parser.rb +3 -3
- data/lib/decidim/content_processor.rb +1 -1
- data/lib/decidim/content_renderers/base_renderer.rb +112 -0
- data/lib/decidim/content_renderers/blob_renderer.rb +6 -9
- data/lib/decidim/content_renderers/mention_resource_renderer.rb +10 -6
- data/lib/decidim/content_renderers/resource_renderer.rb +16 -7
- data/lib/decidim/content_renderers/user_renderer.rb +11 -9
- data/lib/decidim/core/api.rb +8 -0
- data/lib/decidim/core/content_blocks/registry_manager.rb +4 -10
- data/lib/decidim/core/engine.rb +10 -34
- data/lib/decidim/core/menu.rb +0 -26
- data/lib/decidim/core/test/factories.rb +32 -18
- data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +175 -0
- data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +244 -0
- data/lib/decidim/core/test/shared_examples/admin_resource_gallery_examples.rb +10 -10
- data/lib/decidim/core/test/shared_examples/amendable/amendment_event_examples.rb +2 -2
- data/lib/decidim/core/test/shared_examples/amendable/amendment_promoted_event_examples.rb +3 -3
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +147 -117
- data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +2 -0
- data/lib/decidim/core/test/shared_examples/has_members.rb +63 -0
- data/lib/decidim/core/test/shared_examples/has_space_in_mcell_examples.rb +2 -1
- data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +1 -1
- data/lib/decidim/core/test/shared_examples/map_examples.rb +1 -1
- data/lib/decidim/core/test/shared_examples/participant_details_examples.rb +16 -0
- data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +10 -10
- data/lib/decidim/core/test/shared_examples/participatory_space_members_shared_examples.rb +121 -0
- data/lib/decidim/core/test/shared_examples/resource_liked_event_examples.rb +3 -3
- data/lib/decidim/core/test/shared_examples/resource_locator_presenter_examples.rb +7 -7
- data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +3 -3
- data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +2 -2
- data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -0
- data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
- data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +1 -1
- data/lib/decidim/core/test.rb +2 -1
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/core.rb +222 -335
- data/lib/decidim/download_your_data_serializers/{download_your_data_participatory_space_private_user_serializer.rb → download_your_data_member_serializer.rb} +6 -6
- data/lib/decidim/download_your_data_serializers.rb +2 -2
- data/lib/decidim/engine_router.rb +31 -6
- data/lib/decidim/exporters/csv.rb +1 -1
- data/lib/decidim/filter_form_builder.rb +1 -1
- data/lib/decidim/form_builder.rb +58 -36
- data/{app/controllers/concerns → lib}/decidim/form_factory.rb +11 -1
- data/lib/decidim/has_settings.rb +2 -2
- data/lib/decidim/legacy_form_builder.rb +1 -0
- data/lib/decidim/locale_router_detector.rb +41 -0
- data/lib/decidim/maintenance/import_models/scope.rb +1 -1
- data/lib/decidim/maintenance/import_models.rb +0 -2
- data/lib/decidim/maintenance/taxonomy_importer.rb +1 -1
- data/lib/decidim/map/autocomplete.rb +4 -3
- data/lib/decidim/map/dynamic_map.rb +3 -1
- data/lib/decidim/map/frontend.rb +1 -1
- data/lib/decidim/map/geocoding.rb +2 -2
- data/lib/decidim/map/static_map.rb +10 -22
- data/lib/decidim/map/utility.rb +3 -6
- data/lib/decidim/map.rb +2 -2
- data/lib/decidim/menu.rb +1 -1
- data/lib/decidim/menu_item.rb +1 -0
- data/lib/decidim/menu_registry.rb +1 -1
- data/lib/decidim/moderation_tools.rb +1 -1
- data/lib/decidim/newsletter_encryptor.rb +5 -8
- data/lib/decidim/organization_settings.rb +2 -2
- data/lib/decidim/participable.rb +1 -0
- data/lib/decidim/participatory_space/has_members.rb +61 -0
- data/lib/decidim/participatory_space_manifest.rb +0 -4
- data/lib/decidim/participatory_space_resourceable.rb +10 -1
- data/lib/decidim/participatory_space_user.rb +1 -1
- data/lib/decidim/routes/locale_redirects.rb +47 -0
- data/lib/decidim/routes.rb +7 -0
- data/lib/decidim/search_resource_fields_mapper.rb +3 -4
- data/lib/decidim/searchable.rb +9 -4
- data/lib/decidim/seeds.rb +17 -0
- data/lib/decidim/shakapacker/runner.rb +4 -4
- data/lib/decidim/shakapacker/shakapacker.yml +28 -3
- data/lib/decidim/taxonomizable.rb +1 -1
- data/lib/decidim/translatable_attributes.rb +9 -3
- data/lib/decidim/view_model.rb +5 -1
- data/lib/devise/models/decidim_newsletterable.rb +1 -1
- data/lib/tasks/decidim_mailers_tasks.rake +31 -9
- data/lib/tasks/decidim_procfile.rake +1 -1
- data/lib/tasks/decidim_tasks.rake +0 -1
- data/lib/tasks/decidim_taxonomies.rake +1 -1
- data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +0 -1
- data/lib/tasks/upgrade/decidim_encryption.rake +12 -0
- data/lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake +0 -1
- data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +1 -1
- data/lib/tasks/upgrade/{fix_deleted_private_follows.rake → fix_deleted_members_follows.rake} +5 -5
- data/lib/tasks/upgrade/migrations.rake +0 -1
- data/lib/tasks/upgrade/user_groups_migration.rake +0 -1
- metadata +244 -132
- data/app/cells/decidim/content_blocks/global_menu/show.erb +0 -11
- data/app/cells/decidim/content_blocks/global_menu_cell.rb +0 -35
- data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity/show.erb +0 -10
- data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity_cell.rb +0 -49
- data/app/cells/decidim/participatory_space_dropdown_metadata/links.erb +0 -9
- data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +0 -1
- data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +0 -11
- data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +0 -26
- data/app/commands/decidim/gallery_methods.rb +0 -107
- data/app/controllers/concerns/decidim/has_members_page.rb +0 -25
- data/app/jobs/decidim/newsletters_opt_in_job.rb +0 -11
- data/app/jobs/decidim/user_report_job.rb +0 -11
- data/app/models/decidim/participatory_space_private_user.rb +0 -51
- data/app/packs/src/decidim/controllers/sticky_header/controller.js +0 -116
- data/app/packs/src/decidim/controllers/sticky_header/sticky_header.test.js +0 -320
- data/app/packs/src/decidim/dropdown_menu.js +0 -18
- data/app/packs/src/decidim/identity_selector_dialog.js +0 -33
- data/app/packs/src/decidim/vendor/tribute.js +0 -1890
- data/app/packs/stylesheets/decidim/_tribute.scss +0 -36
- data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +0 -38
- data/app/presenters/decidim/participatory_space_private_user_presenter.rb +0 -46
- data/app/views/decidim/participants_account_mailer/removal_notification.html.erb +0 -11
- data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +0 -1
- data/app/views/layouts/decidim/footer/_main_language_chooser.html.erb +0 -26
- data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +0 -34
- data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +0 -10
- data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +0 -17
- data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +0 -2
- data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +0 -33
- data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +0 -25
- data/lib/decidim/core/test/shared_examples/has_private_users.rb +0 -63
- data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +0 -81
- data/lib/decidim/has_private_users.rb +0 -57
- data/lib/decidim/maintenance/import_models/assembly_type.rb +0 -49
- data/lib/decidim/maintenance/import_models/participatory_process_type.rb +0 -21
- data/lib/decidim/query_extensions.rb +0 -64
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
module Decidim
|
|
4
4
|
# Helper that provides methods to render links with utm codes, and replaced name
|
|
5
5
|
module NewslettersHelper
|
|
6
|
+
include Decidim::SanitizeHelper
|
|
7
|
+
include Decidim::MailerHelper
|
|
8
|
+
|
|
6
9
|
# If the newsletter body there are some links and the Decidim.track_newsletter_links = true
|
|
7
10
|
# it will be replaced with the utm_codes method described below.
|
|
8
11
|
# for example transform "https://es.lipsum.com/" to "https://es.lipsum.com/?utm_source=localhost&utm_campaign=newsletter_11"
|
|
@@ -19,7 +22,7 @@ module Decidim
|
|
|
19
22
|
|
|
20
23
|
content = interpret_name(content, user)
|
|
21
24
|
content = track_newsletter_links(content, id, host)
|
|
22
|
-
|
|
25
|
+
decidim_transform_image_urls(content, host)
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
# this method is used to generate the root link on mail with the utm_codes
|
|
@@ -67,27 +70,6 @@ module Decidim
|
|
|
67
70
|
content.gsub("%{name}", user.name)
|
|
68
71
|
end
|
|
69
72
|
|
|
70
|
-
# Find each img HTML tag with relative path in src attribute
|
|
71
|
-
# For each URL, prepends the decidim.root_url
|
|
72
|
-
# If host is not defined it returns full content
|
|
73
|
-
#
|
|
74
|
-
# @param content [String] - the string to convert
|
|
75
|
-
# @param host [String] - the Decidim::Organization host to replace
|
|
76
|
-
#
|
|
77
|
-
# @return [String] - the content converted
|
|
78
|
-
#
|
|
79
|
-
def transform_image_urls(content, host)
|
|
80
|
-
return content if host.blank?
|
|
81
|
-
|
|
82
|
-
content.scan(/src\s*=\s*"([^"]*)"/).each do |src|
|
|
83
|
-
root_url = decidim.root_url(host:)[0..-2]
|
|
84
|
-
src_replaced = "#{root_url}#{src.first}"
|
|
85
|
-
content = content.gsub(/src\s*=\s*"([^"]*#{src.first})"/, %(src="#{src_replaced}"))
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
content
|
|
89
|
-
end
|
|
90
|
-
|
|
91
73
|
# Add tracking query params to each links
|
|
92
74
|
#
|
|
93
75
|
# @param content [String] - the string to convert
|
|
@@ -16,9 +16,22 @@ module Decidim
|
|
|
16
16
|
content_tag :div, class: "flex flex-col-reverse md:flex-row items-center justify-between gap-1 py-8 md:py-16 md:flex-wrap", data: { pagination: "" } do
|
|
17
17
|
template = ""
|
|
18
18
|
template += render(partial: "decidim/shared/results_per_page", locals: { per_page: }, formats: [:html]) if collection.total_pages.positive?
|
|
19
|
-
template += paginate collection, window: 2, outer_window: 1, theme: "decidim", params: paginate_params
|
|
19
|
+
template += paginate collection, window: 2, outer_window: 1, theme: "decidim", params: pagination_params(paginate_params)
|
|
20
20
|
template.html_safe
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def pagination_params(paginate_params)
|
|
27
|
+
request_params = params.to_unsafe_h.except("locale", :locale)
|
|
28
|
+
request_params["q"] = request_params["q"].except("locale", :locale) if request_params["q"].is_a?(Hash)
|
|
29
|
+
request_params[:locale] = nil if admin_controller_with_locale_prefix?
|
|
30
|
+
request_params.merge(paginate_params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def admin_controller_with_locale_prefix?
|
|
34
|
+
request.path_parameters[:locale].present? && controller_path.to_s.include?("/admin/")
|
|
35
|
+
end
|
|
23
36
|
end
|
|
24
37
|
end
|
|
@@ -131,6 +131,7 @@ module Decidim
|
|
|
131
131
|
# @param method [Symbol] Method name
|
|
132
132
|
#
|
|
133
133
|
# @return ActiveSupport::SafeBuffer
|
|
134
|
+
# @param [Object, nil] presenter_class
|
|
134
135
|
def render_sanitized_content(resource, method, presenter_class: nil)
|
|
135
136
|
content = present(resource, presenter_class:).send(method, links: true, strip_tags: !try(:safe_content?))
|
|
136
137
|
|
|
@@ -10,11 +10,11 @@ module Decidim
|
|
|
10
10
|
# also resolves the current mounted route name to make it possible to refer
|
|
11
11
|
# to the same context when redirecting the short URL to correct full URL.
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# @return [String] The short URL
|
|
13
|
+
# Accepts keyword arguments such as:
|
|
14
|
+
# - `route_name`: the route name to link to
|
|
15
|
+
# - `params`: query parameters for the redirect
|
|
16
|
+
#
|
|
17
|
+
# @return [String] The short URL.
|
|
18
18
|
def short_url(**)
|
|
19
19
|
target = respond_to?(:current_component) && current_component
|
|
20
20
|
target ||= respond_to?(:current_participatory_space) && current_participatory_space
|
|
@@ -30,8 +30,8 @@ module Decidim
|
|
|
30
30
|
#
|
|
31
31
|
# Returns a Hash with the locales as keys and the empty strings as values.
|
|
32
32
|
def empty_translatable(locales = Decidim.available_locales)
|
|
33
|
-
locales.
|
|
34
|
-
|
|
33
|
+
locales.to_h do |locale|
|
|
34
|
+
[locale.to_s, ""]
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -49,8 +49,8 @@ module Decidim
|
|
|
49
49
|
def ensure_translatable(value, locales = Decidim.available_locales)
|
|
50
50
|
return empty_translatable(locales) unless value.is_a?(Hash)
|
|
51
51
|
|
|
52
|
-
locales.
|
|
53
|
-
|
|
52
|
+
locales.to_h do |locale|
|
|
53
|
+
[locale.to_s, value[locale.to_s] || value[locale] || ""]
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -14,9 +14,9 @@ module Decidim
|
|
|
14
14
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
|
-
def enqueue_jobs(users, action, *
|
|
17
|
+
def enqueue_jobs(users, action, *)
|
|
18
18
|
users.find_each do |user|
|
|
19
|
-
ProcessInactiveParticipantJob.perform_later(user.id, action, *
|
|
19
|
+
ProcessInactiveParticipantJob.perform_later(user.id, action, *)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -4,8 +4,14 @@ module Decidim
|
|
|
4
4
|
# Update search indexes for each descendants of a given element
|
|
5
5
|
class FindAndUpdateDescendantsJob < ApplicationJob
|
|
6
6
|
queue_as :default
|
|
7
|
+
MAX_DEPTH = 5
|
|
8
|
+
|
|
9
|
+
def perform(element, current_depth = 0)
|
|
10
|
+
if current_depth >= MAX_DEPTH
|
|
11
|
+
Rails.logger.warn "Max depth of #{MAX_DEPTH} reached for element #{element.class.name} with id #{element.id}. Stopping recursion."
|
|
12
|
+
return
|
|
13
|
+
end
|
|
7
14
|
|
|
8
|
-
def perform(element)
|
|
9
15
|
descendants_collector = components_for(element)
|
|
10
16
|
descendants_collector << element.comments.to_a if element.respond_to?(:comments)
|
|
11
17
|
|
|
@@ -14,7 +20,7 @@ module Decidim
|
|
|
14
20
|
descendants_collector.each do |descendants|
|
|
15
21
|
next if descendants.blank?
|
|
16
22
|
|
|
17
|
-
Decidim::UpdateSearchIndexesJob.perform_later(descendants)
|
|
23
|
+
Decidim::UpdateSearchIndexesJob.perform_later(descendants, current_depth + 1)
|
|
18
24
|
end
|
|
19
25
|
end
|
|
20
26
|
|
|
@@ -31,13 +31,6 @@ module Decidim
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def process_remove_user(user)
|
|
34
|
-
email = user.email
|
|
35
|
-
name = user.name
|
|
36
|
-
locale = user.locale
|
|
37
|
-
organization = user.organization
|
|
38
|
-
|
|
39
|
-
ParticipantsAccountMailer.removal_notification(email, name, locale, organization).deliver_later
|
|
40
|
-
|
|
41
34
|
Decidim::DestroyAccount.call(
|
|
42
35
|
Decidim::DeleteAccountForm.from_params(
|
|
43
36
|
delete_reason: I18n.t("decidim.account.destroy.inactive_account_removal_reason", inactivity_period: Decidim.delete_inactive_users_after_days)
|
|
@@ -4,8 +4,8 @@ module Decidim
|
|
|
4
4
|
class UpdateSearchIndexesJob < ApplicationJob
|
|
5
5
|
queue_as :default
|
|
6
6
|
|
|
7
|
-
def perform(elements)
|
|
8
|
-
elements.each { |element| element.try(:try_update_index_for_search_resource) }
|
|
7
|
+
def perform(elements, current_depth = 0)
|
|
8
|
+
elements.each { |element| element.try(:try_update_index_for_search_resource, current_depth) }
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -7,8 +7,13 @@ module Decidim
|
|
|
7
7
|
include LocalisedMailer
|
|
8
8
|
include MultitenantAssetHost
|
|
9
9
|
include Decidim::SanitizeHelper
|
|
10
|
+
include Decidim::MailerHelper
|
|
10
11
|
include Decidim::OrganizationHelper
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
helper Decidim::SanitizeHelper
|
|
14
|
+
helper Decidim::MailerHelper
|
|
15
|
+
helper_method :organization_name, :current_locale, :decidim_escape_translated, :decidim_sanitize_translated, :translated_attribute, :decidim_sanitize,
|
|
16
|
+
:decidim_sanitize_newsletter
|
|
12
17
|
|
|
13
18
|
after_action :set_smtp
|
|
14
19
|
after_action :set_from
|
|
@@ -20,10 +25,14 @@ module Decidim
|
|
|
20
25
|
|
|
21
26
|
attr_reader :organization
|
|
22
27
|
|
|
28
|
+
def current_locale
|
|
29
|
+
I18n.locale || I18n.default_locale
|
|
30
|
+
end
|
|
31
|
+
|
|
23
32
|
def set_smtp
|
|
24
33
|
return if organization.nil? || organization.smtp_settings.blank? || organization.smtp_settings.except("from", "from_label", "from_email").all?(&:blank?)
|
|
25
34
|
|
|
26
|
-
mail.reply_to = mail.reply_to || Decidim.config.
|
|
35
|
+
mail.reply_to = mail.reply_to || Decidim.config.mailer_sender
|
|
27
36
|
mail.delivery_method.settings.merge!(
|
|
28
37
|
address: organization.smtp_settings["address"],
|
|
29
38
|
port: organization.smtp_settings["port"],
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
class DeleteUserMailer < ApplicationMailer
|
|
5
|
+
# This email is being sent when a user deletes his own account, or when the user was inactive for too long.
|
|
6
|
+
def delete(user_email:, user_name:, locale:, organization:)
|
|
7
|
+
I18n.with_locale(locale) do
|
|
8
|
+
@user_name = user_name
|
|
9
|
+
@organization = organization
|
|
10
|
+
mail(to: user_email, subject: I18n.t("decidim.delete_user_mailer.subject"))
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -18,21 +18,5 @@ module Decidim
|
|
|
18
18
|
mail(to: user.email, subject:)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
-
|
|
22
|
-
# Notify user about account removal due to inactivity
|
|
23
|
-
def removal_notification(email, name, locale, organization)
|
|
24
|
-
@email = email
|
|
25
|
-
@user_name = name
|
|
26
|
-
@organization = organization
|
|
27
|
-
|
|
28
|
-
I18n.with_locale(locale) do
|
|
29
|
-
subject = I18n.t(
|
|
30
|
-
"decidim.participants_account_mailer.removal_notification.subject",
|
|
31
|
-
organization_name: organization_name(@organization)
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
mail(to: email, subject:)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
21
|
end
|
|
38
22
|
end
|
|
@@ -72,7 +72,10 @@ module Decidim
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def author_profile_url
|
|
75
|
-
@author_profile_url ||= @author.is_a?(Decidim::UserBaseEntity) && !@author.deleted?
|
|
75
|
+
@author_profile_url ||= if @author.is_a?(Decidim::UserBaseEntity) && !@author.deleted?
|
|
76
|
+
decidim.profile_url(@author.nickname,
|
|
77
|
+
host: @organization.host)
|
|
78
|
+
end
|
|
76
79
|
end
|
|
77
80
|
|
|
78
81
|
def original_language(reportable)
|
|
@@ -262,7 +262,7 @@ module Decidim
|
|
|
262
262
|
participatory_space_lazy.present? &&
|
|
263
263
|
!resource_lazy.try(:deleted?) &&
|
|
264
264
|
!resource_lazy.try(:hidden?) &&
|
|
265
|
-
(participatory_space_lazy.try(:
|
|
265
|
+
(participatory_space_lazy.try(:transparent?) || !resource_lazy.respond_to?(:can_participate?) || resource_lazy.try(:can_participate?, user))
|
|
266
266
|
rescue NameError => e
|
|
267
267
|
Rails.logger.warn "Failed resource for #{self.class.name}(id=#{id}): #{e.message}"
|
|
268
268
|
|
|
@@ -88,7 +88,7 @@ module Decidim
|
|
|
88
88
|
# Returns String.
|
|
89
89
|
def file_type
|
|
90
90
|
if file?
|
|
91
|
-
|
|
91
|
+
file.filename.extension&.downcase
|
|
92
92
|
elsif link?
|
|
93
93
|
"link"
|
|
94
94
|
end
|
|
@@ -100,7 +100,13 @@ module Decidim
|
|
|
100
100
|
def url
|
|
101
101
|
@url ||=
|
|
102
102
|
if file?
|
|
103
|
-
|
|
103
|
+
if private_download_required?
|
|
104
|
+
Decidim::Core::Engine.routes.url_helpers.private_download_path(
|
|
105
|
+
Decidim::PrivateDownload.for(self, attachment_name: :file).token
|
|
106
|
+
)
|
|
107
|
+
else
|
|
108
|
+
attached_uploader(:file).url
|
|
109
|
+
end
|
|
104
110
|
elsif link?
|
|
105
111
|
link
|
|
106
112
|
end
|
|
@@ -144,5 +150,17 @@ module Decidim
|
|
|
144
150
|
|
|
145
151
|
attached_to.can_participate?(user)
|
|
146
152
|
end
|
|
153
|
+
|
|
154
|
+
def private_download_authorized?(user, requested_attachment_name)
|
|
155
|
+
return false unless requested_attachment_name.to_s == "file"
|
|
156
|
+
|
|
157
|
+
can_participate?(user)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def private_download_required?
|
|
161
|
+
return attached_to.restricted? if attached_to.respond_to?(:restricted?)
|
|
162
|
+
|
|
163
|
+
attached_to.respond_to?(:component) && attached_to.component&.restricted_space?
|
|
164
|
+
end
|
|
147
165
|
end
|
|
148
166
|
end
|
|
@@ -91,6 +91,13 @@ module Decidim
|
|
|
91
91
|
Decidim::AuthorizationTransfer.perform!(self, handler)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def private_download_authorized?(user, requested_attachment_name)
|
|
95
|
+
return false unless requested_attachment_name.to_s == "verification_attachment"
|
|
96
|
+
return true if user&.admin? && user.organization == organization
|
|
97
|
+
|
|
98
|
+
user == self.user
|
|
99
|
+
end
|
|
100
|
+
|
|
94
101
|
private
|
|
95
102
|
|
|
96
103
|
def active_handler?
|
|
@@ -214,7 +214,7 @@ module Decidim
|
|
|
214
214
|
# }
|
|
215
215
|
# }
|
|
216
216
|
#
|
|
217
|
-
# @return [Hash
|
|
217
|
+
# @return [Hash{String => Hash{Symbol => Integer, ActiveModel::Name}}] The
|
|
218
218
|
# information hash created for the transfer.
|
|
219
219
|
def information
|
|
220
220
|
{}.tap do |types|
|
|
@@ -64,6 +64,7 @@ module Decidim
|
|
|
64
64
|
{
|
|
65
65
|
:host => organization.host,
|
|
66
66
|
:component_id => id,
|
|
67
|
+
:locale => I18n.locale,
|
|
67
68
|
:"#{participatory_space.underscored_name}_slug" => participatory_space.slug
|
|
68
69
|
}
|
|
69
70
|
end
|
|
@@ -102,22 +103,18 @@ module Decidim
|
|
|
102
103
|
def can_participate_in_space?(user)
|
|
103
104
|
return false unless published?
|
|
104
105
|
return false unless participatory_space.published?
|
|
105
|
-
|
|
106
|
+
|
|
107
|
+
return true unless participatory_space.respond_to?(:restricted?) && participatory_space.restricted?
|
|
106
108
|
return false unless user
|
|
107
109
|
|
|
108
110
|
participatory_space.can_participate?(user)
|
|
109
111
|
end
|
|
110
112
|
alias can_participate? can_participate_in_space?
|
|
111
113
|
|
|
112
|
-
def
|
|
113
|
-
return false unless participatory_space.respond_to?(:
|
|
114
|
-
return false unless participatory_space.private_space?
|
|
114
|
+
def restricted_space?
|
|
115
|
+
return false unless participatory_space.respond_to?(:restricted?)
|
|
115
116
|
|
|
116
|
-
|
|
117
|
-
!participatory_space.is_transparent?
|
|
118
|
-
else
|
|
119
|
-
true
|
|
120
|
-
end
|
|
117
|
+
participatory_space.restricted?
|
|
121
118
|
end
|
|
122
119
|
|
|
123
120
|
# Public: Public URL for component with given share token as query parameter
|
|
@@ -36,7 +36,7 @@ module Decidim
|
|
|
36
36
|
# Returns an object that responds to the settings defined in the content
|
|
37
37
|
# block manifest.
|
|
38
38
|
def settings
|
|
39
|
-
manifest.settings.schema.new(self[:settings])
|
|
39
|
+
manifest.settings.schema.new(self[:settings], organization&.default_locale)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def reload(*)
|
|
@@ -123,8 +123,8 @@ module Decidim
|
|
|
123
123
|
private
|
|
124
124
|
|
|
125
125
|
def manifest_attachments
|
|
126
|
-
@manifest_attachments ||= manifest.images.
|
|
127
|
-
|
|
126
|
+
@manifest_attachments ||= manifest.images.to_h do |attachment_config|
|
|
127
|
+
[attachment_config[:name], attachments.find_or_initialize_by(name: attachment_config[:name])]
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
130
|
|
|
@@ -32,7 +32,7 @@ module Decidim
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def self.ransackable_attributes(_auth_object = nil)
|
|
35
|
-
%w(reported_id_string reported_content created_at)
|
|
35
|
+
%w(reported_id_string reported_content created_at report_count)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def self.ransackable_associations(_auth_object = nil)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
module ParticipatorySpace
|
|
5
|
+
# This class gives a given User access to a given private Member
|
|
6
|
+
class Member < ApplicationRecord
|
|
7
|
+
include Decidim::DownloadYourData
|
|
8
|
+
include ParticipatorySpaceUser
|
|
9
|
+
include Decidim::TranslatableResource
|
|
10
|
+
|
|
11
|
+
belongs_to :participatory_space, polymorphic: true
|
|
12
|
+
|
|
13
|
+
translatable_fields :role
|
|
14
|
+
|
|
15
|
+
delegate :email, :name, to: :user
|
|
16
|
+
|
|
17
|
+
validates :user, uniqueness: { scope: [:participatory_space_id, :participatory_space_type] }
|
|
18
|
+
|
|
19
|
+
scope :by_participatory_space, ->(participatory_space) { where(participatory_space_id: participatory_space.id, participatory_space_type: participatory_space.class.to_s) }
|
|
20
|
+
scope :published, -> { where(published: true) }
|
|
21
|
+
|
|
22
|
+
def self.user_collection(user)
|
|
23
|
+
where(decidim_user_id: user.id)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.member_ids_for_participatory_spaces(spaces)
|
|
27
|
+
joins(:user).where(participatory_space: spaces).distinct.pluck(:decidim_user_id)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.export_serializer
|
|
31
|
+
Decidim::DownloadYourDataSerializers::DownloadYourDataMemberSerializer
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.log_presenter_class_for(_log)
|
|
35
|
+
Decidim::AdminLog::ParticipatorySpace::MemberPresenter
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
ransacker :invitation_sent_at do
|
|
39
|
+
Arel.sql(%{("invitation_sent_at")::text})
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.ransackable_attributes(auth_object = nil)
|
|
43
|
+
return [] unless auth_object&.admin?
|
|
44
|
+
|
|
45
|
+
%w(name nickname email invitation_accepted_at last_sign_in_at invitation_sent_at role published)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.ransackable_associations(_auth_object = nil)
|
|
49
|
+
%w(user)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def target_space_association = :participatory_space
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
class PrivateDownload
|
|
5
|
+
class InvalidTokenError < StandardError; end
|
|
6
|
+
|
|
7
|
+
VERIFIER_PURPOSE = :private_download
|
|
8
|
+
|
|
9
|
+
def self.for(record, attachment_name:)
|
|
10
|
+
new(record:, attachment_name:)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.from_token(token)
|
|
14
|
+
payload = verifier.verify(token, purpose: VERIFIER_PURPOSE).with_indifferent_access
|
|
15
|
+
record = GlobalID::Locator.locate(payload[:gid])
|
|
16
|
+
|
|
17
|
+
raise InvalidTokenError if record.blank?
|
|
18
|
+
|
|
19
|
+
new(record:, attachment_name: payload[:attachment_name])
|
|
20
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature, TypeError
|
|
21
|
+
raise InvalidTokenError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.verifier
|
|
25
|
+
@verifier ||= ActiveSupport::MessageVerifier.new(Rails.application.secret_key_base, serializer: JSON)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def initialize(record:, attachment_name:)
|
|
29
|
+
@record = record
|
|
30
|
+
@attachment_name = attachment_name.to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def token
|
|
34
|
+
self.class.verifier.generate(
|
|
35
|
+
{
|
|
36
|
+
gid: record.to_global_id.to_s,
|
|
37
|
+
attachment_name:
|
|
38
|
+
},
|
|
39
|
+
purpose: VERIFIER_PURPOSE
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def attachment
|
|
44
|
+
record.public_send(attachment_name)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def attached?
|
|
48
|
+
attachment.respond_to?(:attached?) && attachment.attached?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def authorized_for?(user)
|
|
52
|
+
return false unless record.respond_to?(:private_download_authorized?)
|
|
53
|
+
|
|
54
|
+
record.private_download_authorized?(user, attachment_name)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
attr_reader :record, :attachment_name
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -24,5 +24,11 @@ module Decidim
|
|
|
24
24
|
self.content_type = file.content_type
|
|
25
25
|
self.file_size = file.byte_size
|
|
26
26
|
end
|
|
27
|
+
|
|
28
|
+
def private_download_authorized?(user, requested_attachment_name)
|
|
29
|
+
return false unless requested_attachment_name.to_s == "file"
|
|
30
|
+
|
|
31
|
+
attached_to == user
|
|
32
|
+
end
|
|
27
33
|
end
|
|
28
34
|
end
|
|
@@ -7,7 +7,7 @@ module Decidim
|
|
|
7
7
|
# In order to group the relations between resources you need to specify a name.
|
|
8
8
|
#
|
|
9
9
|
# Some examples could be: proposals that have been created in a meeting or
|
|
10
|
-
#
|
|
10
|
+
# results that are the merge of different proposals.
|
|
11
11
|
class ResourceLink < ApplicationRecord
|
|
12
12
|
belongs_to :from, polymorphic: true
|
|
13
13
|
belongs_to :to, polymorphic: true
|
|
@@ -94,7 +94,7 @@ module Decidim
|
|
|
94
94
|
#
|
|
95
95
|
# @return [String] The target full URL that the short link should link to.
|
|
96
96
|
def target_url
|
|
97
|
-
url_helpers.send("#{route_name}_url",
|
|
97
|
+
url_helpers.send("#{route_name}_url", { locale: I18n.locale }.reverse_merge(params))
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
private
|
data/app/models/decidim/user.rb
CHANGED
|
@@ -21,8 +21,8 @@ module Decidim
|
|
|
21
21
|
|
|
22
22
|
devise :invitable, :database_authenticatable, :registerable, :confirmable, :timeoutable,
|
|
23
23
|
:recoverable, :trackable, :lockable,
|
|
24
|
-
:decidim_validatable, :decidim_newsletterable,
|
|
25
|
-
:omniauthable, omniauth_providers: Decidim::OmniauthProvider.available.keys,
|
|
24
|
+
:decidim_validatable, :decidim_newsletterable,
|
|
25
|
+
:omniauthable, omniauth_providers: Decidim::OmniauthProvider.available.keys,
|
|
26
26
|
request_keys: [:env], reset_password_keys: [:decidim_organization_id, :email],
|
|
27
27
|
confirmation_keys: [:decidim_organization_id, :email]
|
|
28
28
|
devise :rememberable if Decidim.enable_remember_me
|
|
@@ -69,12 +69,27 @@ module Decidim
|
|
|
69
69
|
Decidim::UserBaseEntity.joins(:follows).where(decidim_follows: { user: self }).blocked.exists?
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
ransacker :role do
|
|
73
|
+
Arel.sql(%{CASE WHEN "decidim_users"."admin" = true THEN 'admin' ELSE cast("decidim_users"."roles" as text) END})
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
ransacker :user_moderation_report_count do
|
|
77
|
+
query = <<~SQL.squish
|
|
78
|
+
(
|
|
79
|
+
SELECT COALESCE(MAX(decidim_user_moderations.report_count), 0)
|
|
80
|
+
FROM decidim_user_moderations
|
|
81
|
+
WHERE decidim_user_moderations.decidim_user_id = decidim_users.id
|
|
82
|
+
)
|
|
83
|
+
SQL
|
|
84
|
+
Arel.sql(query)
|
|
85
|
+
end
|
|
86
|
+
|
|
72
87
|
def self.ransackable_attributes(auth_object = nil)
|
|
73
|
-
base = %w(name email nickname last_sign_in_at)
|
|
88
|
+
base = %w(name email nickname last_sign_in_at created_at)
|
|
74
89
|
|
|
75
90
|
return base unless auth_object&.admin?
|
|
76
91
|
|
|
77
|
-
base + %w(invitation_sent_at invitation_accepted_at officialized_at)
|
|
92
|
+
base + %w(invitation_sent_at invitation_accepted_at officialized_at role user_moderation_report_count)
|
|
78
93
|
end
|
|
79
94
|
|
|
80
95
|
def self.ransackable_associations(_auth_object = nil)
|