decidim-core 0.32.0 → 0.32.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/cells/decidim/comments_button_cell.rb +9 -1
- data/app/cells/decidim/content_blocks/participatory_space_main_data/title.erb +1 -14
- data/app/cells/decidim/data_consent/category.erb +20 -33
- data/app/cells/decidim/following_cell.rb +1 -1
- data/app/cells/decidim/footer_topics/show.erb +5 -8
- data/app/cells/decidim/member/show.erb +1 -1
- data/app/cells/decidim/nav_links/show.erb +3 -1
- data/app/cells/decidim/share_text_widget/modal.erb +1 -0
- data/app/cells/decidim/share_widget/modal.erb +1 -0
- data/app/cells/decidim/share_widget/qr_code_modal.erb +2 -4
- data/app/commands/decidim/create_omniauth_registration.rb +17 -2
- data/app/controllers/concerns/decidim/devise_authentication_methods.rb +4 -0
- data/app/controllers/concerns/decidim/devise_controllers.rb +2 -0
- data/app/controllers/concerns/decidim/disable_redirection_to_external_host.rb +2 -0
- data/app/controllers/concerns/decidim/filter_resource.rb +2 -0
- data/app/controllers/concerns/decidim/impersonate_users.rb +2 -2
- data/app/controllers/concerns/decidim/locale_switcher.rb +12 -10
- data/app/controllers/concerns/decidim/needs_permission.rb +22 -10
- data/app/controllers/concerns/decidim/onboarding_action_methods.rb +2 -0
- data/app/controllers/concerns/decidim/paginable.rb +7 -3
- data/app/controllers/concerns/decidim/payload_info.rb +2 -0
- data/app/controllers/concerns/decidim/resource_versions_concern.rb +14 -0
- data/app/controllers/decidim/application_controller.rb +0 -6
- data/app/controllers/decidim/authorization_modals_controller.rb +2 -0
- data/app/controllers/decidim/components/base_controller.rb +2 -0
- data/app/controllers/decidim/devise/passwords_controller.rb +8 -0
- data/app/controllers/decidim/favicon_controller.rb +9 -0
- data/app/controllers/decidim/free_resource_authorization_modals_controller.rb +2 -0
- data/app/controllers/decidim/gamification/badges_controller.rb +2 -0
- data/app/controllers/decidim/homepage_controller.rb +4 -1
- data/app/controllers/decidim/likes_controller.rb +1 -1
- data/app/controllers/decidim/links_controller.rb +2 -0
- data/app/controllers/decidim/manifests_controller.rb +2 -0
- data/app/controllers/decidim/messaging/conversations_controller.rb +10 -4
- data/app/controllers/decidim/newsletters_controller.rb +4 -0
- data/app/controllers/decidim/notifications_subscriptions_controller.rb +4 -0
- data/app/controllers/decidim/offline_controller.rb +5 -1
- data/app/controllers/decidim/open_data_controller.rb +5 -1
- data/app/controllers/decidim/pages_controller.rb +31 -3
- data/app/controllers/decidim/private_downloads_controller.rb +2 -0
- data/app/controllers/decidim/profiles_controller.rb +19 -1
- data/app/controllers/decidim/qr_controller.rb +3 -1
- data/app/controllers/decidim/resource_autocomplete_controller.rb +2 -0
- data/app/controllers/decidim/searches_controller.rb +2 -0
- data/app/controllers/decidim/short_links_controller.rb +4 -0
- data/app/controllers/decidim/static_map_controller.rb +2 -0
- data/app/controllers/decidim/timeouts_controller.rb +4 -0
- data/app/controllers/decidim/tos_controller.rb +2 -0
- data/app/controllers/decidim/upload_validations_controller.rb +4 -2
- data/app/controllers/decidim/user_activities_controller.rb +3 -0
- data/app/forms/decidim/upload_validation_form.rb +16 -10
- data/app/helpers/concerns/decidim/user_role_checker.rb +35 -10
- data/app/helpers/decidim/decidim_form_helper.rb +1 -1
- data/app/helpers/decidim/menu_helper.rb +0 -2
- data/app/helpers/decidim/sanitize_helper.rb +11 -1
- data/app/jobs/decidim/application_job.rb +4 -0
- data/app/models/decidim/authorization.rb +24 -0
- data/app/models/decidim/oauth_application.rb +1 -0
- data/app/models/decidim/user.rb +3 -2
- data/app/models/decidim/user_base_entity.rb +1 -1
- data/app/packs/src/decidim/callout.js +10 -0
- data/app/packs/src/decidim/callout.test.js +32 -0
- data/app/packs/src/decidim/controllers/accordion/accordion.test.js +260 -42
- data/app/packs/src/decidim/controllers/accordion/controller.js +136 -17
- data/app/packs/src/decidim/controllers/autofocus/controller.js +30 -0
- data/app/packs/src/decidim/controllers/dropdown/controller.js +6 -0
- data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +28 -0
- data/app/packs/src/decidim/controllers/language_change/controller.js +21 -8
- data/app/packs/src/decidim/controllers/language_change/language_change.test.js +0 -1
- data/app/packs/src/decidim/controllers/main_menu/controller.js +4 -0
- data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +23 -0
- data/app/packs/src/decidim/controllers/mention/controller.js +32 -3
- data/app/packs/src/decidim/controllers/mention/input_mentions.test.js +8 -5
- data/app/packs/src/decidim/controllers/multiple_mentions/input_multiple_mentions.test.js +1 -1
- 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 +41 -25
- data/app/packs/src/decidim/datepicker/generate_datepicker.js +4 -4
- data/app/packs/src/decidim/datepicker/test/datepicker_functions_adjust_picker_position.test.js +64 -0
- data/app/packs/src/decidim/datepicker/test/time.test.js +39 -24
- data/app/packs/src/decidim/direct_uploads/upload_modal.js +2 -1
- data/app/packs/src/decidim/editor/common/suggestion.js +32 -22
- data/app/packs/src/decidim/editor/extensions/mention/index.js +14 -3
- data/app/packs/src/decidim/editor/index.js +4 -0
- data/app/packs/src/decidim/editor/test/extensions/mention.test.js +32 -9
- data/app/packs/src/decidim/map/controller.js +10 -1
- data/app/packs/src/decidim/refactor/implementation/autofocus.js +22 -0
- data/app/packs/src/decidim/refactor/implementation/autofocus.test.js +171 -0
- data/app/packs/src/decidim/refactor/moved/focus_guard.js +12 -12
- data/app/packs/src/decidim/refactor/moved/focus_guard.test.js +136 -0
- data/app/packs/src/decidim/utilities/dom.js +2 -2
- data/app/packs/stylesheets/decidim/_cards.scss +1 -1
- data/app/packs/stylesheets/decidim/_content_blocks.scss +4 -10
- data/app/packs/stylesheets/decidim/_conversations.scss +0 -8
- data/app/packs/stylesheets/decidim/_cookies.scss +13 -5
- data/app/packs/stylesheets/decidim/_documents.scss +1 -1
- data/app/packs/stylesheets/decidim/_footer.scss +33 -1
- data/app/packs/stylesheets/decidim/_modal.scss +16 -8
- data/app/packs/stylesheets/decidim/_modal_share.scss +0 -22
- data/app/packs/stylesheets/decidim/_participatory_spaces.scss +12 -2
- data/app/packs/stylesheets/decidim/_rich_text.scss +12 -9
- data/app/packs/stylesheets/decidim/_typography.scss +5 -2
- data/app/packs/stylesheets/decidim/application.scss +1 -0
- data/app/packs/stylesheets/decidim/legacy/email.scss +0 -5
- data/app/permissions/decidim/permissions.rb +20 -0
- data/app/presenters/decidim/admin_log/component_presenter.rb +1 -1
- data/app/presenters/decidim/footer_menu_presenter.rb +2 -4
- data/app/presenters/decidim/log/base_presenter.rb +10 -1
- data/app/presenters/decidim/log/user_presenter.rb +2 -2
- data/app/presenters/decidim/menu_item_presenter.rb +1 -5
- data/app/presenters/decidim/resource_presenter.rb +11 -0
- data/app/resolvers/decidim/meta_image_url_resolver.rb +14 -1
- data/app/serializers/decidim/exporters/open_data_blocked_user_serializer.rb +11 -2
- data/app/serializers/decidim/exporters/open_data_moderation_serializer.rb +25 -1
- data/app/services/decidim/svg_content_validator.rb +554 -0
- data/app/uploaders/decidim/application_uploader.rb +2 -2
- data/app/validators/uploader_image_content_validator.rb +276 -0
- data/app/views/decidim/application/_radio_accordion.html.erb +1 -5
- data/app/views/decidim/messaging/conversations/_add_conversation_users.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/create.js.erb +1 -3
- data/app/views/decidim/searches/_filters.html.erb +1 -1
- data/app/views/decidim/shared/_login_modal.html.erb +12 -14
- data/app/views/layouts/decidim/_mailer_logo.html.erb +1 -1
- data/app/views/layouts/decidim/footer/_main.html.erb +1 -1
- data/app/views/layouts/decidim/footer/_main_links.html.erb +56 -28
- data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +3 -2
- data/config/initializers/rack_attack.rb +10 -0
- data/config/locales/bg.yml +0 -1
- data/config/locales/ca-IT.yml +9 -1
- data/config/locales/ca.yml +16 -6
- data/config/locales/cs.yml +31 -1
- data/config/locales/de.yml +99 -3
- data/config/locales/en.yml +11 -1
- data/config/locales/es-MX.yml +11 -1
- data/config/locales/es-PY.yml +11 -1
- data/config/locales/es.yml +15 -5
- data/config/locales/eu.yml +166 -161
- data/config/locales/fi-plain.yml +9 -1
- data/config/locales/fi.yml +9 -1
- data/config/locales/fr-CA.yml +12 -1
- data/config/locales/fr.yml +12 -1
- data/config/locales/gl.yml +1485 -33
- data/config/locales/hu.yml +0 -1
- data/config/locales/ja.yml +28 -1
- data/config/locales/pl.yml +2 -1
- data/config/locales/pt-BR.yml +0 -1
- data/config/locales/ro-RO.yml +0 -1
- data/config/locales/sk.yml +2 -1
- data/config/locales/sv.yml +68 -12
- data/config/locales/tr-TR.yml +0 -2
- data/config/routes.rb +11 -2
- data/db/migrate/20250217192438_convert_user_groups_into_users.rb +3 -2
- data/db/migrate/20260909000000_add_failed_attempts_and_locked_at_to_decidim_authorizations.rb +8 -0
- data/decidim-core.gemspec +4 -1
- data/lib/decidim/api/functions/user_entity_list.rb +1 -0
- data/lib/decidim/api/types/user_moderation_type.rb +2 -2
- data/lib/decidim/content_parsers/user_parser.rb +1 -1
- data/lib/decidim/content_parsers.rb +0 -1
- data/lib/decidim/content_renderers/mention_resource_renderer.rb +18 -4
- data/lib/decidim/content_renderers/user_renderer.rb +15 -4
- data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +8 -5
- data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +14 -11
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +26 -0
- data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +77 -0
- data/lib/decidim/core/test/shared_examples/participatory_space_members_shared_examples.rb +58 -0
- data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +23 -1
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/core.rb +10 -1
- data/lib/decidim/form_builder.rb +9 -1
- data/lib/decidim/has_upload_validations.rb +1 -0
- data/lib/decidim/legacy_form_builder.rb +4 -0
- data/lib/decidim/map/dynamic_map.rb +3 -1
- metadata +33 -7
- data/lib/decidim/content_parsers/inline_images_parser.rb +0 -68
- data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +0 -79
|
@@ -173,6 +173,16 @@ shared_examples "comments" do
|
|
|
173
173
|
expect(page).to have_css(".comment-thread")
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
+
it "opens the login modal when clicking the comment button" do
|
|
177
|
+
visit resource_path
|
|
178
|
+
|
|
179
|
+
expect(page).to have_no_css("#loginModal-content", visible: :visible)
|
|
180
|
+
|
|
181
|
+
find(".add-comment-mobile").click
|
|
182
|
+
|
|
183
|
+
expect(page).to have_css("#loginModal-content", visible: :visible)
|
|
184
|
+
end
|
|
185
|
+
|
|
176
186
|
context "when user visit a mobile browser" do
|
|
177
187
|
before do
|
|
178
188
|
driven_by(:iphone)
|
|
@@ -202,6 +212,22 @@ shared_examples "comments" do
|
|
|
202
212
|
expect(page).to have_css(".add-comment form")
|
|
203
213
|
end
|
|
204
214
|
|
|
215
|
+
it "does not show login modal when clicking the comment button" do
|
|
216
|
+
visit resource_path
|
|
217
|
+
|
|
218
|
+
find("a.add-comment-mobile").click
|
|
219
|
+
|
|
220
|
+
expect(page).to have_no_css("#loginModal-content", visible: :visible)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "guides the user to the comment form when clicking the comment button" do
|
|
224
|
+
visit resource_path
|
|
225
|
+
|
|
226
|
+
find("a.add-comment-mobile").click
|
|
227
|
+
|
|
228
|
+
expect(page).to have_css("#add-comment-anchor")
|
|
229
|
+
end
|
|
230
|
+
|
|
205
231
|
context "when user visit a computer browser" do
|
|
206
232
|
before do
|
|
207
233
|
switch_to_host(organization.host)
|
|
@@ -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: participatory_space.organization) }
|
|
48
|
+
let!(:members) do
|
|
49
|
+
users.map do |user|
|
|
50
|
+
create(:member, participatory_space:, 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
|
|
@@ -117,5 +117,63 @@ shared_examples "participatory space members" do
|
|
|
117
117
|
expect(page).to have_content("Profile")
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
|
+
|
|
121
|
+
context "when there are more members than the pagination per_page limit" do
|
|
122
|
+
let(:per_page) { Decidim::Paginable::OPTIONS.first }
|
|
123
|
+
let(:users) { create_list(:user, per_page + 5, organization: participatory_space.organization) }
|
|
124
|
+
let!(:extra_members) do
|
|
125
|
+
users.map do |user|
|
|
126
|
+
create(:member, participatory_space:, user:, published: true)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
before do
|
|
131
|
+
visit members_path
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "paginates the members list" do
|
|
135
|
+
within ".layout-main__section" do
|
|
136
|
+
expect(page).to have_css(".profile__user", count: per_page)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "shows pagination controls" do
|
|
141
|
+
within("div[data-pagination]") do
|
|
142
|
+
expect(page).to have_css('nav[aria-label="Pagination"]')
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "navigates to the next page" do
|
|
147
|
+
within "nav[aria-label=\"Pagination\"]" do
|
|
148
|
+
click_on "Next"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
within ".layout-main__section" do
|
|
152
|
+
expect(page).to have_css(".profile__user", count: 6)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "maintains pagination when navigating back" do
|
|
157
|
+
within "nav[aria-label=\"Pagination\"]" do
|
|
158
|
+
click_on "Next"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
within "nav[aria-label=\"Pagination\"]" do
|
|
162
|
+
click_on "Prev"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
within ".layout-main__section" do
|
|
166
|
+
expect(page).to have_css(".profile__user", count: per_page)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "shows the correct page number in the URL" do
|
|
171
|
+
within "nav[aria-label=\"Pagination\"]" do
|
|
172
|
+
click_on "Next"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
expect(page).to have_current_path(/page=2/)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
120
178
|
end
|
|
121
179
|
end
|
|
@@ -28,7 +28,7 @@ shared_examples "a version of a hidden object" do
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
|
|
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, :locale => I18n.locale }
|
|
@@ -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
|
data/lib/decidim/core/version.rb
CHANGED
data/lib/decidim/core.rb
CHANGED
|
@@ -288,7 +288,7 @@ module Decidim
|
|
|
288
288
|
mattr_accessor :default_locale, default: (Decidim::Env.new("DECIDIM_DEFAULT_LOCALE", "en").presence || :en).to_s
|
|
289
289
|
|
|
290
290
|
# Users that have not logged in for this period of time will be deleted
|
|
291
|
-
mattr_accessor :delete_inactive_users_after_days, default: Decidim::Env.new("
|
|
291
|
+
mattr_accessor :delete_inactive_users_after_days, default: Decidim::Env.new("DECIDIM_DELETE_INACTIVE_USERS_AFTER_DAYS", 365).to_i
|
|
292
292
|
|
|
293
293
|
# The minimum allowed inactivity period for deleting participants.
|
|
294
294
|
mattr_accessor :minimum_inactivity_period, default: Decidim::Env.new("DECIDIM_MINIMUM_INACTIVITY_PERIOD_IN_DAYS", 30).to_i
|
|
@@ -447,6 +447,15 @@ module Decidim
|
|
|
447
447
|
# Time window in which the throttling is applied.
|
|
448
448
|
mattr_accessor :throttling_period, default: Decidim::Env.new("DECIDIM_THROTTLING_PERIOD", "1").to_i.minutes
|
|
449
449
|
|
|
450
|
+
# Max failed attempts for verification code confirmation before lockout.
|
|
451
|
+
mattr_accessor :verification_max_failed_attempts, default: Decidim::Env.new("DECIDIM_VERIFICATION_MAX_FAILED_ATTEMPTS", "5").to_i
|
|
452
|
+
|
|
453
|
+
# Time window after which a locked verification is automatically unlocked.
|
|
454
|
+
mattr_accessor :verification_unlock_in, default: Decidim::Env.new("DECIDIM_VERIFICATION_UNLOCK_IN", "30").to_i.minutes
|
|
455
|
+
|
|
456
|
+
# Time window (in minutes) after which a verification code expires (SMS only).
|
|
457
|
+
mattr_accessor :verification_code_expiry_minutes, default: Decidim::Env.new("DECIDIM_VERIFICATION_CODE_EXPIRY_MINUTES", "10").to_i
|
|
458
|
+
|
|
450
459
|
# Time window were users can access the website even if their email is not confirmed.
|
|
451
460
|
mattr_accessor :unconfirmed_access_for, default: Decidim::Env.new("DECIDIM_UNCONFIRMED_ACCESS_FOR", "0").to_i.days
|
|
452
461
|
|
data/lib/decidim/form_builder.rb
CHANGED
|
@@ -886,12 +886,20 @@ module Decidim
|
|
|
886
886
|
upload_dialog_selector: "##{upload_options[:modal_id]}"
|
|
887
887
|
}.transform_keys { |key| key.to_s.camelize(:lower) }
|
|
888
888
|
|
|
889
|
-
|
|
889
|
+
mentionable = options.delete(:mentionable)
|
|
890
|
+
editor_options[:mention] = mention_options(mentionable) if mentionable
|
|
890
891
|
editor_options[:emoji] = options.delete(:emojiable)
|
|
891
892
|
|
|
892
893
|
{ editor: editor_options, upload: upload_options }
|
|
893
894
|
end
|
|
894
895
|
|
|
896
|
+
def mention_options(mentionable)
|
|
897
|
+
mention_options = mentionable.is_a?(Hash) ? mentionable.dup : {}
|
|
898
|
+
mention_options[:searchPromptMessage] ||= I18n.t("decidim.shared.mentions.search_prompt")
|
|
899
|
+
|
|
900
|
+
mention_options
|
|
901
|
+
end
|
|
902
|
+
|
|
895
903
|
# Private: creates an upload modal for the editor that we use to dynamically
|
|
896
904
|
# upload the images to the editor.
|
|
897
905
|
def editor_upload(editor_image, options = {})
|
|
@@ -32,6 +32,10 @@ module Decidim
|
|
|
32
32
|
options[:data][:controller] ||= ""
|
|
33
33
|
options[:data][:controller] += " date-picker"
|
|
34
34
|
|
|
35
|
+
if (default_time = options.delete(:default_time))
|
|
36
|
+
options[:data][:default_time] = default_time
|
|
37
|
+
end
|
|
38
|
+
|
|
35
39
|
field(attribute, options) do |opts|
|
|
36
40
|
super(attribute, opts)
|
|
37
41
|
end
|
|
@@ -30,7 +30,9 @@ module Decidim
|
|
|
30
30
|
def builder_options
|
|
31
31
|
{
|
|
32
32
|
marker_color: organization.colors.fetch("primary", "#e02d2d"),
|
|
33
|
-
tile_layer: tile_layer_configuration
|
|
33
|
+
tile_layer: tile_layer_configuration,
|
|
34
|
+
zoom_in_text: I18n.t("zoom_in", scope: "decidim.map.dynamic"),
|
|
35
|
+
zoom_out_text: I18n.t("zoom_out", scope: "decidim.map.dynamic")
|
|
34
36
|
}
|
|
35
37
|
end
|
|
36
38
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: decidim-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.32.
|
|
4
|
+
version: 0.32.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Josep Jaume Rey Peroy
|
|
@@ -681,6 +681,26 @@ dependencies:
|
|
|
681
681
|
- - "<"
|
|
682
682
|
- !ruby/object:Gem::Version
|
|
683
683
|
version: '6.9'
|
|
684
|
+
- !ruby/object:Gem::Dependency
|
|
685
|
+
name: rack-proxy
|
|
686
|
+
requirement: !ruby/object:Gem::Requirement
|
|
687
|
+
requirements:
|
|
688
|
+
- - "~>"
|
|
689
|
+
- !ruby/object:Gem::Version
|
|
690
|
+
version: 0.8.3
|
|
691
|
+
- - "<"
|
|
692
|
+
- !ruby/object:Gem::Version
|
|
693
|
+
version: '1.0'
|
|
694
|
+
type: :runtime
|
|
695
|
+
prerelease: false
|
|
696
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
697
|
+
requirements:
|
|
698
|
+
- - "~>"
|
|
699
|
+
- !ruby/object:Gem::Version
|
|
700
|
+
version: 0.8.3
|
|
701
|
+
- - "<"
|
|
702
|
+
- !ruby/object:Gem::Version
|
|
703
|
+
version: '1.0'
|
|
684
704
|
- !ruby/object:Gem::Dependency
|
|
685
705
|
name: rails
|
|
686
706
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -893,28 +913,28 @@ dependencies:
|
|
|
893
913
|
requirements:
|
|
894
914
|
- - '='
|
|
895
915
|
- !ruby/object:Gem::Version
|
|
896
|
-
version: 0.32.
|
|
916
|
+
version: 0.32.2
|
|
897
917
|
type: :development
|
|
898
918
|
prerelease: false
|
|
899
919
|
version_requirements: !ruby/object:Gem::Requirement
|
|
900
920
|
requirements:
|
|
901
921
|
- - '='
|
|
902
922
|
- !ruby/object:Gem::Version
|
|
903
|
-
version: 0.32.
|
|
923
|
+
version: 0.32.2
|
|
904
924
|
- !ruby/object:Gem::Dependency
|
|
905
925
|
name: decidim-dev
|
|
906
926
|
requirement: !ruby/object:Gem::Requirement
|
|
907
927
|
requirements:
|
|
908
928
|
- - '='
|
|
909
929
|
- !ruby/object:Gem::Version
|
|
910
|
-
version: 0.32.
|
|
930
|
+
version: 0.32.2
|
|
911
931
|
type: :development
|
|
912
932
|
prerelease: false
|
|
913
933
|
version_requirements: !ruby/object:Gem::Requirement
|
|
914
934
|
requirements:
|
|
915
935
|
- - '='
|
|
916
936
|
- !ruby/object:Gem::Version
|
|
917
|
-
version: 0.32.
|
|
937
|
+
version: 0.32.2
|
|
918
938
|
description: Adds core features so other engines can hook into the framework.
|
|
919
939
|
email:
|
|
920
940
|
- josepjaume@gmail.com
|
|
@@ -1637,6 +1657,7 @@ files:
|
|
|
1637
1657
|
- app/packs/src/decidim/attachments/file_or_link_tabs.js
|
|
1638
1658
|
- app/packs/src/decidim/attachments/index.js
|
|
1639
1659
|
- app/packs/src/decidim/callout.js
|
|
1660
|
+
- app/packs/src/decidim/callout.test.js
|
|
1640
1661
|
- app/packs/src/decidim/confirm.js
|
|
1641
1662
|
- app/packs/src/decidim/confirm.test.js
|
|
1642
1663
|
- app/packs/src/decidim/controllers/.keep
|
|
@@ -1646,6 +1667,7 @@ files:
|
|
|
1646
1667
|
- app/packs/src/decidim/controllers/account_form/controller.js
|
|
1647
1668
|
- app/packs/src/decidim/controllers/assign_role/assign_role.test.js
|
|
1648
1669
|
- app/packs/src/decidim/controllers/assign_role/controller.js
|
|
1670
|
+
- app/packs/src/decidim/controllers/autofocus/controller.js
|
|
1649
1671
|
- app/packs/src/decidim/controllers/breadcrumb_truncate/breadcrumb_truncate.test.js
|
|
1650
1672
|
- app/packs/src/decidim/controllers/breadcrumb_truncate/controller.js
|
|
1651
1673
|
- app/packs/src/decidim/controllers/character_counter/controller.js
|
|
@@ -1788,6 +1810,8 @@ files:
|
|
|
1788
1810
|
- app/packs/src/decidim/map/provider/default.js
|
|
1789
1811
|
- app/packs/src/decidim/map/provider/here.js
|
|
1790
1812
|
- app/packs/src/decidim/notifications.js
|
|
1813
|
+
- app/packs/src/decidim/refactor/implementation/autofocus.js
|
|
1814
|
+
- app/packs/src/decidim/refactor/implementation/autofocus.test.js
|
|
1791
1815
|
- app/packs/src/decidim/refactor/implementation/configuration.js
|
|
1792
1816
|
- app/packs/src/decidim/refactor/implementation/external_domain_warning.js
|
|
1793
1817
|
- app/packs/src/decidim/refactor/implementation/external_link.js
|
|
@@ -1796,6 +1820,7 @@ files:
|
|
|
1796
1820
|
- app/packs/src/decidim/refactor/moved/check_boxes_tree.js
|
|
1797
1821
|
- app/packs/src/decidim/refactor/moved/delayed.js
|
|
1798
1822
|
- app/packs/src/decidim/refactor/moved/focus_guard.js
|
|
1823
|
+
- app/packs/src/decidim/refactor/moved/focus_guard.test.js
|
|
1799
1824
|
- app/packs/src/decidim/refactor/moved/history.js
|
|
1800
1825
|
- app/packs/src/decidim/refactor/moved/i18n.js
|
|
1801
1826
|
- app/packs/src/decidim/refactor/moved/i18n.test.js
|
|
@@ -2014,6 +2039,7 @@ files:
|
|
|
2014
2039
|
- app/services/decidim/send_push_notification.rb
|
|
2015
2040
|
- app/services/decidim/settings_change.rb
|
|
2016
2041
|
- app/services/decidim/static_map_generator.rb
|
|
2042
|
+
- app/services/decidim/svg_content_validator.rb
|
|
2017
2043
|
- app/services/decidim/tokenizer.rb
|
|
2018
2044
|
- app/services/decidim/traceability.rb
|
|
2019
2045
|
- app/uploaders/decidim/application_uploader.rb
|
|
@@ -2041,6 +2067,7 @@ files:
|
|
|
2041
2067
|
- app/validators/translatable_presence_validator.rb
|
|
2042
2068
|
- app/validators/translated_etiquette_validator.rb
|
|
2043
2069
|
- app/validators/uploader_content_type_validator.rb
|
|
2070
|
+
- app/validators/uploader_image_content_validator.rb
|
|
2044
2071
|
- app/validators/uploader_image_dimensions_validator.rb
|
|
2045
2072
|
- app/validators/url_validator.rb
|
|
2046
2073
|
- app/views/decidim/account/_account_notification.js.erb
|
|
@@ -2589,6 +2616,7 @@ files:
|
|
|
2589
2616
|
- db/migrate/20260208201407_remove_user_group_organizations.rb
|
|
2590
2617
|
- db/migrate/20260217152425_remove_enable_participatory_space_filters_from_decidim_organizations.rb
|
|
2591
2618
|
- db/migrate/20260314081619_add_index_on_decidim_members.rb
|
|
2619
|
+
- db/migrate/20260909000000_add_failed_attempts_and_locked_at_to_decidim_authorizations.rb
|
|
2592
2620
|
- db/seeds.rb
|
|
2593
2621
|
- db/seeds/Exampledocument.pdf
|
|
2594
2622
|
- db/seeds/avatars/001.jpg
|
|
@@ -2838,7 +2866,6 @@ files:
|
|
|
2838
2866
|
- lib/decidim/content_parsers.rb
|
|
2839
2867
|
- lib/decidim/content_parsers/base_parser.rb
|
|
2840
2868
|
- lib/decidim/content_parsers/blob_parser.rb
|
|
2841
|
-
- lib/decidim/content_parsers/inline_images_parser.rb
|
|
2842
2869
|
- lib/decidim/content_parsers/link_parser.rb
|
|
2843
2870
|
- lib/decidim/content_parsers/mention_resource_parser.rb
|
|
2844
2871
|
- lib/decidim/content_parsers/newline_parser.rb
|
|
@@ -3158,7 +3185,6 @@ files:
|
|
|
3158
3185
|
- lib/tasks/decidim_taxonomies.rake
|
|
3159
3186
|
- lib/tasks/upgrade/clean.rake
|
|
3160
3187
|
- lib/tasks/upgrade/decidim_action_log_valuation_assignment.rake
|
|
3161
|
-
- lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake
|
|
3162
3188
|
- lib/tasks/upgrade/decidim_attachments.rake
|
|
3163
3189
|
- lib/tasks/upgrade/decidim_change_valuator_tasks.rake
|
|
3164
3190
|
- lib/tasks/upgrade/decidim_content_blocks_tasks.rake
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Decidim
|
|
4
|
-
module ContentParsers
|
|
5
|
-
# A parser that searches for inline images in an html content and
|
|
6
|
-
# replaces them with EditorImage attachments. Note that rewrite method may
|
|
7
|
-
# create EditorImage instances
|
|
8
|
-
#
|
|
9
|
-
# @see BaseParser Examples of how to use a content parser
|
|
10
|
-
class InlineImagesParser < BaseParser
|
|
11
|
-
# @return [String] the content with the inline images replaced.
|
|
12
|
-
def rewrite
|
|
13
|
-
return content unless inline_images?
|
|
14
|
-
|
|
15
|
-
replace_inline_images
|
|
16
|
-
parsed_content.to_html
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def inline_images?
|
|
20
|
-
parsed_content.search(:img).find do |image|
|
|
21
|
-
image.attr(:src).start_with?(%r{data:image/[a-z]{3,4};base64,})
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def parsed_content
|
|
28
|
-
@parsed_content ||= Nokogiri::HTML(content)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def replace_inline_images
|
|
32
|
-
parsed_content.search(:img).each do |image|
|
|
33
|
-
next unless image.attr(:src).start_with?(%r{data:image/[a-z]{3,4};base64,})
|
|
34
|
-
|
|
35
|
-
file = base64_tempfile(image.attr(:src))
|
|
36
|
-
editor_image = EditorImage.create!(
|
|
37
|
-
decidim_author_id: context[:user]&.id,
|
|
38
|
-
organization: context[:user].organization,
|
|
39
|
-
file:
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
image.set_attribute(:src, editor_image.attached_uploader(:file).path)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def base64_tempfile(base64_data, filename = nil)
|
|
47
|
-
return base64_data unless base64_data.is_a? String
|
|
48
|
-
|
|
49
|
-
start_regex = %r{data:image/[a-z]{3,4};base64,}
|
|
50
|
-
filename ||= SecureRandom.hex
|
|
51
|
-
|
|
52
|
-
regex_result = start_regex.match(base64_data)
|
|
53
|
-
|
|
54
|
-
return unless base64_data && regex_result
|
|
55
|
-
|
|
56
|
-
start = regex_result.to_s
|
|
57
|
-
tempfile = Tempfile.new(filename)
|
|
58
|
-
tempfile.binmode
|
|
59
|
-
tempfile.write(Base64.decode64(base64_data[start.length..-1]))
|
|
60
|
-
ActionDispatch::Http::UploadedFile.new(
|
|
61
|
-
tempfile:,
|
|
62
|
-
filename:,
|
|
63
|
-
original_filename: filename
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
namespace :decidim do
|
|
4
|
-
namespace :upgrade do
|
|
5
|
-
namespace :active_storage_migrations do
|
|
6
|
-
desc "Migrates inline images to ActiveStorage editor_image attachments"
|
|
7
|
-
task :migrate_inline_images_to_active_storage, [:admin_email] => :environment do |_t, args|
|
|
8
|
-
user = Decidim::User.find_by(email: args[:admin_email])
|
|
9
|
-
|
|
10
|
-
raise "Invalid admin. Please, provide the email of an admin with permissions to create editor images" unless user&.admin? && user.admin_terms_accepted?
|
|
11
|
-
|
|
12
|
-
inline_images_available_attributes.each do |model, attributes|
|
|
13
|
-
puts "=== Updating model #{model.name} (attributes: #{attributes.join(", ")})..."
|
|
14
|
-
model.all.each do |item|
|
|
15
|
-
attributes.each do |attribute|
|
|
16
|
-
item.update(attribute => rewrite_value(item.send(attribute), user))
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
puts "=== Finished update of model #{model.name}\n\n"
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def rewrite_value(value, user)
|
|
24
|
-
if value.is_a?(Hash)
|
|
25
|
-
value.transform_values do |nested_value|
|
|
26
|
-
rewrite_value(nested_value, user)
|
|
27
|
-
end
|
|
28
|
-
else
|
|
29
|
-
parser = Decidim::ContentParsers::InlineImagesParser.new(value, user:)
|
|
30
|
-
parser.rewrite
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def inline_images_available_attributes
|
|
35
|
-
{
|
|
36
|
-
"Decidim::Accountability::Result" => %w(description),
|
|
37
|
-
"Decidim::Proposals::Proposal" => %w(body answer cost_report execution_period),
|
|
38
|
-
"Decidim::Votings::Voting" => %w(description),
|
|
39
|
-
"Decidim::Elections::Question" => %w(description),
|
|
40
|
-
"Decidim::Elections::Answer" => %w(description),
|
|
41
|
-
"Decidim::Elections::Election" => %w(description),
|
|
42
|
-
"Decidim::Initiative" => %w(description answer),
|
|
43
|
-
"Decidim::InitiativesType" => %w(description extra_fields_legal_information),
|
|
44
|
-
"Decidim::Assembly" => %w(short_description description purpose_of_action composition internal_organisation announcement closing_date_reason special_features),
|
|
45
|
-
"Decidim::Forms::Questionnaire" => %w(description tos),
|
|
46
|
-
"Decidim::Forms::Question" => %w(description),
|
|
47
|
-
"Decidim::Organization" => %w(
|
|
48
|
-
welcome_notification_body
|
|
49
|
-
admin_terms_of_use_body
|
|
50
|
-
admin_terms_of_service_body
|
|
51
|
-
description
|
|
52
|
-
highlighted_content_banner_short_description
|
|
53
|
-
id_documents_explanation_text
|
|
54
|
-
),
|
|
55
|
-
"Decidim::StaticPage" => %w(content),
|
|
56
|
-
"Decidim::ContextualHelpSection" => %w(content),
|
|
57
|
-
"Decidim::Category" => %w(description),
|
|
58
|
-
"Decidim::Blogs::Post" => %w(body),
|
|
59
|
-
"Decidim::Pages::Page" => %w(body),
|
|
60
|
-
"Decidim::Debates::Debate" => %w(description instructions information_updates conclusions),
|
|
61
|
-
"Decidim::Budgets::Budget" => %w(description),
|
|
62
|
-
"Decidim::Budgets::Project" => %w(description),
|
|
63
|
-
"Decidim::ConferenceSpeaker" => %w(short_bio),
|
|
64
|
-
"Decidim::Conferences::RegistrationType" => %w(description),
|
|
65
|
-
"Decidim::Conference" => %w(short_description description objectives registration_terms),
|
|
66
|
-
"Decidim::ParticipatoryProcessGroup" => %w(description),
|
|
67
|
-
"Decidim::ParticipatoryProcess" => %w(short_description description announcement),
|
|
68
|
-
"Decidim::ParticipatoryProcessStep" => %w(description),
|
|
69
|
-
"Decidim::Meetings::AgendaItem" => %w(description),
|
|
70
|
-
"Decidim::Meetings::Meeting" => %w(registration_terms description registration_email_custom_content closing_report)
|
|
71
|
-
}.each_with_object({}) do |(main_model, attributes), hash|
|
|
72
|
-
hash[main_model.constantize] = attributes
|
|
73
|
-
rescue NameError
|
|
74
|
-
hash
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|