decidim-initiatives 0.30.2 → 0.31.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -9
  3. data/app/cells/decidim/initiatives/content_blocks/highlighted_initiatives_settings_form/show.erb +7 -2
  4. data/app/cells/decidim/initiatives/initiative_g_cell.rb +5 -1
  5. data/app/commands/decidim/initiatives/admin/publish_initiative.rb +1 -5
  6. data/app/commands/decidim/initiatives/admin/update_initiative.rb +1 -2
  7. data/app/commands/decidim/initiatives/create_initiative.rb +0 -1
  8. data/app/commands/decidim/initiatives/update_initiative.rb +1 -3
  9. data/app/commands/decidim/initiatives/vote_initiative.rb +1 -11
  10. data/app/controllers/concerns/decidim/initiatives/has_signature_workflow.rb +36 -0
  11. data/app/controllers/concerns/decidim/initiatives/needs_initiative.rb +1 -12
  12. data/app/controllers/decidim/initiatives/admin/initiatives_controller.rb +2 -2
  13. data/app/controllers/decidim/initiatives/admin/initiatives_settings_controller.rb +1 -1
  14. data/app/controllers/decidim/initiatives/admin/initiatives_type_scopes_controller.rb +2 -2
  15. data/app/controllers/decidim/initiatives/admin/initiatives_types_controller.rb +2 -2
  16. data/app/controllers/decidim/initiatives/committee_requests_controller.rb +10 -2
  17. data/app/controllers/decidim/initiatives/create_initiative_controller.rb +84 -18
  18. data/app/controllers/decidim/initiatives/initiative_signatures_controller.rb +133 -42
  19. data/app/controllers/decidim/initiatives/initiative_votes_controller.rb +3 -2
  20. data/app/controllers/decidim/initiatives/initiatives_controller.rb +21 -2
  21. data/app/forms/decidim/initiatives/admin/initiative_form.rb +0 -1
  22. data/app/forms/decidim/initiatives/initiative_form.rb +0 -3
  23. data/app/helpers/decidim/initiatives/application_helper.rb +2 -0
  24. data/app/helpers/decidim/initiatives/initiatives_helper.rb +0 -1
  25. data/app/models/decidim/initiative.rb +7 -31
  26. data/app/models/decidim/initiatives_committee_member.rb +1 -1
  27. data/app/models/decidim/initiatives_type.rb +5 -2
  28. data/app/models/decidim/initiatives_vote.rb +2 -2
  29. data/app/packs/entrypoints/decidim_initiatives.js +1 -1
  30. data/app/packs/entrypoints/decidim_initiatives_admin.scss +1 -1
  31. data/app/packs/src/decidim/initiatives/admin/initiatives_types.js +2 -11
  32. data/app/packs/src/decidim/initiatives/admin/invite_users.js +1 -1
  33. data/app/packs/src/decidim/initiatives/application.js +1 -1
  34. data/app/packs/src/decidim/initiatives/check_code.js +114 -0
  35. data/app/packs/src/decidim/initiatives/initiative_creation_wizard.js +16 -0
  36. data/app/packs/src/decidim/initiatives/scoped_type.js +1 -1
  37. data/app/packs/stylesheets/initiatives.scss +16 -2
  38. data/app/permissions/decidim/initiatives/admin/permissions.rb +1 -4
  39. data/app/permissions/decidim/initiatives/permissions.rb +26 -16
  40. data/app/presenters/decidim/initiative_presenter.rb +12 -6
  41. data/app/presenters/decidim/initiatives/admin_log/initiative_presenter.rb +1 -2
  42. data/app/queries/decidim/initiatives/initiatives_stats_followers_count.rb +14 -0
  43. data/app/queries/decidim/initiatives/initiatives_stats_participants_count.rb +14 -0
  44. data/app/serializers/decidim/initiatives/open_data_initiative_serializer.rb +0 -1
  45. data/app/services/decidim/initiatives/data_encryptor.rb +1 -1
  46. data/app/services/decidim/initiatives/legacy_signature_handler.rb +25 -0
  47. data/app/services/decidim/initiatives/progress_notifier.rb +1 -7
  48. data/app/services/decidim/initiatives/signature_handler.rb +248 -0
  49. data/app/services/decidim/initiatives/status_change_notifier.rb +1 -7
  50. data/app/views/decidim/initiatives/admin/committee_requests/index.html.erb +29 -11
  51. data/app/views/decidim/initiatives/admin/exports/_dropdown.html.erb +17 -20
  52. data/app/views/decidim/initiatives/admin/initiatives/_form.html.erb +7 -13
  53. data/app/views/decidim/initiatives/admin/initiatives/_initiative_attachments.erb +2 -2
  54. data/app/views/decidim/initiatives/admin/initiatives/index.html.erb +76 -47
  55. data/app/views/decidim/initiatives/admin/initiatives_types/_form.html.erb +13 -21
  56. data/app/views/decidim/initiatives/admin/initiatives_types/_initiative_type_scopes.html.erb +28 -12
  57. data/app/views/decidim/initiatives/admin/initiatives_types/index.html.erb +33 -15
  58. data/app/views/decidim/initiatives/create_initiative/_committee_member.html.erb +27 -0
  59. data/app/views/decidim/initiatives/create_initiative/_return_to_initiatives_button.html.erb +3 -0
  60. data/app/views/decidim/initiatives/create_initiative/_send_to_technical_validation_button.html.erb +10 -0
  61. data/app/views/decidim/initiatives/create_initiative/_share_committee_link.html.erb +5 -1
  62. data/app/views/decidim/initiatives/create_initiative/fill_data.html.erb +7 -11
  63. data/app/views/decidim/initiatives/create_initiative/finish.html.erb +16 -13
  64. data/app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb +33 -6
  65. data/app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb +40 -26
  66. data/app/views/decidim/initiatives/initiative_signatures/_sms_code_form.html.erb +22 -0
  67. data/app/views/decidim/initiatives/initiative_signatures/_sms_phone_number_form.html.erb +13 -0
  68. data/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +23 -22
  69. data/app/views/decidim/initiatives/initiative_signatures/finish.html.erb +17 -5
  70. data/app/views/decidim/initiatives/initiative_signatures/sms_code.html.erb +6 -8
  71. data/app/views/decidim/initiatives/initiative_signatures/sms_phone_number.html.erb +3 -8
  72. data/app/views/decidim/initiatives/initiative_signatures/update_buttons_and_counters.js.erb +3 -14
  73. data/app/views/decidim/initiatives/initiative_votes/update_buttons_and_counters.js.erb +3 -14
  74. data/app/views/decidim/initiatives/initiatives/_committee_members.html.erb +1 -1
  75. data/app/views/decidim/initiatives/initiatives/_form.html.erb +1 -3
  76. data/app/views/decidim/initiatives/initiatives/_new_initiative_button.html.erb +10 -3
  77. data/app/views/decidim/initiatives/initiatives/_pending_initiatives.html.erb +5 -0
  78. data/app/views/decidim/initiatives/initiatives/index.html.erb +8 -0
  79. data/app/views/decidim/initiatives/initiatives/show.html.erb +2 -2
  80. data/app/views/layouts/decidim/_initiative_signature_creation_header.html.erb +20 -2
  81. data/app/views/layouts/decidim/admin/_manage_initiatives.html.erb +1 -1
  82. data/app/views/layouts/decidim/initiative_signature_creation.html.erb +3 -1
  83. data/config/assets.rb +2 -2
  84. data/config/locales/ar.yml +0 -45
  85. data/config/locales/bg.yml +0 -54
  86. data/config/locales/ca-IT.yml +99 -51
  87. data/config/locales/ca.yml +99 -51
  88. data/config/locales/cs.yml +93 -54
  89. data/config/locales/de.yml +99 -51
  90. data/config/locales/el.yml +0 -45
  91. data/config/locales/en.yml +99 -51
  92. data/config/locales/es-MX.yml +99 -51
  93. data/config/locales/es-PY.yml +99 -51
  94. data/config/locales/es.yml +99 -51
  95. data/config/locales/eu.yml +99 -51
  96. data/config/locales/fi-plain.yml +99 -51
  97. data/config/locales/fi.yml +99 -51
  98. data/config/locales/fr-CA.yml +44 -51
  99. data/config/locales/fr.yml +44 -51
  100. data/config/locales/ga-IE.yml +0 -17
  101. data/config/locales/gl.yml +0 -41
  102. data/config/locales/hu.yml +0 -54
  103. data/config/locales/id-ID.yml +0 -40
  104. data/config/locales/is-IS.yml +0 -22
  105. data/config/locales/it.yml +0 -53
  106. data/config/locales/ja.yml +98 -49
  107. data/config/locales/lb.yml +0 -50
  108. data/config/locales/lt.yml +0 -56
  109. data/config/locales/lv.yml +0 -46
  110. data/config/locales/nl.yml +0 -47
  111. data/config/locales/no.yml +0 -53
  112. data/config/locales/pl.yml +0 -56
  113. data/config/locales/pt-BR.yml +0 -53
  114. data/config/locales/pt.yml +0 -53
  115. data/config/locales/ro-RO.yml +92 -50
  116. data/config/locales/ru.yml +0 -25
  117. data/config/locales/sk.yml +0 -43
  118. data/config/locales/sl.yml +0 -1
  119. data/config/locales/sv.yml +10 -53
  120. data/config/locales/tr-TR.yml +0 -53
  121. data/config/locales/uk.yml +0 -25
  122. data/config/locales/zh-CN.yml +0 -45
  123. data/config/locales/zh-TW.yml +0 -53
  124. data/db/migrate/20250605104500_remove_hashtag_column_initiatives.rb +7 -0
  125. data/lib/decidim/api/initiative_api_type.rb +3 -0
  126. data/lib/decidim/api/initiative_type.rb +23 -4
  127. data/lib/decidim/exporters/initiative_votes_pdf.rb +1 -1
  128. data/lib/decidim/initiatives/default_signature_authorizer.rb +17 -0
  129. data/lib/decidim/initiatives/engine.rb +17 -14
  130. data/lib/decidim/initiatives/participatory_space.rb +15 -1
  131. data/lib/decidim/initiatives/seeds.rb +1 -2
  132. data/lib/decidim/initiatives/signature_workflow_manifest.rb +176 -0
  133. data/lib/decidim/initiatives/signatures.rb +12 -0
  134. data/lib/decidim/initiatives/test/factories.rb +7 -7
  135. data/lib/decidim/initiatives/test/initiatives_signatures_test_helpers.rb +19 -0
  136. data/lib/decidim/initiatives/validatable_authorizations.rb +83 -0
  137. data/lib/decidim/initiatives/version.rb +1 -1
  138. data/lib/decidim/initiatives.rb +23 -12
  139. metadata +33 -21
  140. data/app/events/decidim/initiatives/endorse_initiative_event.rb +0 -13
  141. data/app/forms/decidim/initiatives/vote_form.rb +0 -208
  142. data/app/packs/src/decidim/initiatives/identity_selector_dialog.js +0 -14
  143. data/app/services/decidim/initiatives/pdf_signature_example.rb +0 -110
  144. data/app/views/decidim/initiatives/initiative_signatures/_wizard_steps.html.erb +0 -15
  145. data/app/views/decidim/initiatives/initiatives/_interactions.html.erb +0 -10
  146. data/app/views/layouts/decidim/_initiative_header.html.erb +0 -27
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-initiatives
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.2
4
+ version: 0.31.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Salvador Perez Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-23 00:00:00.000000000 Z
11
+ date: 2025-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim-admin
@@ -16,84 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.30.2
19
+ version: 0.31.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.30.2
26
+ version: 0.31.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: decidim-comments
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.30.2
33
+ version: 0.31.0.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.30.2
40
+ version: 0.31.0.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: decidim-core
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.30.2
47
+ version: 0.31.0.rc1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.30.2
54
+ version: 0.31.0.rc1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: decidim-verifications
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.30.2
61
+ version: 0.31.0.rc1
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.30.2
68
+ version: 0.31.0.rc1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: decidim-dev
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.30.2
75
+ version: 0.31.0.rc1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 0.30.2
82
+ version: 0.31.0.rc1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: decidim-meetings
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.30.2
89
+ version: 0.31.0.rc1
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.30.2
96
+ version: 0.31.0.rc1
97
97
  description: Participants initiatives plugin for decidim.
98
98
  email:
99
99
  - jsperezg@gmail.com
@@ -140,6 +140,7 @@ files:
140
140
  - app/constraints/decidim/initiatives/current_initiative.rb
141
141
  - app/controllers/concerns/decidim/initiatives/admin/filterable.rb
142
142
  - app/controllers/concerns/decidim/initiatives/admin/initiative_admin.rb
143
+ - app/controllers/concerns/decidim/initiatives/has_signature_workflow.rb
143
144
  - app/controllers/concerns/decidim/initiatives/needs_initiative.rb
144
145
  - app/controllers/concerns/decidim/initiatives/orderable.rb
145
146
  - app/controllers/concerns/decidim/initiatives/single_initiative_type.rb
@@ -177,7 +178,6 @@ files:
177
178
  - app/events/decidim/initiatives/admin/support_threshold_reached_event.rb
178
179
  - app/events/decidim/initiatives/approve_membership_request_event.rb
179
180
  - app/events/decidim/initiatives/create_initiative_event.rb
180
- - app/events/decidim/initiatives/endorse_initiative_event.rb
181
181
  - app/events/decidim/initiatives/extend_initiative_event.rb
182
182
  - app/events/decidim/initiatives/initiative_sent_to_technical_validation_event.rb
183
183
  - app/events/decidim/initiatives/milestone_completed_event.rb
@@ -191,7 +191,6 @@ files:
191
191
  - app/forms/decidim/initiatives/committee_member_form.rb
192
192
  - app/forms/decidim/initiatives/initiative_form.rb
193
193
  - app/forms/decidim/initiatives/select_initiative_type_form.rb
194
- - app/forms/decidim/initiatives/vote_form.rb
195
194
  - app/helpers/decidim/initiatives/admin/initiatives_helper.rb
196
195
  - app/helpers/decidim/initiatives/application_helper.rb
197
196
  - app/helpers/decidim/initiatives/initiative_helper.rb
@@ -215,7 +214,8 @@ files:
215
214
  - app/packs/src/decidim/initiatives/admin/initiatives_types.js
216
215
  - app/packs/src/decidim/initiatives/admin/invite_users.js
217
216
  - app/packs/src/decidim/initiatives/application.js
218
- - app/packs/src/decidim/initiatives/identity_selector_dialog.js
217
+ - app/packs/src/decidim/initiatives/check_code.js
218
+ - app/packs/src/decidim/initiatives/initiative_creation_wizard.js
219
219
  - app/packs/src/decidim/initiatives/scoped_type.js
220
220
  - app/packs/stylesheets/decidim/initiatives/admin/initiatives.scss
221
221
  - app/packs/stylesheets/initiatives.scss
@@ -232,6 +232,8 @@ files:
232
232
  - app/queries/decidim/initiatives/initiative_types.rb
233
233
  - app/queries/decidim/initiatives/initiatives_created.rb
234
234
  - app/queries/decidim/initiatives/initiatives_promoted.rb
235
+ - app/queries/decidim/initiatives/initiatives_stats_followers_count.rb
236
+ - app/queries/decidim/initiatives/initiatives_stats_participants_count.rb
235
237
  - app/queries/decidim/initiatives/organization_prioritized_initiatives.rb
236
238
  - app/queries/decidim/initiatives/outdated_validating_initiatives.rb
237
239
  - app/queries/decidim/initiatives/support_period_finished_initiatives.rb
@@ -243,8 +245,9 @@ files:
243
245
  - app/services/decidim/initiatives/diff_renderer.rb
244
246
  - app/services/decidim/initiatives/dummy_timestamp.rb
245
247
  - app/services/decidim/initiatives/initiative_search.rb
246
- - app/services/decidim/initiatives/pdf_signature_example.rb
248
+ - app/services/decidim/initiatives/legacy_signature_handler.rb
247
249
  - app/services/decidim/initiatives/progress_notifier.rb
250
+ - app/services/decidim/initiatives/signature_handler.rb
248
251
  - app/services/decidim/initiatives/status_change_notifier.rb
249
252
  - app/views/decidim/initiatives/_initiative.html.erb
250
253
  - app/views/decidim/initiatives/_modal.html.erb
@@ -267,12 +270,16 @@ files:
267
270
  - app/views/decidim/initiatives/admin/initiatives_types/index.html.erb
268
271
  - app/views/decidim/initiatives/admin/initiatives_types/new.html.erb
269
272
  - app/views/decidim/initiatives/committee_requests/new.html.erb
273
+ - app/views/decidim/initiatives/create_initiative/_committee_member.html.erb
274
+ - app/views/decidim/initiatives/create_initiative/_return_to_initiatives_button.html.erb
275
+ - app/views/decidim/initiatives/create_initiative/_send_to_technical_validation_button.html.erb
270
276
  - app/views/decidim/initiatives/create_initiative/_share_committee_link.html.erb
271
277
  - app/views/decidim/initiatives/create_initiative/fill_data.html.erb
272
278
  - app/views/decidim/initiatives/create_initiative/finish.html.erb
273
279
  - app/views/decidim/initiatives/create_initiative/promotal_committee.html.erb
274
280
  - app/views/decidim/initiatives/create_initiative/select_initiative_type.html.erb
275
- - app/views/decidim/initiatives/initiative_signatures/_wizard_steps.html.erb
281
+ - app/views/decidim/initiatives/initiative_signatures/_sms_code_form.html.erb
282
+ - app/views/decidim/initiatives/initiative_signatures/_sms_phone_number_form.html.erb
276
283
  - app/views/decidim/initiatives/initiative_signatures/error_on_vote.js.erb
277
284
  - app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb
278
285
  - app/views/decidim/initiatives/initiative_signatures/finish.html.erb
@@ -285,9 +292,9 @@ files:
285
292
  - app/views/decidim/initiatives/initiatives/_initiative_badge.html.erb
286
293
  - app/views/decidim/initiatives/initiatives/_initiative_hero.html.erb
287
294
  - app/views/decidim/initiatives/initiatives/_initiatives.html.erb
288
- - app/views/decidim/initiatives/initiatives/_interactions.html.erb
289
295
  - app/views/decidim/initiatives/initiatives/_new_initiative_button.html.erb
290
296
  - app/views/decidim/initiatives/initiatives/_no_initiatives_yet.html.erb
297
+ - app/views/decidim/initiatives/initiatives/_pending_initiatives.html.erb
291
298
  - app/views/decidim/initiatives/initiatives/_progress_bar.html.erb
292
299
  - app/views/decidim/initiatives/initiatives/_result.html.erb
293
300
  - app/views/decidim/initiatives/initiatives/_tags_type.html.erb
@@ -305,7 +312,6 @@ files:
305
312
  - app/views/decidim/initiatives/initiatives_type_signature_types/search.html.erb
306
313
  - app/views/decidim/initiatives/versions/show.html.erb
307
314
  - app/views/layouts/decidim/_initiative_creation_header.html.erb
308
- - app/views/layouts/decidim/_initiative_header.html.erb
309
315
  - app/views/layouts/decidim/_initiative_header_steps.html.erb
310
316
  - app/views/layouts/decidim/_initiative_signature_creation_header.html.erb
311
317
  - app/views/layouts/decidim/admin/_manage_initiatives.html.erb
@@ -459,6 +465,7 @@ files:
459
465
  - db/migrate/20220518053612_add_comments_enabled_to_initiative_types.rb
460
466
  - db/migrate/20220527130640_create_decidim_initiatives_settings.rb
461
467
  - db/migrate/20241127104718_add_taxonomy_to_initiatives_type_scope.rb
468
+ - db/migrate/20250605104500_remove_hashtag_column_initiatives.rb
462
469
  - decidim-initiatives.gemspec
463
470
  - lib/decidim/api/initiative_api_type.rb
464
471
  - lib/decidim/api/initiative_committee_member_type.rb
@@ -472,13 +479,18 @@ files:
472
479
  - lib/decidim/initiatives/application_form_pdf.rb
473
480
  - lib/decidim/initiatives/content_blocks/registry_manager.rb
474
481
  - lib/decidim/initiatives/current_locale.rb
482
+ - lib/decidim/initiatives/default_signature_authorizer.rb
475
483
  - lib/decidim/initiatives/engine.rb
476
484
  - lib/decidim/initiatives/initiative_slug.rb
477
485
  - lib/decidim/initiatives/menu.rb
478
486
  - lib/decidim/initiatives/participatory_space.rb
479
487
  - lib/decidim/initiatives/query_extensions.rb
480
488
  - lib/decidim/initiatives/seeds.rb
489
+ - lib/decidim/initiatives/signature_workflow_manifest.rb
490
+ - lib/decidim/initiatives/signatures.rb
481
491
  - lib/decidim/initiatives/test/factories.rb
492
+ - lib/decidim/initiatives/test/initiatives_signatures_test_helpers.rb
493
+ - lib/decidim/initiatives/validatable_authorizations.rb
482
494
  - lib/decidim/initiatives/version.rb
483
495
  - lib/tasks/decidim_initiatives.rake
484
496
  - lib/tasks/initiatives/upgrade/decidim_initiatives_upgrade_tasks.rake
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Initiatives
5
- class EndorseInitiativeEvent < Decidim::Events::SimpleEvent
6
- include Decidim::Events::AuthorEvent
7
-
8
- def i18n_scope
9
- "decidim.initiatives.events.endorse_initiative_event"
10
- end
11
- end
12
- end
13
- end
@@ -1,208 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Initiatives
5
- # A form object used to collect the data for a new initiative.
6
- class VoteForm < Form
7
- include TranslatableAttributes
8
-
9
- mimic :initiatives_vote
10
-
11
- attribute :name_and_surname, String
12
- attribute :document_number, String
13
- attribute :date_of_birth, Date
14
-
15
- attribute :postal_code, String
16
- attribute :encrypted_metadata, String
17
- attribute :hash_id, String
18
-
19
- attribute :initiative, Decidim::Initiative
20
- attribute :signer, Decidim::User
21
-
22
- validates :initiative, :signer, presence: true
23
-
24
- validates :authorized_scopes, presence: true
25
-
26
- with_options if: :required_personal_data? do
27
- validates :name_and_surname, :document_number, :date_of_birth, :postal_code, :encrypted_metadata, :hash_id, presence: true
28
- validate :document_number_authorized?
29
- validate :already_voted?
30
- end
31
-
32
- delegate :scope, to: :initiative
33
-
34
- def encrypted_metadata
35
- return unless required_personal_data?
36
-
37
- @encrypted_metadata ||= encryptor.encrypt(metadata)
38
- end
39
-
40
- # Public: The hash to uniquely identify an initiative vote. It uses the
41
- # initiative scope as a default.
42
- #
43
- # Returns a String.
44
- def hash_id
45
- return unless initiative && (document_number || signer)
46
-
47
- @hash_id ||= Digest::MD5.hexdigest(
48
- [
49
- initiative.id,
50
- document_number || signer.id,
51
- Rails.application.secret_key_base
52
- ].compact.join("-")
53
- )
54
- end
55
-
56
- # Public: Builds the list of scopes where the user is authorized to vote in. This is used when
57
- # the initiative allows also voting on child scopes, not only the main scope.
58
- #
59
- # Instead of just listing the children of the main scope, we just want to select the ones that
60
- # have been added to the InitiativeType with its voting settings.
61
- #
62
- def authorized_scopes
63
- initiative.votable_initiative_type_scopes.select do |initiative_type_scope|
64
- initiative_type_scope.global_scope? ||
65
- initiative_type_scope.scope == user_authorized_scope ||
66
- initiative_type_scope.scope.ancestor_of?(user_authorized_scope)
67
- end.flat_map(&:scope)
68
- end
69
-
70
- # Public: Finds the scope the user has an authorization for, this way the user can vote
71
- # on that scope and its parents.
72
- #
73
- # This is can be used to allow users that are authorized with a children
74
- # scope to sign an initiative with a parent scope.
75
- #
76
- # As an example: A city (global scope) has many districts (scopes with
77
- # parent nil), and each district has different neighbourhoods (with its
78
- # parent as a district). If we setup the authorization handler to match
79
- # a neighbourhood, the same authorization can be used to participate
80
- # in district, neighbourhoods or city initiatives.
81
- #
82
- # Returns a Decidim::Scope.
83
- def user_authorized_scope
84
- return scope if handler_name.blank?
85
- return unless authorized?
86
- return if authorization.metadata.blank?
87
-
88
- @user_authorized_scope ||= authorized_scope_candidates.find do |scope|
89
- scope&.id == authorization.metadata.symbolize_keys[:scope_id]
90
- end
91
- end
92
-
93
- # Public: Builds a list of Decidim::Scopes where the user could have a
94
- # valid authorization.
95
- #
96
- # If the initiative is set with a global scope (meaning the scope is nil),
97
- # all the scopes in the organization are valid.
98
- #
99
- # Returns an array of Decidim::Scopes.
100
- def authorized_scope_candidates
101
- authorized_scope_candidates = [initiative.scope]
102
- authorized_scope_candidates += if initiative.scope.present?
103
- initiative.scope.descendants
104
- else
105
- initiative.organization.scopes
106
- end
107
- authorized_scope_candidates.uniq
108
- end
109
-
110
- def metadata
111
- {
112
- name_and_surname:,
113
- document_number:,
114
- date_of_birth:,
115
- postal_code:
116
- }
117
- end
118
-
119
- protected
120
-
121
- # Private: Whether the personal data given when signing the initiative should
122
- # be stored together with the vote or not.
123
- #
124
- # Returns a Boolean.
125
- def required_personal_data?
126
- @required_personal_data ||= initiative&.type&.collect_user_extra_fields?
127
- end
128
-
129
- # Private: Checks that the unique hash computed from the authorization
130
- # and the user provided data match.
131
- #
132
- # This prevents users that know partial data from another user to sign
133
- # initiatives with someone elses identity.
134
- def document_number_authorized?
135
- return if initiative.document_number_authorization_handler.blank?
136
-
137
- errors.add(:document_number, :invalid) unless authorized? && authorization_handler && authorization.unique_id == authorization_handler.unique_id
138
- end
139
-
140
- # Private: Checks if there is any existing vote that matches the user's data.
141
- def already_voted?
142
- errors.add(:document_number, :taken) if initiative.votes.exists?(hash_id:, scope:)
143
- end
144
-
145
- def author
146
- @author ||= current_organization.users.find_by(id: author_id)
147
- end
148
-
149
- # Private: Finds an authorization for the user signing the initiative and
150
- # the configured handler.
151
- def authorization
152
- return unless signer && handler_name
153
-
154
- @authorization ||= Verifications::Authorizations.new(
155
- organization: signer.organization,
156
- user: signer,
157
- name: handler_name
158
- ).first
159
- end
160
-
161
- # Private: Checks if the authorization has not expired or is invalid.
162
- def authorized?
163
- authorization_status&.first == :ok
164
- end
165
-
166
- # Private: Builds an authorization handler with the data the user provided
167
- # when signing the initiative.
168
- #
169
- # This is currently tied to authorization handlers that have, at least, these attributes:
170
- # * document_number
171
- # * name_and_surname
172
- # * date_of_birth
173
- # * postal_code
174
- #
175
- # Once we have the authorization handler we can use is to compute the
176
- # unique_id and compare it to an existing authorization.
177
- #
178
- # Returns a Decidim::AuthorizationHandler.
179
- def authorization_handler
180
- return unless document_number && handler_name
181
-
182
- @authorization_handler ||= Decidim::AuthorizationHandler.handler_for(handler_name,
183
- document_number:,
184
- name_and_surname:,
185
- date_of_birth:,
186
- postal_code:)
187
- end
188
-
189
- # Private: The AuthorizationHandler name used to verify the user's
190
- # document number.
191
- #
192
- # Returns a String.
193
- def handler_name
194
- initiative.document_number_authorization_handler
195
- end
196
-
197
- def authorization_status
198
- return unless authorization
199
-
200
- Decidim::Verifications::Adapter.from_element(handler_name).authorize(authorization, {}, nil, nil)
201
- end
202
-
203
- def encryptor
204
- @encryptor ||= DataEncryptor.new(secret: "personal user metadata")
205
- end
206
- end
207
- end
208
- end
@@ -1,14 +0,0 @@
1
- $(() => {
2
- let button = $("#select-identity-button"),
3
- userIdentitiesDialog = $("#user-identities");
4
-
5
- if (userIdentitiesDialog.length) {
6
- let refreshUrl = userIdentitiesDialog.data("refresh-url");
7
-
8
- button.click(function () {
9
- $.ajax(refreshUrl).done(function(response) {
10
- userIdentitiesDialog.html(response).foundation("open");
11
- });
12
- });
13
- }
14
- })
@@ -1,110 +0,0 @@
1
- # frozen_string_literal: false
2
-
3
- require "hexapdf"
4
- require "tempfile"
5
-
6
- module Decidim
7
- module Initiatives
8
- # Example of service to add a signature to a pdf
9
- class PdfSignatureExample
10
- attr_accessor :pdf
11
-
12
- # Public: Initializes the service.
13
- # pdf - The pdf document to be signed
14
- def initialize(args = {})
15
- @pdf = args.fetch(:pdf)
16
- end
17
-
18
- # Public: PDF signed using a new certificate generated by the service
19
- def signed_pdf
20
- signed_file = Tempfile.new("signed_pdf")
21
-
22
- doc = HexaPDF::Document.new(io: StringIO.new(pdf))
23
-
24
- # Prepare the document for embedding of the digital signature
25
- data = nil # Used for storing the to-be-signed data
26
- signing_mechanism = lambda do |io, byte_range|
27
- # Store the to-be-signed data in the local variable data
28
- io.pos = byte_range[0]
29
- data = io.read(byte_range[1])
30
- io.pos = byte_range[2]
31
- data << io.read(byte_range[3])
32
- ""
33
- end
34
- doc.sign(signed_file.path, signature: signature_widget(doc), reason: caption, signature_size: 10_000, external_signing: signing_mechanism)
35
-
36
- signature = OpenSSL::PKCS7.sign(certificate, key, data,
37
- # [HexaPDF.demo_cert.sub_ca, HexaPDF.demo_cert.root_ca],
38
- [],
39
- OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY).to_der
40
-
41
- # Embed the signature
42
- HexaPDF::DigitalSignature::Signing.embed_signature(File.open(signed_file.path, "rb+"), signature)
43
-
44
- File.binread(signed_file.path)
45
- ensure
46
- signed_file.close
47
- signed_file.unlink
48
- end
49
-
50
- private
51
-
52
- def signature_widget(doc)
53
- form = doc.acro_form(create: true)
54
- form.signature_flag(:append_only)
55
-
56
- sig_field = form.create_signature_field("signature")
57
-
58
- widget = sig_field.create_widget(doc.pages[doc.pages.length - 1], Rect: [60, 50, 250, 620])
59
- widget.flag(:print)
60
- xobject = (widget[:AP] ||= {})[:N] ||= doc.add({ Type: :XObject, Subtype: :Form }) # Create the appearance for the widget
61
- xobject[:BBox] = [0, 0, widget[:Rect].width, widget[:Rect].height]
62
- xobject.canvas
63
- .font("Helvetica", size: 10)
64
- .text(caption, at: [10, 30])
65
-
66
- sig = doc.add({ Type: :Sig }) # set an empty signature and apply it to the field
67
- sig_field.field_value = sig
68
- sig
69
- end
70
-
71
- def certificate
72
- @certificate ||= OpenSSL::X509::Certificate.new.tap do |cert|
73
- cert.not_before = Time.current
74
- cert.not_after = 10.years.from_now
75
-
76
- cert.public_key = key.public_key
77
- cert.sign(key, OpenSSL::Digest.new("SHA256"))
78
- end
79
- end
80
-
81
- def key
82
- @key ||= OpenSSL::PKey::RSA.new(2048)
83
- end
84
-
85
- def caption
86
- @caption ||= "Digitally Signed By: #{signedby}\nContact: #{contact}\nLocation: #{location}\nDate: #{date.iso8601}"
87
- end
88
-
89
- def signedby
90
- "Test"
91
- end
92
-
93
- def location
94
- "Barcelona"
95
- end
96
-
97
- def contact
98
- "test@example.org"
99
- end
100
-
101
- def issuer
102
- "Decidim"
103
- end
104
-
105
- def date
106
- Time.current
107
- end
108
- end
109
- end
110
- end
@@ -1,15 +0,0 @@
1
- <% scope = "layouts.decidim.initiative_signature_creation_header" %>
2
- <ol id="wizard-steps" class="wizard-steps">
3
- <% options = { data: { active: false }, aria: { current: "step" } } %>
4
-
5
- <% if fill_personal_data_step? %>
6
- <%= content_tag :li, t("fill_personal_data", scope: ),
7
- %w(fill_personal_data update_fill_personal_data).include?(action_name) ? options : {} %>
8
- <% end %>
9
- <% if sms_step? %>
10
- <%= content_tag :li, t("sms_phone_number", scope: ),
11
- %w(sms_phone_number update_sms_phone_number).include?(action_name) ? options : {} %>
12
- <%= content_tag :li, t("sms_code", scope: ), %w(sms_code update_sms_code).include?(action_name) ? options : {} %>
13
- <% end %>
14
- <%= content_tag :li, t("finish", scope: ), action_name == "finish" ? options : {} %>
15
- </ol>
@@ -1,10 +0,0 @@
1
- <div class="row collapse">
2
- <div class="column collapse">
3
- <%= link_to "#comments", class: "button small compact hollow button--nomargin expanded" do %>
4
- <%= icon "chat-1-line", class: "icon--small", role: "img", "aria-hidden": true %>
5
- <%= stats.comments_count %>
6
- <%= t(".comments_count.count", count: stats.comments_count) %>
7
- <% end %>
8
- </button>
9
- </div>
10
- </div>
@@ -1,27 +0,0 @@
1
- <div class="process-header">
2
- <div>
3
- <div class="row column"
4
- style="background-image:url('<%= current_participatory_space.type.attached_uploader(:banner_image).url %>');">
5
- </div>
6
- <div class="row collapse column">
7
- <div class="columns">
8
- <div>
9
- <h1>
10
- <%= participatory_space_helpers.translated_attribute(current_participatory_space.title) %>
11
- </h1>
12
- </div>
13
- <div>
14
- <p>
15
- <% if current_participatory_space.hashtag.present? %>
16
- <span>
17
- <%= link_to "##{current_participatory_space.hashtag}", twitter_hashtag_url(current_participatory_space.hashtag), target: "_blank" %>
18
- </span>
19
- <% end %>
20
- <%= strip_tags participatory_space_helpers.translated_attribute(current_participatory_space.type.title) %>
21
- </p>
22
- </div>
23
- </div>
24
- </div>
25
- </div>
26
- <%= extended_navigation_bar(initiative_nav_items(current_participatory_space)) %>
27
- </div>