decidim-decidim_awesome 0.12.0 → 0.12.4

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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/README.md +25 -15
  4. data/Rakefile +12 -0
  5. data/app/cells/concerns/decidim/decidim_awesome/global_menu_cell_override.rb +14 -2
  6. data/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb +5 -4
  7. data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal/show.erb +3 -3
  8. data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal/vote_block_for.erb +1 -1
  9. data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +39 -5
  10. data/app/commands/decidim/decidim_awesome/admin/create_authorization_group.rb +42 -0
  11. data/app/commands/decidim/decidim_awesome/admin/create_custom_redirect.rb +10 -14
  12. data/app/commands/decidim/decidim_awesome/admin/create_menu_hack.rb +9 -8
  13. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +3 -8
  14. data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +4 -8
  15. data/app/commands/decidim/decidim_awesome/admin/create_scoped_style.rb +3 -7
  16. data/app/commands/decidim/decidim_awesome/admin/destroy_authorization_group.rb +37 -0
  17. data/app/commands/decidim/decidim_awesome/admin/destroy_custom_redirect.rb +10 -9
  18. data/app/commands/decidim/decidim_awesome/admin/destroy_menu_hack.rb +8 -7
  19. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +7 -13
  20. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +7 -10
  21. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +6 -11
  22. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +12 -1
  23. data/app/commands/decidim/decidim_awesome/admin/update_custom_redirect.rb +11 -11
  24. data/app/commands/decidim/decidim_awesome/admin/update_menu_hack.rb +10 -8
  25. data/app/controllers/concerns/decidim/decidim_awesome/admin/maintenance_context.rb +0 -28
  26. data/app/controllers/concerns/decidim/decidim_awesome/enforce_access_authorizations.rb +49 -0
  27. data/app/controllers/concerns/decidim/decidim_awesome/needs_hashcash.rb +43 -0
  28. data/app/controllers/concerns/decidim/decidim_awesome/not_found_redirect.rb +2 -2
  29. data/app/controllers/decidim/decidim_awesome/admin/admin_authorizations_controller.rb +2 -2
  30. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +0 -4
  31. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +2 -1
  32. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +2 -0
  33. data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +1 -2
  34. data/app/controllers/decidim/decidim_awesome/admin/force_authorizations_controller.rb +44 -0
  35. data/app/controllers/decidim/decidim_awesome/admin/hashcash_controller.rb +39 -0
  36. data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +1 -1
  37. data/app/controllers/decidim/decidim_awesome/admin/{maintenance_controller.rb → private_data_controller.rb} +9 -9
  38. data/app/controllers/decidim/decidim_awesome/required_authorizations_controller.rb +51 -13
  39. data/app/controllers/decidim/decidim_awesome/utils_controller.rb +17 -0
  40. data/app/forms/concerns/decidim/decidim_awesome/proposals/admin/proposal_form_customizations.rb +59 -0
  41. data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_customizations.rb +28 -28
  42. data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_customizations_base.rb +36 -0
  43. data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_override.rb +7 -1
  44. data/app/forms/decidim/decidim_awesome/admin/authorization_group_form.rb +66 -0
  45. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +23 -24
  46. data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +2 -0
  47. data/app/helpers/concerns/decidim/decidim_awesome/amendments_helper_override.rb +2 -1
  48. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +21 -18
  49. data/app/helpers/decidim/decidim_awesome/map_helper.rb +4 -2
  50. data/app/models/decidim/decidim_awesome/paper_trail_version.rb +1 -1
  51. data/app/overrides/decidim/assemblies/admin/assemblies/_form/add_visibility_callout.html.erb.deface +3 -0
  52. data/app/overrides/decidim/conferences/admin/conferences/_form/add_visibility_callout.html.erb.deface +3 -0
  53. data/app/overrides/decidim/devise/registrations/new/add_hashcash.html.erb.deface +3 -0
  54. data/app/overrides/decidim/devise/sessions/new/add_hashcash.html.erb.deface +3 -0
  55. data/app/overrides/decidim/participatory_processes/admin/participatory_process_groups/_form/add_visibility_callout.html.erb.deface +3 -0
  56. data/app/overrides/decidim/participatory_processes/admin/participatory_processes/_form/add_visibility_callout.html.erb.deface +3 -0
  57. data/app/overrides/decidim/shared/_login_modal/add_hashcash.html.erb.deface +3 -0
  58. data/app/overrides/layouts/decidim/_head/add_awesome_custom_styles.html.erb.deface +3 -0
  59. data/app/overrides/layouts/decidim/_head/add_awesome_tags.html.erb.deface +0 -2
  60. data/app/packs/entrypoints/decidim_decidim_awesome_hashcash.js +4 -0
  61. data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +25 -6
  62. data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +4 -2
  63. data/app/packs/src/decidim/decidim_awesome/admin/verifications.js +6 -3
  64. data/app/packs/src/decidim/decidim_awesome/awesome_admin.js +0 -1
  65. data/app/packs/src/decidim/decidim_awesome/awesome_map/api/proposals_fetcher.js +1 -1
  66. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/controller.js +1 -1
  67. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/proposals_controller.js +1 -1
  68. data/app/packs/src/decidim/decidim_awesome/awesome_map/controls_ui.js +6 -6
  69. data/app/packs/src/decidim/decidim_awesome/awesome_map/load_map.js +1 -1
  70. data/app/packs/src/decidim/decidim_awesome/forms/autosave.js +3 -3
  71. data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +1 -113
  72. data/app/packs/src/decidim/decidim_awesome/proposals/images.js +1 -1
  73. data/app/packs/src/vendor/form_builder_langs/ar-SA.lang +111 -0
  74. data/app/packs/src/vendor/form_builder_langs/ar-TN.lang +94 -0
  75. data/app/packs/src/vendor/form_builder_langs/ca-ES.lang +110 -0
  76. data/app/packs/src/vendor/form_builder_langs/cs-CZ.lang +105 -0
  77. data/app/packs/src/vendor/form_builder_langs/da-DK.lang +110 -0
  78. data/app/packs/src/vendor/form_builder_langs/de-DE.lang +109 -0
  79. data/app/packs/src/vendor/form_builder_langs/el-GR.lang +110 -0
  80. data/app/packs/src/vendor/form_builder_langs/en-US.lang +117 -0
  81. data/app/packs/src/vendor/form_builder_langs/es-ES.lang +103 -0
  82. data/app/packs/src/vendor/form_builder_langs/fa-IR.lang +108 -0
  83. data/app/packs/src/vendor/form_builder_langs/fi-FI.lang +107 -0
  84. data/app/packs/src/vendor/form_builder_langs/fr-FR.lang +117 -0
  85. data/app/packs/src/vendor/form_builder_langs/he-IL.lang +108 -0
  86. data/app/packs/src/vendor/form_builder_langs/hi-IN.lang +110 -0
  87. data/app/packs/src/vendor/form_builder_langs/hu-HU.lang +108 -0
  88. data/app/packs/src/vendor/form_builder_langs/id-ID.lang +110 -0
  89. data/app/packs/src/vendor/form_builder_langs/it-IT.lang +107 -0
  90. data/app/packs/src/vendor/form_builder_langs/ja-JP.lang +108 -0
  91. data/app/packs/src/vendor/form_builder_langs/my-MM.lang +108 -0
  92. data/app/packs/src/vendor/form_builder_langs/nb-NO.lang +94 -0
  93. data/app/packs/src/vendor/form_builder_langs/nl-NL.lang +94 -0
  94. data/app/packs/src/vendor/form_builder_langs/pl-PL.lang +122 -0
  95. data/app/packs/src/vendor/form_builder_langs/pt-BR.lang +110 -0
  96. data/app/packs/src/vendor/form_builder_langs/pu-IN.lang +110 -0
  97. data/app/packs/src/vendor/form_builder_langs/qz-MM.lang +108 -0
  98. data/app/packs/src/vendor/form_builder_langs/ro-RO.lang +94 -0
  99. data/app/packs/src/vendor/form_builder_langs/ru-RU.lang +110 -0
  100. data/app/packs/src/vendor/form_builder_langs/sl-SI.lang +110 -0
  101. data/app/packs/src/vendor/form_builder_langs/th-TH.lang +111 -0
  102. data/app/packs/src/vendor/form_builder_langs/tr-TR.lang +115 -0
  103. data/app/packs/src/vendor/form_builder_langs/uk-UA.lang +108 -0
  104. data/app/packs/src/vendor/form_builder_langs/vi-VN.lang +94 -0
  105. data/app/packs/src/vendor/form_builder_langs/zh-CN.lang +100 -0
  106. data/app/packs/src/vendor/form_builder_langs/zh-TW.lang +94 -0
  107. data/app/packs/src/vendor/hashcash.js +83 -0
  108. data/app/packs/src/vendor/sha1.js +143 -0
  109. data/app/packs/src/vendor/stamp.js +50 -0
  110. data/app/packs/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +6 -1
  111. data/app/packs/stylesheets/decidim/decidim_awesome/admin/constraints.scss +5 -0
  112. data/app/packs/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +1 -2
  113. data/app/packs/stylesheets/decidim/decidim_awesome/forms/autosave.scss +2 -12
  114. data/app/presenters/decidim/decidim_awesome/private_data_presenter.rb +2 -2
  115. data/app/queries/decidim/decidim_awesome/space_constraint_finder.rb +43 -0
  116. data/app/serializers/concerns/decidim/decidim_awesome/proposals/proposal_serializer_methods.rb +3 -2
  117. data/app/services/decidim/decidim_awesome/access_authorization_service.rb +79 -0
  118. data/app/types/concerns/decidim/decidim_awesome/add_proposal_type_custom_fields.rb +2 -1
  119. data/app/views/decidim/decidim_awesome/admin/admin_accountability/index.html.erb +4 -4
  120. data/app/views/decidim/decidim_awesome/admin/admin_authorizations/callout.html.erb +2 -2
  121. data/app/views/decidim/decidim_awesome/admin/admin_authorizations/conflict.html.erb +4 -4
  122. data/app/views/decidim/decidim_awesome/admin/admin_authorizations/edit.html.erb +6 -5
  123. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +6 -6
  124. data/app/views/decidim/decidim_awesome/admin/config/_authorization_options_form.html.erb +19 -0
  125. data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +2 -2
  126. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +3 -3
  127. data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +4 -3
  128. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +1 -1
  129. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +4 -4
  130. data/app/views/decidim/decidim_awesome/admin/config/_form_scoped_styles.html.erb +3 -3
  131. data/app/views/decidim/decidim_awesome/admin/config/_form_surveys.html.erb +40 -2
  132. data/app/views/decidim/decidim_awesome/admin/config/_form_verifications.html.erb +71 -9
  133. data/app/views/decidim/decidim_awesome/admin/constraints/_form.html.erb +5 -4
  134. data/app/views/decidim/decidim_awesome/admin/hashcash/_filters.html.erb +55 -0
  135. data/app/views/decidim/decidim_awesome/admin/hashcash/index.html.erb +33 -0
  136. data/app/views/decidim/decidim_awesome/admin/hashcash/ip_addresses.html.erb +29 -0
  137. data/app/views/decidim/decidim_awesome/admin/hashcash/show.html.erb +42 -0
  138. data/app/views/decidim/decidim_awesome/admin/menu_hacks/index.html.erb +2 -2
  139. data/app/views/decidim/decidim_awesome/admin/{maintenance → private_data}/_private_data.html.erb +2 -2
  140. data/app/views/decidim/decidim_awesome/admin/{maintenance/show.html.erb → private_data/index.html.erb} +2 -3
  141. data/app/views/decidim/decidim_awesome/admin/proposals/_private_body.html.erb +1 -1
  142. data/app/views/decidim/decidim_awesome/admin/shared/_visibility_notice.html.erb +8 -0
  143. data/app/views/decidim/decidim_awesome/amendments/_modal.html.erb +2 -2
  144. data/app/views/decidim/decidim_awesome/hashcash/_hidden_field.html.erb +4 -0
  145. data/app/views/decidim/decidim_awesome/required_authorizations/index.html.erb +14 -4
  146. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +2 -2
  147. data/app/views/layouts/decidim/decidim_awesome/admin/maintenance.html.erb +2 -11
  148. data/config/assets.rb +1 -0
  149. data/config/i18n-tasks.yml +2 -0
  150. data/config/locales/ca.yml +100 -37
  151. data/config/locales/cs.yml +100 -36
  152. data/config/locales/de.yml +98 -35
  153. data/config/locales/en.yml +117 -44
  154. data/config/locales/es.yml +100 -36
  155. data/config/locales/eu.yml +34 -39
  156. data/config/locales/fr.yml +77 -31
  157. data/config/locales/ja.yml +99 -36
  158. data/config/locales/sv.yml +49 -0
  159. data/lib/decidim/decidim_awesome/admin_engine.rb +9 -5
  160. data/lib/decidim/decidim_awesome/{authorizator.rb → authorizer.rb} +1 -1
  161. data/lib/decidim/decidim_awesome/awesome.rb +34 -24
  162. data/lib/decidim/decidim_awesome/awesome_helpers.rb +14 -5
  163. data/lib/decidim/decidim_awesome/checksums.yml +26 -40
  164. data/lib/decidim/decidim_awesome/config.rb +18 -7
  165. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +1 -1
  166. data/lib/decidim/decidim_awesome/engine.rb +14 -3
  167. data/lib/decidim/decidim_awesome/menu.rb +151 -138
  168. data/lib/decidim/decidim_awesome/middleware/current_config.rb +5 -10
  169. data/lib/decidim/decidim_awesome/test/initializer.rb +5 -2
  170. data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +1 -3
  171. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +2 -1
  172. data/lib/decidim/decidim_awesome/test/shared_examples/proposal_form_examples.rb +191 -0
  173. data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +15 -4
  174. data/lib/decidim/decidim_awesome/version.rb +1 -1
  175. data/lib/tasks/decidim_awesome_upgrade_tasks.rake +4 -1
  176. data/package.json +7 -8
  177. metadata +86 -13
  178. data/app/controllers/concerns/decidim/decidim_awesome/check_login_authorizations.rb +0 -60
  179. data/app/packs/src/decidim/decidim_awesome/admin/verification_selects.js +0 -21
  180. data/config/rubocop/disabled.yml +0 -11
  181. data/config/rubocop/faker.yml +0 -480
  182. data/config/rubocop/rails.yml +0 -88
  183. data/config/rubocop/rspec.yml +0 -65
  184. data/config/rubocop/ruby.yml +0 -1210
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29689a9ea7f9c930c3683f13c34ecf797b125dc8241ed704ca44174085d59a00
4
- data.tar.gz: f3552ebb84814f2f854f7a9b9bb1f80a0d8b3739cd1fd9626c3cbc4f6a7c7a6e
3
+ metadata.gz: 85eb621adc0f8d42ade17d24162061418885a2d566fab94af0ede1a195c1cf06
4
+ data.tar.gz: ae6688521eb2a8f81d02f67790ea25e6ca1be0466e0874d6f624431b65a73c31
5
5
  SHA512:
6
- metadata.gz: a521a9f071f71436ad251a7ce20c9a7d6202fe83518e291927ce4d9affdbc138238b2e5b618b505db66882beb3af2775f90993ca501c290b7f4152990a38d456
7
- data.tar.gz: 28c137dced1adb31664299f427b55257877f56b4d06041de46a0194fb14b976adf6375dad4a17063ff155031ab4ba6ff6345b4bf2066bcfa9102a3f00a7a482a
6
+ metadata.gz: b4b183a80725bc02a7c518f1de438eb182e2b1108c4d2ab935d47cd959abf8890da6d587990dc5de64194a69513bf7d758c9d763084c853ae83b62998c0d850c
7
+ data.tar.gz: 75aa3a809688d9d5f8a4cfa51a2cea964b1deeb214d9ad774a6869dadc6c81bcf640182ec9577a7b3dd840f5a74916a73c28e1c1913f03ed30ab8b5569605bab
data/CHANGELOG.md CHANGED
@@ -1,6 +1,51 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ v0.12.4
5
+ -------
6
+ Compatibility:
7
+ - Decidim 0.29.x
8
+
9
+ Features:
10
+ - Added application context for config constraints (whether the user is logged or not)
11
+ - Allow to granular permissions to forced verifications.
12
+ **NOTE** Config var `force_authorization_after_login` has changed to `force_authorizations`
13
+ - Fix use of Hashcash in loginModals
14
+ - Fix validation overrides in the admin for proposals
15
+
16
+ v0.12.3
17
+ -------
18
+
19
+ Compatibility:
20
+ - Decidim 0.29.x
21
+
22
+ Features:
23
+ - Fix custom styles loading order
24
+ - Fix for awesome map no loading in a component
25
+ - Fix "other" options in checkbox/radio custom fields
26
+ - Added Mobile Menu Override
27
+
28
+ v0.12.2
29
+ -------
30
+
31
+ Compatibility:
32
+ - Decidim 0.29.x
33
+
34
+ Features:
35
+ - Added HashCash anti-bot mechanism
36
+ - Fixed multi-tenant crossover in admin accountability
37
+
38
+ v0.12.1
39
+ -------
40
+
41
+ Compatibility:
42
+ - Decidim 0.29.x
43
+
44
+ Feature:
45
+ - Added formBuilder languages controller to avoid external CDN
46
+ - Fix cache hash in the global menu override
47
+ - Fix crash on updating empty boxes for scoped admins
48
+
4
49
  v0.12.0
5
50
  -------
6
51
  Compatibility:
data/README.md CHANGED
@@ -121,21 +121,8 @@ Technically, the content is stored in the database as an XML document compatible
121
121
  ![Custom fields screenshot](examples/custom-fields-2.png)
122
122
  ![Custom fields screenshot](examples/custom-fields-1.gif)
123
123
 
124
- Note that the custom fields are build using the jQuery library [formBuilder](https://formbuilder.online). This package is included in Decidim Awesome but the i18n translations are not. By default they are dynamically downloaded from the CDN https://cdn.jsdelivr.net/npm/formbuilder-languages@1.1.0/.
125
- If you wish to provide an alternative place for those files, you can configure the variable `form_builder_langs_location` in an initializer:
126
124
 
127
- ```ruby
128
- # config/initializers/awesome_defaults.rb
129
-
130
- # A URL where to obtain the translations for the FormBuilder component
131
- # you can a custom place if you are worried about the CDN geolocation
132
- # Download them from https://github.com/kevinchappell/formBuilder-languages
133
-
134
- # For instance, copy them to your /public/fb_locales/ directory and set the path here:
135
- Decidim::DecidimAwesome.configure do |config|
136
- config.form_builder_langs_location = "/fb_locales/"
137
- end
138
- ```
125
+ Translations for this feature are extracted from the [NPM formBuilder-languages](https://github.com/kevinchappell/formBuilder-languages).
139
126
 
140
127
  ##### 11.1. GraphQL types for custom fields
141
128
 
@@ -400,7 +387,7 @@ Admins can manage these settings in the Awesome admin panel under the "Verificat
400
387
  ![Forced verifications admin side](examples/forced_verifications_admin.png)
401
388
  ![Forced verifications public side](examples/forced_verifications_public.png)
402
389
 
403
- Note that some pages are allowed, you can even configure which controller are allowed by creating an initializer ("required_authorizations" and "authorizations" are always allowed):
390
+ You can configure which controller are allowed by creating an initializer (some controllers like the login, terms and conditions, etc. are always allowed):
404
391
 
405
392
  ```ruby
406
393
  # config/initializers/decidim_awesome.rb
@@ -425,6 +412,19 @@ System configuration:
425
412
  ![Removing an authorization](examples/manual_verifications_2.png)
426
413
  ![Creating an authorization](examples/manual_verifications_3.png)
427
414
 
415
+ #### 22. HashCash Anti-Bot login/registration
416
+
417
+ This feature adds a HashCash-based anti-bot mechanism to the login and registration forms. HashCash is a proof-of-work system originally designed to limit email spam and denial-of-service attacks. When enabled, users must solve a computational puzzle (a "stamp") before submitting the form, making automated attacks significantly harder.
418
+
419
+ The integration leverages the [ActiveHashcash](https://github.com/BaseSecrete/active_hashcash) gem to generate and verify HashCash stamps (although with some customizations). For more details on the HashCash protocol, see the [official documentation](http://www.hashcash.org/docs/hashcash.html).
420
+
421
+ When this feature is active, each login or registration attempt requires a valid HashCash stamp, effectively reducing the risk of automated bot submissions.
422
+
423
+ Note this feature is **disabled by default**, admins can enabled it under the "Surveys & Forms" menu in the Decidim Awesome admin dashboard.
424
+
425
+ ![Hashcash admin config](examples/haschcash_admin.png)
426
+ ![Hashcash public rendering](examples/hashcash_public.png)
427
+
428
428
  #### To be continued...
429
429
 
430
430
  We're not done! Please check the [issues](/decidim-ice/decidim-module-decidim_awesome/issues) (and participate) to see what's on our mind
@@ -567,6 +567,16 @@ can add the environment variables to the root directory of the project in a file
567
567
  named `.rbenv-vars`. If these are defined for the environment, you can omit
568
568
  defining these in the commands shown above.
569
569
 
570
+ ### Updating formBuilder languages
571
+
572
+ There's a rake task to update the translations of the custom field's form builder interface:
573
+
574
+ ```
575
+ bundle exec rake update_form_builder_i18n
576
+ ```
577
+
578
+ This updates the `app/packs/src/vendor/form_builder_langs` folder.
579
+
570
580
  ### Code Styling
571
581
 
572
582
  Please follow the code styling defined by the different linters that ensure we
data/Rakefile CHANGED
@@ -6,6 +6,7 @@ require "fileutils"
6
6
  def install_module(path)
7
7
  Dir.chdir(path) do
8
8
  system("bundle exec rake decidim_decidim_awesome:install:migrations")
9
+ system("bundle exec rake active_hashcash:install:migrations")
9
10
  system("bundle exec rake db:migrate")
10
11
  end
11
12
  end
@@ -55,3 +56,14 @@ task :development_app do
55
56
  override_webpacker_config_files("development_app")
56
57
  seed_db("development_app")
57
58
  end
59
+
60
+ desc "Update languages for custom fields"
61
+ task :update_form_builder_i18n do
62
+ puts "Updating languages for custom fields from formbuilder-languages NPM package..."
63
+ system("npm install formbuilder-languages")
64
+ puts "Copying files..."
65
+
66
+ Dir.glob("node_modules/formbuilder-languages/*.lang").each do |file_lang|
67
+ FileUtils.cp(file_lang, "app/packs/src/vendor/form_builder_langs", verbose: true)
68
+ end
69
+ end
@@ -6,14 +6,26 @@ module Decidim
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
+ private
10
+
9
11
  def cache_hash
10
- [
12
+ @decidim_awesome_cache_hash ||= [
11
13
  "decidim/content_blocks/global_menu",
12
14
  current_organization.cache_key_with_version,
13
15
  I18n.locale,
14
- awesome_config[:home_content_block_menu].to_s
16
+ *extra_cache_keys
15
17
  ].join(Decidim.cache_key_separator)
16
18
  end
19
+
20
+ def extra_cache_keys
21
+ [].tap do |array|
22
+ array << awesome_config[:home_content_block_menu].to_s
23
+ if defined?(current_user) && current_user
24
+ array << current_user.id
25
+ array << Decidim::Authorization.find_by(user: current_user)&.cache_key_with_version
26
+ end
27
+ end
28
+ end
17
29
  end
18
30
  end
19
31
  end
@@ -15,10 +15,11 @@ module Decidim
15
15
  end
16
16
 
17
17
  def cache_hash
18
- all_extra_fields = memoize("extra_fields")
19
- extra_fields = all_extra_fields ? all_extra_fields[resource.id] : resource.extra_fields
20
-
21
- @cache_hash ||= "#{decidim_original_cache_hash}#{Decidim.cache_key_separator}#{extra_fields&.vote_weight_totals}"
18
+ @decidim_awesome_cache_hash ||= begin
19
+ all_extra_fields = memoize("extra_fields")
20
+ extra_fields = all_extra_fields ? all_extra_fields[resource.id] : resource.extra_fields
21
+ "#{decidim_original_cache_hash}#{Decidim.cache_key_separator}#{extra_fields&.vote_weight_totals}"
22
+ end
22
23
  end
23
24
  end
24
25
  end
@@ -12,9 +12,9 @@
12
12
  voted_for?(0) ? t("decidim.decidim_awesome.voting.voting_cards.abstained") : proposal.manifest.label_for(0),
13
13
  proposal_vote_path(0),
14
14
  link_options(0).merge({
15
- title: t("decidim.decidim_awesome.voting.voting_cards.voting_for", proposal: sanitized_title, type: proposal.manifest.label_for(0)),
16
- class: "button button__sm button__transparent-secondary mb-4 vote-action abstain-button #{classes_for(0)}"
17
- }) %>
15
+ title: t("decidim.decidim_awesome.voting.voting_cards.voting_for", proposal: sanitized_title, type: proposal.manifest.label_for(0)),
16
+ class: "button button__sm button__transparent-secondary mb-4 vote-action abstain-button #{classes_for(0)}"
17
+ }) %>
18
18
  <% end %>
19
19
 
20
20
  <% if voted_for_any? && !current_settings.votes_blocked? %>
@@ -9,7 +9,7 @@
9
9
  <span class="vote-label"><%= proposal.manifest.label_for(weight) %></span>
10
10
  <%= content_tag :svg, role: "img" do
11
11
  content_tag(:title, t("decidim.decidim_awesome.voting.voting_cards.voting_for", proposal: sanitized_title, type: proposal.manifest.label_for(weight))) +
12
- content_tag(:use, "", "href" => svg_path(weight))
12
+ content_tag(:use, "", "href" => svg_path(weight))
13
13
  end %>
14
14
  <% end %>
15
15
  </div>
@@ -6,12 +6,46 @@ module Decidim
6
6
  module NeedsConstraintHelpers
7
7
  private
8
8
 
9
- def create_constraint_never(var)
10
- settings = { "participatory_space_manifest" => "none" }
11
- subconfig = AwesomeConfig.find_or_initialize_by(var: "#{var}_#{@ident}", organization: @organization)
9
+ attr_reader :organization, :config_var
10
+
11
+ def ident
12
+ @ident ||= rand(36**8).to_s(36)
13
+ end
14
+
15
+ def find_var
16
+ @find_var ||= AwesomeConfig.find_or_initialize_by(var: config_var, organization:)
17
+ end
18
+
19
+ def find_sub_var
20
+ @find_sub_var ||= AwesomeConfig.find_or_initialize_by(var: "#{config_var.to_s.singularize}_#{ident}", organization:)
21
+ end
22
+
23
+ def create_array_config!(default_attributes = nil)
24
+ find_var.value = [] unless find_var.value.is_a?(Array)
25
+ find_var.value << default_attributes if default_attributes
26
+ find_var.save!
27
+ find_var
28
+ end
29
+
30
+ def create_hash_config!(default_attributes = nil)
31
+ find_var.value = {} unless find_var.value.is_a?(Hash)
32
+ find_var.value[ident] = default_attributes if default_attributes
33
+ find_var.save!
34
+ find_var
35
+ end
36
+
37
+ def destroy_hash_ident!
38
+ find_var.value.except!(ident)
39
+ find_var.save!
40
+
41
+ # remove associated sub var (dependents will be destroyed automatically via ActiveRecord triggers)
42
+ find_sub_var.destroy! if find_sub_var.present?
43
+ end
44
+
45
+ def create_constraint_never!
12
46
  @constraint = ConfigConstraint.create!(
13
- awesome_config: subconfig,
14
- settings:
47
+ awesome_config: find_sub_var,
48
+ settings: { "participatory_space_manifest" => "none" }
15
49
  )
16
50
  end
17
51
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Admin
6
+ class CreateAuthorizationGroup < Command
7
+ include NeedsConstraintHelpers
8
+ # Public: Initializes the command.
9
+ #
10
+ def initialize(organization, config_var = :force_authorizations)
11
+ @organization = organization
12
+ @config_var = config_var
13
+ end
14
+
15
+ # Executes the command. Broadcasts these events:
16
+ #
17
+ # - :ok when everything is valid.
18
+ # - :invalid if we couldn't proceed.
19
+ #
20
+ # Returns nothing.
21
+ def call
22
+ create_hash_config!(attributes)
23
+
24
+ create_constraint_never!
25
+
26
+ broadcast(:ok, ident)
27
+ rescue StandardError => e
28
+ broadcast(:invalid, e.message)
29
+ end
30
+
31
+ private
32
+
33
+ def attributes
34
+ {
35
+ "authorization_handlers" => {},
36
+ "force_authorization_help_text" => {}
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,11 +4,14 @@ module Decidim
4
4
  module DecidimAwesome
5
5
  module Admin
6
6
  class CreateCustomRedirect < Command
7
+ include NeedsConstraintHelpers
7
8
  # Public: Initializes the command.
8
9
  #
9
10
  def initialize(form)
10
11
  @form = form
11
- @redirections = AwesomeConfig.find_or_initialize_by(var: :custom_redirects, organization: form.current_organization)
12
+ @ident = form.to_params[0]
13
+ @organization = form.current_organization
14
+ @config_var = :custom_redirects
12
15
  end
13
16
 
14
17
  # Executes the command. Broadcasts these events:
@@ -21,7 +24,8 @@ module Decidim
21
24
  return broadcast(:invalid) if form.invalid?
22
25
  return broadcast(:invalid, I18n.t("custom_redirects.origin_exists", scope: "decidim.decidim_awesome.admin")) if url_exists?
23
26
 
24
- create_redirection!
27
+ create_hash_config!(form.to_params[1])
28
+
25
29
  broadcast(:ok)
26
30
  rescue StandardError => e
27
31
  broadcast(:invalid, e.message)
@@ -29,21 +33,13 @@ module Decidim
29
33
 
30
34
  private
31
35
 
32
- attr_reader :form, :redirections
33
-
34
- delegate :to_params, to: :form
35
-
36
- def create_redirection!
37
- redirections.value = {} unless redirections.value.is_a? Hash
38
- redirections.value[to_params[0]] = to_params[1]
39
- redirections.save!
40
- end
36
+ attr_reader :form
41
37
 
42
38
  def url_exists?
43
- return false unless redirections
44
- return false unless redirections.value.is_a? Hash
39
+ return false unless find_var
40
+ return false unless find_var.value.is_a? Hash
45
41
 
46
- redirections.value[form.origin].present?
42
+ find_var.value[form.origin].present?
47
43
  end
48
44
  end
49
45
  end
@@ -4,11 +4,13 @@ module Decidim
4
4
  module DecidimAwesome
5
5
  module Admin
6
6
  class CreateMenuHack < Command
7
+ include NeedsConstraintHelpers
7
8
  # Public: Initializes the command.
8
9
  #
9
10
  def initialize(form, menu_name)
10
11
  @form = form
11
- @menu = AwesomeConfig.find_or_initialize_by(var: menu_name, organization: form.current_organization)
12
+ @config_var = menu_name
13
+ @organization = form.current_organization
12
14
  end
13
15
 
14
16
  # Executes the command. Broadcasts these events:
@@ -21,22 +23,21 @@ module Decidim
21
23
  return broadcast(:invalid) if form.invalid?
22
24
  return broadcast(:invalid, I18n.t("menu_hacks.url_exists", scope: "decidim.decidim_awesome.admin")) if url_exists?
23
25
 
24
- menu.value = [] unless menu.value.is_a? Array
25
- menu.value << to_params
26
- menu.save!
27
- broadcast(:ok, menu)
26
+ create_array_config!(to_params)
27
+
28
+ broadcast(:ok, find_var)
28
29
  rescue StandardError => e
29
30
  broadcast(:invalid, e.message)
30
31
  end
31
32
 
32
33
  private
33
34
 
34
- attr_reader :form, :menu
35
+ attr_reader :form
35
36
 
36
37
  def url_exists?
37
- return false unless menu
38
+ return false unless find_var
38
39
 
39
- menu.value&.detect { |i| i["url"] == form.url.gsub(/\?.*/, "") }
40
+ find_var.value&.detect { |i| i["url"] == form.url.gsub(/\?.*/, "") }
40
41
  end
41
42
 
42
43
  def to_params
@@ -10,7 +10,6 @@ module Decidim
10
10
  #
11
11
  def initialize(organization, config_var = :proposal_custom_fields)
12
12
  @organization = organization
13
- @ident = rand(36**8).to_s(36)
14
13
  @config_var = config_var
15
14
  end
16
15
 
@@ -21,15 +20,11 @@ module Decidim
21
20
  #
22
21
  # Returns nothing.
23
22
  def call
24
- fields = AwesomeConfig.find_or_initialize_by(var: @config_var, organization: @organization)
25
- fields.value = {} unless fields.value.is_a? Hash
26
- # TODO: prevent (unlikely) colisions with exisiting values
27
- fields.value[@ident] = default_definition
28
- fields.save!
23
+ create_hash_config!(default_definition)
29
24
 
30
- create_constraint_never(@config_var == :proposal_custom_fields ? :proposal_custom_field : :proposal_private_custom_field)
25
+ create_constraint_never!
31
26
 
32
- broadcast(:ok, @ident)
27
+ broadcast(:ok, ident)
33
28
  rescue StandardError => e
34
29
  broadcast(:invalid, e.message)
35
30
  end
@@ -10,7 +10,7 @@ module Decidim
10
10
  #
11
11
  def initialize(organization)
12
12
  @organization = organization
13
- @ident = rand(36**8).to_s(36)
13
+ @config_var = :scoped_admins
14
14
  end
15
15
 
16
16
  # Executes the command. Broadcasts these events:
@@ -20,15 +20,11 @@ module Decidim
20
20
  #
21
21
  # Returns nothing.
22
22
  def call
23
- admins = AwesomeConfig.find_or_initialize_by(var: :scoped_admins, organization: @organization)
24
- admins.value = {} unless admins.value.is_a? Hash
25
- # TODO: prevent (unlikely) colisions with exisiting values
26
- admins.value[@ident] = []
27
- admins.save!
23
+ create_hash_config!([])
28
24
 
29
- create_constraint_never(:scoped_admin)
25
+ create_constraint_never!
30
26
 
31
- broadcast(:ok, @ident)
27
+ broadcast(:ok, ident)
32
28
  rescue StandardError => e
33
29
  broadcast(:invalid, e.message)
34
30
  end
@@ -4,11 +4,11 @@ module Decidim
4
4
  module DecidimAwesome
5
5
  module Admin
6
6
  class CreateScopedStyle < Command
7
+ include NeedsConstraintHelpers
7
8
  # Public: Initializes the command.
8
9
  #
9
10
  def initialize(organization, config_var = :scoped_styles)
10
11
  @organization = organization
11
- @ident = rand(36**8).to_s(36)
12
12
  @config_var = config_var
13
13
  end
14
14
 
@@ -19,13 +19,9 @@ module Decidim
19
19
  #
20
20
  # Returns nothing.
21
21
  def call
22
- styles = AwesomeConfig.find_or_initialize_by(var: @config_var, organization: @organization)
23
- styles.value = {} unless styles.value.is_a? Hash
24
- # TODO: prevent (unlikely) colisions with exisiting values
25
- styles.value[@ident] = ""
26
- styles.save!
22
+ create_hash_config!("")
27
23
 
28
- broadcast(:ok, @ident)
24
+ broadcast(:ok, ident)
29
25
  rescue StandardError => e
30
26
  broadcast(:invalid, e.message)
31
27
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module Admin
6
+ class DestroyAuthorizationGroup < Command
7
+ include NeedsConstraintHelpers
8
+ # Public: Initializes the command.
9
+ #
10
+ # key - the key to destroy inside force_authorizations
11
+ # organization - the organization to which the config belongs
12
+ def initialize(key, organization, config_var = :force_authorizations)
13
+ @ident = key
14
+ @organization = organization
15
+ @config_var = config_var
16
+ end
17
+
18
+ # Executes the command. Broadcasts these events:
19
+ #
20
+ # - :ok when everything is valid.
21
+ # - :invalid if we couldn't proceed.
22
+ #
23
+ # Returns nothing.
24
+ def call
25
+ return broadcast(:invalid, "Not a hash") unless find_var&.value.is_a?(Hash)
26
+ return broadcast(:invalid, "#{ident} key invalid") unless find_var.value.has_key?(ident)
27
+
28
+ destroy_hash_ident!
29
+
30
+ broadcast(:ok, ident)
31
+ rescue StandardError => e
32
+ broadcast(:invalid, e.message)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -4,14 +4,15 @@ module Decidim
4
4
  module DecidimAwesome
5
5
  module Admin
6
6
  class DestroyCustomRedirect < Command
7
+ include NeedsConstraintHelpers
7
8
  # Public: Initializes the command.
8
9
  #
9
- # item - the redirections item to destroy
10
+ # item - the redirects item to destroy
10
11
  # organization
11
12
  def initialize(item, organization)
12
13
  @item = item
13
14
  @organization = organization
14
- @redirections = AwesomeConfig.find_by(var: :custom_redirects, organization:)
15
+ @config_var = :custom_redirects
15
16
  end
16
17
 
17
18
  # Executes the command. Broadcasts these events:
@@ -23,23 +24,23 @@ module Decidim
23
24
  def call
24
25
  return broadcast(:invalid) unless url_exists?
25
26
 
26
- redirections.value&.except!(item.origin)
27
- redirections.save!
27
+ find_var.value&.except!(item.origin)
28
+ find_var.save!
28
29
 
29
- broadcast(:ok, @item)
30
+ broadcast(:ok, item)
30
31
  rescue StandardError => e
31
32
  broadcast(:invalid, e.message)
32
33
  end
33
34
 
34
35
  private
35
36
 
36
- attr_reader :organization, :item, :redirections
37
+ attr_reader :item
37
38
 
38
39
  def url_exists?
39
- return false unless redirections
40
- return false unless redirections.value.is_a? Hash
40
+ return false unless find_var
41
+ return false unless find_var.value.is_a? Hash
41
42
 
42
- redirections.value[item.origin].present?
43
+ find_var.value[item.origin].present?
43
44
  end
44
45
  end
45
46
  end
@@ -4,6 +4,7 @@ module Decidim
4
4
  module DecidimAwesome
5
5
  module Admin
6
6
  class DestroyMenuHack < Command
7
+ include NeedsConstraintHelpers
7
8
  # Public: Initializes the command.
8
9
  #
9
10
  # item - the menu item to destroy
@@ -11,7 +12,7 @@ module Decidim
11
12
  def initialize(item, menu_name, organization)
12
13
  @item = item
13
14
  @organization = organization
14
- @menu = AwesomeConfig.find_by(var: menu_name, organization:)
15
+ @config_var = menu_name
15
16
  end
16
17
 
17
18
  # Executes the command. Broadcasts these events:
@@ -23,8 +24,8 @@ module Decidim
23
24
  def call
24
25
  return broadcast(:invalid) unless url_exists?
25
26
 
26
- menu.value&.reject! { |i| i["url"] == item.url }
27
- menu.save!
27
+ find_var.value&.reject! { |i| i["url"] == item.url }
28
+ find_var.save!
28
29
 
29
30
  broadcast(:ok, @item)
30
31
  rescue StandardError => e
@@ -33,13 +34,13 @@ module Decidim
33
34
 
34
35
  private
35
36
 
36
- attr_reader :organization, :item, :menu
37
+ attr_reader :organization, :item
37
38
 
38
39
  def url_exists?
39
- return false unless menu
40
- return false unless menu.value.is_a? Array
40
+ return false unless find_var
41
+ return false unless find_var.value.is_a? Array
41
42
 
42
- menu.value&.detect { |i| i["url"] == item.url }
43
+ find_var.value&.detect { |i| i["url"] == item.url }
43
44
  end
44
45
  end
45
46
  end