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
@@ -0,0 +1,100 @@
1
+ NATIVE_NAME = 简体中文
2
+ ENGLISH_NAME = Chinese
3
+
4
+ addOption = 新增选项
5
+ number = 数字
6
+ allFieldsRemoved = 所有字段已删除
7
+ allowSelect = 允许选择
8
+ autocomplete = 自动完成
9
+ button = 按钮
10
+ cannotBeEmpty = 此字段不能为空
11
+ checkboxGroup = 复选框组
12
+ checkbox = 复选框
13
+ checkboxes = 复选框
14
+ class = CSS样式
15
+ clearAllMessage = 您确定要清空所有字段吗?
16
+ clear = 清除所有
17
+ close = 关闭
18
+ content = 内容
19
+ copy = 复制
20
+ copyButtonTooltip=复制
21
+ dateField = 日期字段
22
+ description = 帮助信息
23
+ descriptionField = 描述
24
+ devMode = 开发者模式
25
+ editNames = 编辑名称
26
+ editorTitle = 表单元素
27
+ editXML = 编辑XML
28
+ fieldDeleteWarning: false
29
+ fieldVars = 字段变量
30
+ fieldNonEditable = 此字段不允许修改。
31
+ fieldRemoveWarning = 您确定要移除此字段吗?
32
+ fileUpload = 文件上传
33
+ formUpdated = 表单已更新
34
+ getStarted = 请从右边拖拽原件到此为止。
35
+ header = 表头
36
+ hide = 编辑
37
+ hidden = 隐藏域
38
+ label = 标签
39
+ labelEmpty = 标签字段不能为空
40
+ limitRole = 角色受限
41
+ mandatory = 强制填写
42
+ maxlength = 最大长度
43
+ minOptionMessage = 此字段至少需要选择两项
44
+ name = 名称
45
+ no = 否
46
+ off = 关
47
+ on = 开
48
+ option = 选项
49
+ optional = 可选
50
+ optionEmpty = 请输入选择
51
+ paragraph = 段落
52
+ placeholder = 占位符
53
+ placeholder.value = 值
54
+ placeholder.label = 标签
55
+ placeholder.text = 请输入文字
56
+ placeholder.textarea = 请输入文字
57
+ placeholder.email = 请输入邮件地址
58
+ placeholder.placeholder = 占位符
59
+ placeholder.className = 输入类名,以空格分开
60
+ placeholder.password = 请输入密码
61
+ preview = 预览
62
+ radioGroup = 单选组
63
+ radio = 单选框
64
+ removeMessage = 移除元件
65
+ remove = ×
66
+ required = 必填
67
+ richText = 富文本框
68
+ roles = 访问
69
+ save = 保存
70
+ selectOptions = 选项
71
+ select = 选择
72
+ selectColor = 选择颜色
73
+ selectionsMessage = 允许多选
74
+ size = 大小
75
+ sizes = 大小
76
+ sizes.xs = 最小
77
+ sizes.sm = 小
78
+ sizes.m = 中
79
+ sizes.lg = 大
80
+ style = 样式
81
+ styles = 样式
82
+ styles.btn = 按钮样式
83
+ styles.btn.default = 默认样式
84
+ styles.btn.danger = 危险
85
+ styles.btn.info = 一般信息
86
+ styles.btn.primary = 主样式
87
+ styles.btn.success = 成功
88
+ styles.btn.warning = 警告
89
+ subtype = 格式
90
+ text = 单行文本
91
+ password = 密码
92
+ email = 邮箱
93
+ color = 颜色
94
+ tel = 电话
95
+ textArea = 多行文本
96
+ toggle = 弹出提示
97
+ warning = 警告!
98
+ viewXML = </>
99
+ viewJSON = { }
100
+ yes = 是
@@ -0,0 +1,94 @@
1
+ NATIVE_NAME = 繁體中文(台灣)
2
+ ENGLISH_NAME = Chinese (Taiwan)
3
+
4
+ addOption = 新增選項
5
+ allFieldsRemoved = 所有欄位已移除
6
+ allowSelect = 允許選擇
7
+ autocomplete = 自動完成
8
+ button = 按鈕
9
+ cannotBeEmpty = 此欄位不能是空白
10
+ checkboxGroup = 核取方塊群組
11
+ checkbox = 核取方塊
12
+ checkboxes = 核取方塊組
13
+ class = CSS 類別
14
+ clearAllMessage = 你確定要移除所有的項目嗎?
15
+ clear = 清除
16
+ close = 關閉
17
+ content = 內容
18
+ copy = 複製到剪貼簿
19
+ dateField = 日期欄位
20
+ description = 描述
21
+ descriptionField = 描述欄位
22
+ devMode = 開發者模式
23
+ editNames = 編輯名稱
24
+ editorTitle = 表單元件
25
+ editXML = 編輯 XML
26
+ fieldDeleteWarning: false
27
+ fieldVars = 欄位變數
28
+ fieldNonEditable = 此欄位無法修改。
29
+ fieldRemoveWarning = 你確定要移除此欄位嗎?
30
+ fileUpload = 檔案上傳
31
+ formUpdated = 已更新表單
32
+ getStarted = 請拖拉表單元件到此區域。
33
+ header = 標頭
34
+ hide = 隱藏
35
+ hidden = 隱藏輸入欄位
36
+ label = 標籤
37
+ labelEmpty = 標籤欄位名稱不能是空白的
38
+ limitRole = 限制可讀取的角色 :
39
+ mandatory = 強制性的
40
+ maxlength = 最大長度
41
+ minOptionMessage = 此欄位至少要兩個選項
42
+ name = 名稱
43
+ no = 否
44
+ off = 關
45
+ on = 開
46
+ option = 選項
47
+ optional = 可選的
48
+ optionEmpty = 請填入選項值
49
+ paragraph = 段落
50
+ placeholder = 占位符
51
+ placeholder.value = 值
52
+ placeholder.label = 標籤
53
+ placeholder.text = 請輸入一些文字
54
+ placeholder.textarea = 請輸入文字
55
+ placeholder.email = 請輸入你的電子郵件
56
+ placeholder.placeholder = 占位符
57
+ placeholder.className = 多個類別時,請用空白隔開即可。
58
+ placeholder.password = 請輸入密碼
59
+ preview = 預覽
60
+ radioGroup = 單選群組
61
+ radio = 單選
62
+ removeMessage = 移除元件
63
+ remove = &#215;
64
+ required = 必要的
65
+ richText = 文字編輯框
66
+ roles = 存取
67
+ save = 儲存
68
+ selectOptions = 選項
69
+ select = 選擇
70
+ selectColor = 選擇顏色
71
+ selectionsMessage = 允許多重選擇
72
+ size = 大小
73
+ sizes = 大小
74
+ sizes.xs = 最小
75
+ sizes.sm = 小
76
+ sizes.m = 中
77
+ sizes.lg = 大
78
+ style = 樣式
79
+ styles = 樣式
80
+ styles.btn = 按鈕樣式
81
+ styles.btn.default = Default
82
+ styles.btn.danger = Danger
83
+ styles.btn.info = Info
84
+ styles.btn.primary = Primary
85
+ styles.btn.success = Success
86
+ styles.btn.warning = Warning
87
+ subtype = 格式
88
+ text = 文字欄位
89
+ textArea = 文字區塊
90
+ toggle = 彈出提示
91
+ warning = 警告!
92
+ viewXML = 顯示 XML
93
+ viewJSON = { }
94
+ yes = 是
@@ -0,0 +1,83 @@
1
+ // http://www.hashcash.org/docs/hashcash.html
2
+ // <input type="hidden" name="hashcash" data-hashcash="{resource: 'site.example', bits: 16}"/>
3
+
4
+ import Stamp from "src/vendor/stamp"
5
+
6
+ export default class Hashcash {
7
+ static default = {
8
+ version: 1,
9
+ bits: 20,
10
+ extension: null,
11
+ }
12
+
13
+ constructor(input) {
14
+ this.options = JSON.parse(input.getAttribute("data-hashcash"))
15
+ this.input = input
16
+ this.disableParentForm()
17
+ this.input.dispatchEvent(new CustomEvent("hashcash:mint", {bubbles: true}))
18
+
19
+ this.mint((stamp) => {
20
+ this.input.value = stamp.toString()
21
+ console.log("Hashcash stamp: ", stamp)
22
+ console.log("Hashcash input: ", this.input.value)
23
+ this.enableParentForm()
24
+ this.input.dispatchEvent(new CustomEvent("hashcash:minted", {bubbles: true, detail: {stamp: stamp}}))
25
+ })
26
+ }
27
+
28
+ static setup() {
29
+ if (document.readyState != "loading") {
30
+ var input = document.querySelector("input#hashcash")
31
+ input && new Hashcash(input)
32
+ } else
33
+ document.addEventListener("DOMContentLoaded", Hashcash.setup )
34
+ }
35
+
36
+ setSubmitText(submit, text) {
37
+ if (!text) {
38
+ return
39
+ }
40
+ if (submit.tagName == "BUTTON") {
41
+ !submit.originalValue && (submit.originalValue = submit.innerHTML)
42
+ submit.innerHTML = text
43
+ } else {
44
+ !submit.originalValue && (submit.originalValue = submit.value)
45
+ submit.value = text
46
+ }
47
+ }
48
+
49
+ disableParentForm() {
50
+ this.input.form.querySelectorAll("[type=submit]").forEach((submit) => {
51
+ this.setSubmitText(submit, this.options["waiting_message"])
52
+ submit.disabled = true
53
+ })
54
+ }
55
+
56
+ enableParentForm() {
57
+ this.input.form.querySelectorAll("[type=submit]").forEach((submit) => {
58
+ this.setSubmitText(submit, submit.originalValue)
59
+ submit.disabled = null
60
+ })
61
+ }
62
+
63
+ mint(callback) {
64
+ var options = this.options
65
+ var resource = this.options.resource
66
+ // Format date to YYMMDD
67
+ var date = new Date
68
+ var year = date.getFullYear().toString()
69
+ year = year.slice(year.length - 2, year.length)
70
+ var month = (date.getMonth() + 1).toString().padStart(2, "0")
71
+ var day = date.getDate().toString().padStart(2, "0")
72
+
73
+ var stamp = new Stamp(
74
+ options.version || Hashcash.default.version,
75
+ options.bits || Hashcash.default.bits,
76
+ options.date || year + month + day,
77
+ resource,
78
+ options.extension || Hashcash.default.extension,
79
+ options.rand || Math.random().toString(36).substr(2, 10),
80
+ )
81
+ return stamp.work(callback)
82
+ }
83
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Secure Hash Algorithm (SHA1)
3
+ * http://www.webtoolkit.info/
4
+ **/
5
+ export default function SHA1(msg) {
6
+ var blockstart;
7
+ var i, j;
8
+ var W = new Array(80);
9
+ var H0 = 0x67452301;
10
+ var H1 = 0xEFCDAB89;
11
+ var H2 = 0x98BADCFE;
12
+ var H3 = 0x10325476;
13
+ var H4 = 0xC3D2E1F0;
14
+ var A, B, C, D, E;
15
+ var temp;
16
+ msg = Utf8Encode(msg);
17
+ var msg_len = msg.length;
18
+ var word_array = new Array();
19
+ for (i = 0; i < msg_len - 3; i += 4) {
20
+ j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 |
21
+ msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3);
22
+ word_array.push(j);
23
+ }
24
+ switch (msg_len % 4) {
25
+ case 0:
26
+ i = 0x080000000;
27
+ break;
28
+ case 1:
29
+ i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000;
30
+ break;
31
+ case 2:
32
+ i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000;
33
+ break;
34
+ case 3:
35
+ i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80;
36
+ break;
37
+ }
38
+ word_array.push(i);
39
+ while ((word_array.length % 16) != 14) word_array.push(0);
40
+ word_array.push(msg_len >>> 29);
41
+ word_array.push((msg_len << 3) & 0x0ffffffff);
42
+ for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
43
+ for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i];
44
+ for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
45
+ A = H0;
46
+ B = H1;
47
+ C = H2;
48
+ D = H3;
49
+ E = H4;
50
+ for (i = 0; i <= 19; i++) {
51
+ temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
52
+ E = D;
53
+ D = C;
54
+ C = rotate_left(B, 30);
55
+ B = A;
56
+ A = temp;
57
+ }
58
+ for (i = 20; i <= 39; i++) {
59
+ temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
60
+ E = D;
61
+ D = C;
62
+ C = rotate_left(B, 30);
63
+ B = A;
64
+ A = temp;
65
+ }
66
+ for (i = 40; i <= 59; i++) {
67
+ temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
68
+ E = D;
69
+ D = C;
70
+ C = rotate_left(B, 30);
71
+ B = A;
72
+ A = temp;
73
+ }
74
+ for (i = 60; i <= 79; i++) {
75
+ temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
76
+ E = D;
77
+ D = C;
78
+ C = rotate_left(B, 30);
79
+ B = A;
80
+ A = temp;
81
+ }
82
+ H0 = (H0 + A) & 0x0ffffffff;
83
+ H1 = (H1 + B) & 0x0ffffffff;
84
+ H2 = (H2 + C) & 0x0ffffffff;
85
+ H3 = (H3 + D) & 0x0ffffffff;
86
+ H4 = (H4 + E) & 0x0ffffffff;
87
+ }
88
+ return [H0, H1, H2, H3, H4]
89
+ }
90
+
91
+ export function hexSha1(msg) {
92
+ var array = SHA1(msg)
93
+ return cvt_hex(array[0]) + cvt_hex(array[1]) + cvt_hex(array[2]) + cvt_hex(array3) + cvt_hex(array[4])
94
+ }
95
+
96
+ function rotate_left(n, s) {
97
+ var t4 = (n << s) | (n >>> (32 - s));
98
+ return t4;
99
+ };
100
+
101
+ function lsb_hex(val) {
102
+ var str = '';
103
+ var i;
104
+ var vh;
105
+ var vl;
106
+ for (i = 0; i <= 6; i += 2) {
107
+ vh = (val >>> (i * 4 + 4)) & 0x0f;
108
+ vl = (val >>> (i * 4)) & 0x0f;
109
+ str += vh.toString(16) + vl.toString(16);
110
+ }
111
+ return str;
112
+ };
113
+
114
+ function cvt_hex(val) {
115
+ var str = '';
116
+ var i;
117
+ var v;
118
+ for (i = 7; i >= 0; i--) {
119
+ v = (val >>> (i * 4)) & 0x0f;
120
+ str += v.toString(16);
121
+ }
122
+ return str;
123
+ };
124
+
125
+ function Utf8Encode(string) {
126
+ string = string.replace(/\r\n/g, '\n');
127
+ var utftext = '';
128
+ for (var n = 0; n < string.length; n++) {
129
+ var c = string.charCodeAt(n);
130
+ if (c < 128) {
131
+ utftext += String.fromCharCode(c);
132
+ } else if ((c > 127) && (c < 2048)) {
133
+ utftext += String.fromCharCode((c >> 6) | 192);
134
+ utftext += String.fromCharCode((c & 63) | 128);
135
+ } else {
136
+ utftext += String.fromCharCode((c >> 12) | 224);
137
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
138
+ utftext += String.fromCharCode((c & 63) | 128);
139
+ }
140
+ }
141
+ return utftext;
142
+ };
143
+
@@ -0,0 +1,50 @@
1
+ import SHA1 from "src/vendor/sha1"
2
+
3
+ export default class Stamp {
4
+ constructor(version, bits, date, resource, extension, rand, counter = 0) {
5
+ this.version = version
6
+ this.bits = bits
7
+ this.date = date
8
+ this.resource = resource
9
+ this.extension = extension
10
+ this.rand = rand
11
+ this.counter = counter
12
+ }
13
+
14
+ static parse(string) {
15
+ const args = string.split(":")
16
+ return new Stamp(args[0], args[1], args[2], args[3], args[4], args[5], args[6])
17
+ }
18
+
19
+ toString() {
20
+ return [this.version, this.bits, this.date, this.resource, this.extension, this.rand, this.counter].join(":")
21
+ }
22
+
23
+ // Trigger the given callback when the problem is solved.
24
+ // In order to not freeze the page, setTimeout is called every 100ms to let some CPU to other tasks.
25
+ work(callback) {
26
+ this.startClock()
27
+ const timer = performance.now()
28
+ while (!this.check())
29
+ if (this.counter++ && performance.now() - timer > 100)
30
+ return setTimeout(this.work.bind(this), 0, callback)
31
+ this.stopClock()
32
+ callback(this)
33
+ }
34
+
35
+ check() {
36
+ const array = SHA1(this.toString())
37
+ return array[0] >> (160-this.bits) == 0
38
+ }
39
+
40
+ startClock() {
41
+ this.startedAt || (this.startedAt = performance.now())
42
+ }
43
+
44
+ stopClock() {
45
+ this.endedAt || (this.endedAt = performance.now())
46
+ const duration = this.endedAt - this.startedAt
47
+ const speed = Math.round(this.counter * 1000 / duration)
48
+ console.debug("Hashcash " + this.toString() + " minted in " + duration + "ms (" + speed + " per seconds)")
49
+ }
50
+ }
@@ -5,9 +5,14 @@
5
5
 
6
6
  .awesome-edit-config {
7
7
  .scoped_styles_container,
8
- .proposal_custom_fields_container {
8
+ .proposal_custom_fields_container,
9
+ .force_authorization_container {
9
10
  @apply bg-background;
10
11
 
12
+ .editor-container {
13
+ @apply bg-white;
14
+ }
15
+
11
16
  &.private {
12
17
  @apply outline-2 outline-[#fca5a5] outline-dotted;
13
18
  }
@@ -33,6 +33,11 @@
33
33
  color: #fff;
34
34
  }
35
35
 
36
+ &.application_context {
37
+ background-color: #007bff;
38
+ color: #fff;
39
+ }
40
+
36
41
  &.constraint {
37
42
  &-none {
38
43
  background-color: #ff3000;
@@ -15,8 +15,7 @@
15
15
  @apply bg-background mr-2;
16
16
  }
17
17
 
18
- border-top-left-radius: 5px;
19
- border-top-right-radius: 5px;
18
+ @apply rounded-tl-[5px] rounded-tr-[5px];
20
19
 
21
20
  svg {
22
21
  @apply fill-black;
@@ -1,17 +1,7 @@
1
1
  .awesome_autosave-notice {
2
- background-color: rgb(var(--success-rgb) / 90%);
3
- position: fixed;
4
- top: 90%;
5
- left: 50%;
6
- transform: translate(-50%, -50%);
7
- padding: 1em 2em;
8
- border-radius: 4px;
9
- border: 1px solid var(--success);
10
- font-weight: 600;
11
- color: white;
12
- z-index: 1000;
2
+ @apply bg-success/90 fixed top-[2%] right-[2%] p-4 rounded border border-success font-semibold text-white z-[1000];
13
3
 
14
4
  &.error {
15
- background-color: rgb(var(--alert-rgb) / 90%);
5
+ @apply bg-alert/90;
16
6
  }
17
7
  }
@@ -31,7 +31,7 @@ module Decidim
31
31
  end
32
32
 
33
33
  def time_ago
34
- I18n.t("decidim.decidim_awesome.admin.maintenance.private_data.time_ago", time: time_ago_in_words(last_date)) if last_date
34
+ I18n.t("decidim.decidim_awesome.admin.private_data.private_data.time_ago", time: time_ago_in_words(last_date)) if last_date
35
35
  end
36
36
 
37
37
  def destroyable?
@@ -63,7 +63,7 @@ module Decidim
63
63
  return if destroyable?
64
64
  return if last_date
65
65
 
66
- I18n.t("decidim.decidim_awesome.admin.maintenance.private_data.done")
66
+ I18n.t("decidim.decidim_awesome.admin.private_data.private_data.done")
67
67
  end
68
68
  end
69
69
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class SpaceConstraintFinder
6
+ def initialize(config_var, participatory_space)
7
+ @config_var = config_var
8
+ @participatory_space = participatory_space
9
+ end
10
+
11
+ attr_reader :participatory_space, :config_var
12
+
13
+ def query
14
+ set_base_query
15
+ add_space_specific_conditions
16
+ end
17
+
18
+ private
19
+
20
+ def set_base_query
21
+ @query = Decidim::DecidimAwesome::AwesomeConfig
22
+ .where("var LIKE ?", "#{config_var}_%")
23
+ .where(organization: participatory_space.organization)
24
+ .joins(:constraints)
25
+ .where("decidim_awesome_config_constraints.settings @> ?", { participatory_space_manifest: manifest_key }.to_json)
26
+ end
27
+
28
+ def add_space_specific_conditions
29
+ @query.where(
30
+ "(decidim_awesome_config_constraints.settings ->> 'participatory_space_slug' = ? OR " \
31
+ "decidim_awesome_config_constraints.settings ->> 'participatory_space_slug' IS NULL)",
32
+ participatory_space.try(:slug) || participatory_space.id.to_s
33
+ )
34
+ end
35
+
36
+ def manifest_key
37
+ return participatory_space.manifest.name if participatory_space.respond_to?(:manifest)
38
+
39
+ :process_groups
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module DecidimAwesome
5
5
  module Proposals
6
- # Adds one custom field per column in export if custom fields are activted
6
+ # Adds one custom field per column in export if custom fields are activated
7
7
  # Adds vote weights
8
8
  module ProposalSerializerMethods
9
9
  extend ActiveSupport::Concern
@@ -17,7 +17,8 @@ module Decidim
17
17
  return @custom_config if @custom_config
18
18
 
19
19
  @custom_config = Config.new(proposal.organization)
20
- @custom_config.context_from_component(proposal.component)
20
+ @custom_config.context_from_component!(proposal.component)
21
+ @custom_config.application_context!(current_user: proposal.creator)
21
22
  @custom_config
22
23
  end
23
24
 
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class AccessAuthorizationService
6
+ def initialize(user, organization, authorization_groups = [])
7
+ @user = user
8
+ @organization = organization
9
+ @available_handlers = organization.available_authorizations & Decidim.authorization_workflows.map(&:name)
10
+ @authorization_groups = authorization_groups.filter_map do |group|
11
+ group.filter_map do |handler, options|
12
+ next unless @available_handlers.include?(handler)
13
+
14
+ [handler, options]
15
+ end.to_h
16
+ end.compact_blank
17
+ end
18
+
19
+ attr_reader :user, :organization, :authorization_groups
20
+
21
+ def granted?
22
+ return false unless user
23
+ return true if authorization_groups.blank?
24
+
25
+ # if one group is authorized that's ok
26
+ # inside a group, all adapters must be authorized
27
+ authorization_groups.detect do |group|
28
+ statuses = authorization_statuses_for(group)
29
+ next if statuses.blank?
30
+
31
+ statuses.all? { |status| status == :ok }
32
+ end
33
+ end
34
+
35
+ def authorization_handlers
36
+ @authorization_handlers ||= authorization_groups.flat_map do |group|
37
+ next unless group.is_a?(Hash)
38
+
39
+ group.keys
40
+ end.uniq
41
+ end
42
+
43
+ def adapters
44
+ @authorizations ||= adapters_for(authorization_handlers)
45
+ end
46
+
47
+ def authorization_status(method)
48
+ authorization_statuses_for({ method => authorization_groups.flat_map { |group| group[method] } }).first
49
+ end
50
+
51
+ private
52
+
53
+ def adapters_for(handlers)
54
+ Decidim::Verifications::Adapter.from_collection(
55
+ handlers & organization.available_authorizations & Decidim.authorization_workflows.map(&:name)
56
+ )
57
+ end
58
+
59
+ def authorization_statuses_for(group)
60
+ @authorization_statuses_for ||= {}
61
+
62
+ adapters_for(group.keys).map do |adapter|
63
+ next @authorization_statuses_for[adapter.name] if @authorization_statuses_for.has_key?(adapter.name)
64
+
65
+ @authorization_statuses_for[adapter.name] = begin
66
+ authorization = Decidim::Verifications::Authorizations.new(
67
+ organization:,
68
+ user:,
69
+ name: adapter.name,
70
+ granted: true
71
+ ).first
72
+
73
+ adapter.authorize(authorization, group[adapter.name]["options"], nil, nil)&.first
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end