decidim-core 0.30.8 → 0.30.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/cells/decidim/content_blocks/html_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/section_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/summary_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/two_pane_section_cell.rb +2 -2
- data/app/cells/decidim/data_consent/category.erb +5 -5
- data/app/cells/decidim/upload_modal_cell.rb +5 -0
- data/app/controllers/decidim/download_your_data_controller.rb +1 -1
- data/app/controllers/decidim/notifications_subscriptions_controller.rb +8 -0
- data/app/controllers/decidim/private_downloads_controller.rb +29 -0
- data/app/models/decidim/attachment.rb +20 -2
- data/app/models/decidim/authorization.rb +7 -0
- data/app/models/decidim/private_download.rb +61 -0
- data/app/models/decidim/private_export.rb +6 -0
- data/app/packs/src/decidim/sw/push-permissions.js +47 -12
- data/app/services/decidim/notifications_subscriptions_persistor.rb +6 -0
- data/app/services/decidim/push_subscription_endpoint_validator.rb +34 -0
- data/app/services/decidim/send_push_notification.rb +5 -1
- data/app/views/decidim/notifications_settings/show.html.erb +5 -5
- data/config/locales/ca-IT.yml +1 -0
- data/config/locales/ca.yml +1 -0
- data/config/locales/cs.yml +2 -0
- data/config/locales/en.yml +1 -0
- data/config/locales/es-MX.yml +1 -0
- data/config/locales/es-PY.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/locales/eu.yml +1 -0
- data/config/locales/fi.yml +2 -2
- data/config/locales/fr-CA.yml +1 -0
- data/config/locales/fr.yml +1 -0
- data/config/locales/it.yml +10 -0
- data/config/locales/pt-BR.yml +1 -1
- data/config/locales/sk.yml +1417 -0
- data/config/locales/sv.yml +1 -0
- data/config/routes.rb +1 -0
- data/lib/decidim/core/version.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5817376e17111569ffa304fd748355de958fdb6020c5fec8f49d913707b43e9
|
|
4
|
+
data.tar.gz: '0785c351a8efe4e5740a7551bf6994a98db61257e29b8df325823a790061385b'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cf18599b257a5ffea8442bcba6ea817eddecfa48e7a2150fb0ccf00ee024c267da283c333ee5c2eedb89441c7deea081bc89fe3f5af3ce55d5e27b13ab3a3484
|
|
7
|
+
data.tar.gz: f56a6474372376c00de0e4589d9dcc733a311a5302aedc4384064cdb4ec7048b0761360f616d5bd0d515068757776691c0bb951aec53df944742015678287042
|
|
@@ -5,11 +5,11 @@ module Decidim
|
|
|
5
5
|
module StaticPage
|
|
6
6
|
class TwoPaneSectionCell < Decidim::ViewModel
|
|
7
7
|
def left_column
|
|
8
|
-
translated_attribute(model.settings.left_column)
|
|
8
|
+
decidim_sanitize_editor_admin(translated_attribute(model.settings.left_column))
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def right_column
|
|
12
|
-
translated_attribute(model.settings.right_column)
|
|
12
|
+
decidim_sanitize_editor_admin(translated_attribute(model.settings.right_column))
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
<%= icon "close-line", class: "cookies__category-toggle-icon" %>
|
|
14
14
|
</label>
|
|
15
15
|
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</h3>
|
|
16
|
+
<h3 id="accordion-title-<%= category[:slug] %>" class="cookies__category-trigger-title">
|
|
17
|
+
<%= category[:title] %>
|
|
18
|
+
</h3>
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
<div id="accordion-trigger-<%= category[:slug] %>" role="group" data-controls="accordion-panel-<%= category[:slug] %>" aria-labelledby="accordion-title-<%= category[:slug] %>">
|
|
21
|
+
<span aria-hidden="true">
|
|
22
22
|
<%= icon "arrow-down-s-line", class: "cookies__category-trigger-arrow" %>
|
|
23
23
|
<%= icon "arrow-up-s-line", class: "cookies__category-trigger-arrow" %>
|
|
24
24
|
</span>
|
|
@@ -177,6 +177,11 @@ module Decidim
|
|
|
177
177
|
|
|
178
178
|
def file_attachment_path(attachment)
|
|
179
179
|
return unless attachment
|
|
180
|
+
|
|
181
|
+
if attachment.respond_to?(:record) && attachment.record.is_a?(Decidim::Authorization) && attachment.name.to_s == "verification_attachment"
|
|
182
|
+
return decidim.private_download_path(Decidim::PrivateDownload.for(attachment.record, attachment_name: attachment.name).token)
|
|
183
|
+
end
|
|
184
|
+
|
|
180
185
|
return Rails.application.routes.url_helpers.rails_blob_url(attachment, only_path: true) if attachment.is_a? ActiveStorage::Blob
|
|
181
186
|
|
|
182
187
|
if attachment.try(:attached?)
|
|
@@ -50,7 +50,7 @@ module Decidim
|
|
|
50
50
|
flash[:error] = t("decidim.account.download_your_data_export.export_expired")
|
|
51
51
|
redirect_to download_your_data_path
|
|
52
52
|
elsif private_export.file.attached?
|
|
53
|
-
redirect_to
|
|
53
|
+
redirect_to private_download_path(Decidim::PrivateDownload.for(private_export, attachment_name: :file).token)
|
|
54
54
|
else
|
|
55
55
|
flash[:error] = t("decidim.account.download_your_data_export.file_no_exists")
|
|
56
56
|
redirect_to download_your_data_path
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module Decidim
|
|
4
4
|
# The controller to handle the subscriptions to push notifications
|
|
5
5
|
class NotificationsSubscriptionsController < Decidim::ApplicationController
|
|
6
|
+
rescue_from Decidim::NotificationsSubscriptionsPersistor::UnsupportedPushSubscriptionEndpointError, with: :unsupported_browser
|
|
7
|
+
|
|
6
8
|
def create
|
|
7
9
|
Decidim::NotificationsSubscriptionsPersistor.new(current_user).add_subscription(params)
|
|
8
10
|
head :ok
|
|
@@ -12,5 +14,11 @@ module Decidim
|
|
|
12
14
|
Decidim::NotificationsSubscriptionsPersistor.new(current_user).delete_subscription(params[:auth])
|
|
13
15
|
head :ok
|
|
14
16
|
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def unsupported_browser
|
|
21
|
+
render json: { error: I18n.t("notifications_settings.show.push_notifications_unsupported_browser", scope: "decidim") }, status: :unprocessable_entity
|
|
22
|
+
end
|
|
15
23
|
end
|
|
16
24
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
class PrivateDownloadsController < Decidim::ApplicationController
|
|
5
|
+
before_action :authenticate_user!
|
|
6
|
+
|
|
7
|
+
def show
|
|
8
|
+
return head :not_found unless private_download.attached?
|
|
9
|
+
return head :not_found unless private_download.authorized_for?(current_user)
|
|
10
|
+
|
|
11
|
+
disposition = private_download.attachment.content_type.start_with?("image/") ? :inline : :attachment
|
|
12
|
+
|
|
13
|
+
send_data(
|
|
14
|
+
private_download.attachment.download,
|
|
15
|
+
filename: private_download.attachment.filename.to_s,
|
|
16
|
+
type: private_download.attachment.content_type,
|
|
17
|
+
disposition:
|
|
18
|
+
)
|
|
19
|
+
rescue Decidim::PrivateDownload::InvalidTokenError
|
|
20
|
+
head :not_found
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def private_download
|
|
26
|
+
@private_download ||= Decidim::PrivateDownload.from_token(params[:id])
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -88,7 +88,7 @@ module Decidim
|
|
|
88
88
|
# Returns String.
|
|
89
89
|
def file_type
|
|
90
90
|
if file?
|
|
91
|
-
|
|
91
|
+
file.filename.extension&.downcase
|
|
92
92
|
elsif link?
|
|
93
93
|
"link"
|
|
94
94
|
end
|
|
@@ -100,7 +100,13 @@ module Decidim
|
|
|
100
100
|
def url
|
|
101
101
|
@url ||=
|
|
102
102
|
if file?
|
|
103
|
-
|
|
103
|
+
if private_download_required?
|
|
104
|
+
Decidim::Core::Engine.routes.url_helpers.private_download_path(
|
|
105
|
+
Decidim::PrivateDownload.for(self, attachment_name: :file).token
|
|
106
|
+
)
|
|
107
|
+
else
|
|
108
|
+
attached_uploader(:file).url
|
|
109
|
+
end
|
|
104
110
|
elsif link?
|
|
105
111
|
link
|
|
106
112
|
end
|
|
@@ -144,5 +150,17 @@ module Decidim
|
|
|
144
150
|
|
|
145
151
|
attached_to.can_participate?(user)
|
|
146
152
|
end
|
|
153
|
+
|
|
154
|
+
def private_download_authorized?(user, requested_attachment_name)
|
|
155
|
+
return false unless requested_attachment_name.to_s == "file"
|
|
156
|
+
|
|
157
|
+
can_participate?(user)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def private_download_required?
|
|
161
|
+
return attached_to.private_space? if attached_to.respond_to?(:private_space?)
|
|
162
|
+
|
|
163
|
+
attached_to.respond_to?(:component) && attached_to.component&.private_non_transparent_space?
|
|
164
|
+
end
|
|
147
165
|
end
|
|
148
166
|
end
|
|
@@ -91,6 +91,13 @@ module Decidim
|
|
|
91
91
|
Decidim::AuthorizationTransfer.perform!(self, handler)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def private_download_authorized?(user, requested_attachment_name)
|
|
95
|
+
return false unless requested_attachment_name.to_s == "verification_attachment"
|
|
96
|
+
return true if user&.admin? && user.organization == organization
|
|
97
|
+
|
|
98
|
+
user == self.user
|
|
99
|
+
end
|
|
100
|
+
|
|
94
101
|
private
|
|
95
102
|
|
|
96
103
|
def active_handler?
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
class PrivateDownload
|
|
5
|
+
class InvalidTokenError < StandardError; end
|
|
6
|
+
|
|
7
|
+
VERIFIER_PURPOSE = :private_download
|
|
8
|
+
|
|
9
|
+
def self.for(record, attachment_name:)
|
|
10
|
+
new(record:, attachment_name:)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.from_token(token)
|
|
14
|
+
payload = verifier.verify(token, purpose: VERIFIER_PURPOSE).with_indifferent_access
|
|
15
|
+
record = GlobalID::Locator.locate(payload[:gid])
|
|
16
|
+
|
|
17
|
+
raise InvalidTokenError if record.blank?
|
|
18
|
+
|
|
19
|
+
new(record:, attachment_name: payload[:attachment_name])
|
|
20
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature, TypeError
|
|
21
|
+
raise InvalidTokenError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.verifier
|
|
25
|
+
@verifier ||= ActiveSupport::MessageVerifier.new(Rails.application.secret_key_base, serializer: JSON)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def initialize(record:, attachment_name:)
|
|
29
|
+
@record = record
|
|
30
|
+
@attachment_name = attachment_name.to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def token
|
|
34
|
+
self.class.verifier.generate(
|
|
35
|
+
{
|
|
36
|
+
gid: record.to_global_id.to_s,
|
|
37
|
+
attachment_name:
|
|
38
|
+
},
|
|
39
|
+
purpose: VERIFIER_PURPOSE
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def attachment
|
|
44
|
+
record.public_send(attachment_name)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def attached?
|
|
48
|
+
attachment.respond_to?(:attached?) && attachment.attached?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def authorized_for?(user)
|
|
52
|
+
return false unless record.respond_to?(:private_download_authorized?)
|
|
53
|
+
|
|
54
|
+
record.private_download_authorized?(user, attachment_name)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
attr_reader :record, :attachment_name
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -24,5 +24,11 @@ module Decidim
|
|
|
24
24
|
self.content_type = file.content_type
|
|
25
25
|
self.file_size = file.byte_size
|
|
26
26
|
end
|
|
27
|
+
|
|
28
|
+
def private_download_authorized?(user, requested_attachment_name)
|
|
29
|
+
return false unless requested_attachment_name.to_s == "file"
|
|
30
|
+
|
|
31
|
+
attached_to == user
|
|
32
|
+
end
|
|
27
33
|
end
|
|
28
34
|
end
|
|
@@ -2,15 +2,37 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|
|
2
2
|
const GRANTED_PERMISSION = "granted"
|
|
3
3
|
|
|
4
4
|
const hideReminder = function() {
|
|
5
|
-
const reminder = document.querySelector("
|
|
5
|
+
const reminder = document.querySelector("[data-push-notifications-reminder]")
|
|
6
|
+
if (!reminder) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
reminder.classList.add("hide")
|
|
7
11
|
}
|
|
8
12
|
|
|
13
|
+
const showError = (message) => {
|
|
14
|
+
const container = document.querySelector("[data-push-notifications-container]")
|
|
15
|
+
if (!container) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const existingError = container.querySelector("[data-push-notifications-error]")
|
|
20
|
+
if (existingError) {
|
|
21
|
+
existingError.remove()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const errorElement = document.createElement("div")
|
|
25
|
+
errorElement.dataset.pushNotificationsError = "true"
|
|
26
|
+
errorElement.classList.add("flash", "alert", "push-notifications__error")
|
|
27
|
+
errorElement.innerText = message
|
|
28
|
+
container.prepend(errorElement)
|
|
29
|
+
}
|
|
30
|
+
|
|
9
31
|
const subscribeToNotifications = async (registration) => {
|
|
10
32
|
const permission = await window.Notification.requestPermission();
|
|
11
33
|
|
|
12
34
|
if (registration && permission === GRANTED_PERMISSION) {
|
|
13
|
-
const vapidElement = document.querySelector("
|
|
35
|
+
const vapidElement = document.querySelector("[data-push-vapid-public-key]")
|
|
14
36
|
// element could not exist in DOM
|
|
15
37
|
if (vapidElement) {
|
|
16
38
|
const vapidPublicKeyElement = JSON.parse(vapidElement.value)
|
|
@@ -20,7 +42,7 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|
|
20
42
|
});
|
|
21
43
|
|
|
22
44
|
if (subscription) {
|
|
23
|
-
await fetch("/notifications_subscriptions", {
|
|
45
|
+
const response = await fetch("/notifications_subscriptions", {
|
|
24
46
|
headers: {
|
|
25
47
|
"Content-Type": "application/json",
|
|
26
48
|
"X-CSRF-Token": document.querySelector("meta[name=csrf-token]")?.content
|
|
@@ -28,6 +50,11 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|
|
28
50
|
method: "POST",
|
|
29
51
|
body: JSON.stringify(subscription)
|
|
30
52
|
});
|
|
53
|
+
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
const body = await response.json()
|
|
56
|
+
throw new Error(body.error)
|
|
57
|
+
}
|
|
31
58
|
}
|
|
32
59
|
}
|
|
33
60
|
hideReminder()
|
|
@@ -57,10 +84,13 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|
|
57
84
|
hideReminder()
|
|
58
85
|
if (currentSubscription) {
|
|
59
86
|
const auth = currentSubscription.toJSON().keys.auth
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
const subKeysElement = document.querySelector("[data-push-sub-keys]")
|
|
88
|
+
if (subKeysElement) {
|
|
89
|
+
const subKeys = JSON.parse(subKeysElement.value)
|
|
90
|
+
// Subscribed && browser notifications enabled
|
|
91
|
+
if (subKeys.includes(auth)) {
|
|
92
|
+
toggleChecked = true
|
|
93
|
+
}
|
|
64
94
|
}
|
|
65
95
|
}
|
|
66
96
|
}
|
|
@@ -68,7 +98,7 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|
|
68
98
|
}
|
|
69
99
|
|
|
70
100
|
if ("serviceWorker" in navigator) {
|
|
71
|
-
const toggle = document.
|
|
101
|
+
const toggle = document.querySelector("[data-push-notifications-toggle]")
|
|
72
102
|
|
|
73
103
|
if (toggle) {
|
|
74
104
|
const registration = await navigator.serviceWorker.ready
|
|
@@ -76,10 +106,15 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|
|
76
106
|
setToggleState(registration, toggle)
|
|
77
107
|
|
|
78
108
|
toggle.addEventListener("change", async ({ target }) => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
109
|
+
try {
|
|
110
|
+
if (target.checked) {
|
|
111
|
+
await subscribeToNotifications(registration)
|
|
112
|
+
} else {
|
|
113
|
+
await unsubscribeFromNotifications(registration)
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
target.checked = false
|
|
117
|
+
showError(error.message)
|
|
83
118
|
}
|
|
84
119
|
})
|
|
85
120
|
}
|
|
@@ -4,6 +4,10 @@ module Decidim
|
|
|
4
4
|
# This class manages the creation and deletion of user notifications
|
|
5
5
|
|
|
6
6
|
class NotificationsSubscriptionsPersistor
|
|
7
|
+
include PushSubscriptionEndpointValidator
|
|
8
|
+
|
|
9
|
+
class UnsupportedPushSubscriptionEndpointError < StandardError; end
|
|
10
|
+
|
|
7
11
|
attr_reader :user
|
|
8
12
|
|
|
9
13
|
def initialize(user)
|
|
@@ -11,6 +15,8 @@ module Decidim
|
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def add_subscription(params)
|
|
18
|
+
raise UnsupportedPushSubscriptionEndpointError unless supported_push_subscription_endpoint?(params[:endpoint])
|
|
19
|
+
|
|
14
20
|
subscriptions = user.notification_settings["subscriptions"] || {}
|
|
15
21
|
filtered_params = filter_params(params)
|
|
16
22
|
new_subscription = { filtered_params[:auth] => filtered_params }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
# Shared validation for browser push subscription endpoints.
|
|
5
|
+
module PushSubscriptionEndpointValidator
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def supported_push_subscription_endpoint?(endpoint)
|
|
9
|
+
return false if endpoint.blank?
|
|
10
|
+
|
|
11
|
+
uri = URI.parse(endpoint)
|
|
12
|
+
return false unless uri.is_a?(URI::HTTPS)
|
|
13
|
+
|
|
14
|
+
host = uri.host&.downcase
|
|
15
|
+
return false if host.blank?
|
|
16
|
+
|
|
17
|
+
allowed_push_subscription_endpoint_patterns.any? { |pattern| pattern.match?(host) }
|
|
18
|
+
rescue URI::InvalidURIError
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Override this method to customize the browser push endpoint allowlist.
|
|
23
|
+
def allowed_push_subscription_endpoint_patterns
|
|
24
|
+
[
|
|
25
|
+
/\A(?:.*\.)?push\.services\.mozilla\.com\z/,
|
|
26
|
+
/\A(?:.*\.)?fcm\.googleapis\.com\z/,
|
|
27
|
+
/\A(?:.*\.)?android\.googleapis\.com\z/,
|
|
28
|
+
/\A(?:.*\.)?push\.apple\.com\z/,
|
|
29
|
+
/\A(?:.*\.)?opera\.com\z/,
|
|
30
|
+
/\A(?:.*\.)?notify\.windows\.com\z/
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -10,6 +10,7 @@ module Decidim
|
|
|
10
10
|
|
|
11
11
|
class SendPushNotification
|
|
12
12
|
include ActionView::Helpers::UrlHelper
|
|
13
|
+
include PushSubscriptionEndpointValidator
|
|
13
14
|
|
|
14
15
|
# Send the push notification. Returns `nil` if the user did not allowed push notifications
|
|
15
16
|
# or if the subscription to push notifications does not exist
|
|
@@ -23,9 +24,12 @@ module Decidim
|
|
|
23
24
|
raise ArgumentError, "Need to provide a title if the notification is a PushNotificationMessage" if notification.is_a?(Decidim::PushNotificationMessage) && title.nil?
|
|
24
25
|
|
|
25
26
|
user = notification.user
|
|
27
|
+
subscriptions = user.notifications_subscriptions.values.select do |subscription|
|
|
28
|
+
supported_push_subscription_endpoint?(subscription["endpoint"])
|
|
29
|
+
end
|
|
26
30
|
|
|
27
31
|
I18n.with_locale(user.locale || user.organization.default_locale) do
|
|
28
|
-
|
|
32
|
+
subscriptions.map do |subscription|
|
|
29
33
|
payload = build_payload(message_params(notification, title), subscription)
|
|
30
34
|
# Capture webpush exceptions in order to avoid this call to be repeated by the background job runner
|
|
31
35
|
# Webpush::Error class is the parent class of all defined errors
|
|
@@ -167,20 +167,20 @@
|
|
|
167
167
|
<% end %>
|
|
168
168
|
|
|
169
169
|
<% if @notifications_settings.meet_push_notifications_requirements? %>
|
|
170
|
-
<div class="push-notifications js-sw-mandatory">
|
|
170
|
+
<div class="push-notifications js-sw-mandatory" data-push-notifications-container>
|
|
171
171
|
<label>
|
|
172
172
|
<%= t("push_notifications", scope: "decidim.notifications_settings.show") %>
|
|
173
173
|
</label>
|
|
174
|
-
<p id="push-notifications-reminder" class="push-notifications__reminder block my-4">
|
|
174
|
+
<p id="push-notifications-reminder" class="push-notifications__reminder block my-4" data-push-notifications-reminder>
|
|
175
175
|
<%= t("push_notifications_reminder", scope: "decidim.notifications_settings.show") %>
|
|
176
176
|
</p>
|
|
177
177
|
<div class="toggle__switch-trigger">
|
|
178
178
|
<label class="toggle__switch-toggle" for="allow_push_notifications">
|
|
179
179
|
<span>
|
|
180
180
|
<input
|
|
181
|
-
<%== %(checked="checked") if @notifications_settings.meet_push_notifications_requirements? %>
|
|
182
181
|
id="allow_push_notifications"
|
|
183
182
|
type="checkbox"
|
|
183
|
+
data-push-notifications-toggle
|
|
184
184
|
name="allow_push_notifications">
|
|
185
185
|
<span class="toggle__switch-toggle-content">
|
|
186
186
|
</span>
|
|
@@ -194,8 +194,8 @@
|
|
|
194
194
|
</div>
|
|
195
195
|
</div>
|
|
196
196
|
|
|
197
|
-
<input id="vapidPublicKey" name="vapid_public_key" type="hidden" value="<%= Base64.urlsafe_decode64(Rails.application.secrets.vapid[:public_key]).bytes %>">
|
|
198
|
-
<input id="subKeys" name="sub_key" type="hidden" value="<%= current_user.notifications_subscriptions.keys %>">
|
|
197
|
+
<input id="vapidPublicKey" name="vapid_public_key" data-push-vapid-public-key type="hidden" value="<%= Base64.urlsafe_decode64(Rails.application.secrets.vapid[:public_key]).bytes.to_json %>">
|
|
198
|
+
<input id="subKeys" name="sub_key" data-push-sub-keys type="hidden" value="<%= current_user.notifications_subscriptions.keys.to_json %>">
|
|
199
199
|
<% end %>
|
|
200
200
|
|
|
201
201
|
<div class="form__wrapper-block">
|
data/config/locales/ca-IT.yml
CHANGED
|
@@ -1525,6 +1525,7 @@ ca-IT:
|
|
|
1525
1525
|
own_activity: La meva pròpia activitat, com quan algú fa comentaris a la meva proposta o em menciona
|
|
1526
1526
|
push_notifications: Notificacions emergents
|
|
1527
1527
|
push_notifications_reminder: Per rebre notificacions de la plataforma, primer les has de permetre a la configuració del teu navegador.
|
|
1528
|
+
push_notifications_unsupported_browser: El navegador no és compatible.
|
|
1528
1529
|
receive_notifications_about: Vull rebre notificacions
|
|
1529
1530
|
update_notifications_settings: Guardar canvis
|
|
1530
1531
|
valuators: Avaluadores
|
data/config/locales/ca.yml
CHANGED
|
@@ -1525,6 +1525,7 @@ ca:
|
|
|
1525
1525
|
own_activity: La meva pròpia activitat, com quan algú fa comentaris a la meva proposta o em menciona
|
|
1526
1526
|
push_notifications: Notificacions emergents
|
|
1527
1527
|
push_notifications_reminder: Per rebre notificacions de la plataforma, primer les has de permetre a la configuració del teu navegador.
|
|
1528
|
+
push_notifications_unsupported_browser: El navegador no és compatible.
|
|
1528
1529
|
receive_notifications_about: Vull rebre notificacions
|
|
1529
1530
|
update_notifications_settings: Guardar canvis
|
|
1530
1531
|
valuators: Avaluadores
|
data/config/locales/cs.yml
CHANGED
|
@@ -844,6 +844,7 @@ cs:
|
|
|
844
844
|
delete_reason: Důvod pro odstranění tohoto uživatele
|
|
845
845
|
deleted_at: Datum a čas, kdy byl tento uživatel odstraněn
|
|
846
846
|
email: E-mailová adresa tohoto uživatele
|
|
847
|
+
followers_count: Počet účastníků, kteří sledují tohoto uživatele
|
|
847
848
|
following_count: Počet účastníků, které tento uživatel sleduje
|
|
848
849
|
id: Jedinečný identifikátor tohoto uživatele
|
|
849
850
|
invitation_accepted_at: Datum a čas, kdy byla pozvánka přijata
|
|
@@ -1331,6 +1332,7 @@ cs:
|
|
|
1331
1332
|
create_with_space: "%{user_name} vytvořil %{resource_name} v %{space_name}"
|
|
1332
1333
|
delete: "%{user_name} odstraněno %{resource_name}"
|
|
1333
1334
|
delete_with_space: "%{user_name} smazán %{resource_name} v %{space_name}"
|
|
1335
|
+
publish: "%{user_name} publikoval %{resource_name}"
|
|
1334
1336
|
publish_with_space: "%{user_name} publikoval %{resource_name} v %{space_name}"
|
|
1335
1337
|
unknown_action: "%{user_name} provedla nějakou akci na %{resource_name}"
|
|
1336
1338
|
unknown_action_with_space: "%{user_name} provedlo nějakou akci na %{resource_name} v %{space_name}"
|
data/config/locales/en.yml
CHANGED
|
@@ -1532,6 +1532,7 @@ en:
|
|
|
1532
1532
|
own_activity: My own activity, like when someone comments in my proposal or mentions me
|
|
1533
1533
|
push_notifications: Push notifications
|
|
1534
1534
|
push_notifications_reminder: To get notifications from the platform, you will need to allow them in your browser settings first.
|
|
1535
|
+
push_notifications_unsupported_browser: Your browser is not supported.
|
|
1535
1536
|
receive_notifications_about: I want to get notifications about
|
|
1536
1537
|
update_notifications_settings: Save changes
|
|
1537
1538
|
valuators: Evaluators
|
data/config/locales/es-MX.yml
CHANGED
|
@@ -1528,6 +1528,7 @@ es-MX:
|
|
|
1528
1528
|
own_activity: Mi propia actividad, como cuando alguien comenta en mi propuesta o me menciona.
|
|
1529
1529
|
push_notifications: Notificaciones emergentes
|
|
1530
1530
|
push_notifications_reminder: Para obtener notificaciones de la plataforma, primero tienes que permitirlas en la configuración de tu navegador.
|
|
1531
|
+
push_notifications_unsupported_browser: Tu navegador no es compatible.
|
|
1531
1532
|
receive_notifications_about: Quiero recibir notificaciones sobre
|
|
1532
1533
|
update_notifications_settings: Guardar cambios
|
|
1533
1534
|
valuators: Evaluadoras
|
data/config/locales/es-PY.yml
CHANGED
|
@@ -1528,6 +1528,7 @@ es-PY:
|
|
|
1528
1528
|
own_activity: Mi propia actividad, como cuando alguien comenta en mi propuesta o me menciona.
|
|
1529
1529
|
push_notifications: Notificaciones emergentes
|
|
1530
1530
|
push_notifications_reminder: Para obtener notificaciones de la plataforma, primero tienes que permitirlas en la configuración de tu navegador.
|
|
1531
|
+
push_notifications_unsupported_browser: Tu navegador no es compatible.
|
|
1531
1532
|
receive_notifications_about: Quiero recibir notificaciones sobre
|
|
1532
1533
|
update_notifications_settings: Guardar cambios
|
|
1533
1534
|
valuators: Evaluadoras
|
data/config/locales/es.yml
CHANGED
|
@@ -1525,6 +1525,7 @@ es:
|
|
|
1525
1525
|
own_activity: Mi propia actividad, como cuando alguien comenta en mi propuesta o me menciona
|
|
1526
1526
|
push_notifications: Notificaciones emergentes
|
|
1527
1527
|
push_notifications_reminder: Para recibir notificaciones de la plataforma, primero tienes que permitirlas en la configuración de tu navegador.
|
|
1528
|
+
push_notifications_unsupported_browser: Tu navegador no es compatible.
|
|
1528
1529
|
receive_notifications_about: Quiero recibir notificaciones
|
|
1529
1530
|
update_notifications_settings: Guardar cambios
|
|
1530
1531
|
valuators: Evaluadoras
|
data/config/locales/eu.yml
CHANGED
|
@@ -1525,6 +1525,7 @@ eu:
|
|
|
1525
1525
|
own_activity: Neure jarduera, norbaitek nire proposamenean iruzkina egiten duenean bezala, edo aipatzen nauenean
|
|
1526
1526
|
push_notifications: Push jakinarazpenak
|
|
1527
1527
|
push_notifications_reminder: Plataformaren jakinarazpenak jasotzeko, lehen zure nabigatzailearen konfigurazioan baimendu behar dituzu.
|
|
1528
|
+
push_notifications_unsupported_browser: Zure nabigatzaileak ez du euskarririk.
|
|
1528
1529
|
receive_notifications_about: Jakinarazpenak jaso nahi ditut
|
|
1529
1530
|
update_notifications_settings: Gorde aldaketak
|
|
1530
1531
|
valuators: Ebaluatzaileak
|
data/config/locales/fi.yml
CHANGED
|
@@ -2222,8 +2222,8 @@ fi:
|
|
|
2222
2222
|
correct_errors: Lomakkeella on virheitä, korjaa ne jatkaaksesi.
|
|
2223
2223
|
length_validator:
|
|
2224
2224
|
minimum:
|
|
2225
|
-
one: Vähintään %{count}
|
|
2226
|
-
other: Vähintään %{count}
|
|
2225
|
+
one: Vähintään %{count} merkki
|
|
2226
|
+
other: Vähintään %{count} merkkiä
|
|
2227
2227
|
required: Pakollinen kenttä
|
|
2228
2228
|
required_explanation: "* Vaaditut kentät on merkitty tähtimerkillä"
|
|
2229
2229
|
invisible_captcha:
|
data/config/locales/fr-CA.yml
CHANGED
|
@@ -1416,6 +1416,7 @@ fr-CA:
|
|
|
1416
1416
|
own_activity: Ma propre activité, comme quand quelqu'un commente dans ma proposition ou me mentionne
|
|
1417
1417
|
push_notifications: Notifications push
|
|
1418
1418
|
push_notifications_reminder: Pour recevoir des notifications de la plateforme, vous devez d'abord les autoriser dans les paramètres de votre navigateur.
|
|
1419
|
+
push_notifications_unsupported_browser: Votre navigateur n'est pas pris en charge.
|
|
1419
1420
|
receive_notifications_about: Je veux recevoir des notifications sur
|
|
1420
1421
|
update_notifications_settings: Enregistrer les modifications
|
|
1421
1422
|
valuators: Évaluateurs
|
data/config/locales/fr.yml
CHANGED
|
@@ -1416,6 +1416,7 @@ fr:
|
|
|
1416
1416
|
own_activity: Ma propre activité, comme quand quelqu'un commente dans ma proposition ou me mentionne
|
|
1417
1417
|
push_notifications: Notifications push
|
|
1418
1418
|
push_notifications_reminder: Pour recevoir des notifications de la plateforme, vous devez d'abord les autoriser dans les paramètres de votre navigateur.
|
|
1419
|
+
push_notifications_unsupported_browser: Votre navigateur n'est pas pris en charge.
|
|
1419
1420
|
receive_notifications_about: Je veux recevoir des notifications sur
|
|
1420
1421
|
update_notifications_settings: Enregistrer les modifications
|
|
1421
1422
|
valuators: Évaluateurs
|
data/config/locales/it.yml
CHANGED
|
@@ -517,6 +517,7 @@ it:
|
|
|
517
517
|
username_help: Nome "pubblico" che comparirà a firma di tutti i tuoi contributi e che sarà accessibile a tutti i navigatori, anche non iscritti alla piattaforma. Ti invitiamo a utilizzare un nome di fantasia per una maggiore tutela della riservatezza.
|
|
518
518
|
sessions:
|
|
519
519
|
new:
|
|
520
|
+
are_you_new?: Non sei ancora registrato?
|
|
520
521
|
register: Crea un account
|
|
521
522
|
shared:
|
|
522
523
|
newsletter_modal:
|
|
@@ -541,6 +542,9 @@ it:
|
|
|
541
542
|
download_your_data:
|
|
542
543
|
export:
|
|
543
544
|
ready: Pronto
|
|
545
|
+
help:
|
|
546
|
+
users:
|
|
547
|
+
notifications_sending_frequency: La frequenza delle notifiche che questo utente riceve
|
|
544
548
|
editor_images:
|
|
545
549
|
drag_and_drop_help: Aggiungi immagini trascinandole o incollandole.
|
|
546
550
|
endorsements:
|
|
@@ -1001,6 +1005,12 @@ it:
|
|
|
1001
1005
|
everything_followed: Tutto ciò che seguo
|
|
1002
1006
|
newsletter_notifications: Voglio ricevere le newsletter
|
|
1003
1007
|
newsletters: Le Newsletter
|
|
1008
|
+
notifications_sending_frequencies:
|
|
1009
|
+
daily: Quotidiana
|
|
1010
|
+
none: Non voglio ricevere mail
|
|
1011
|
+
real_time: Tempo reale
|
|
1012
|
+
weekly: Settimanale
|
|
1013
|
+
notifications_sending_frequency: Con che frequenza vuoi ricevere notifiche via mail?
|
|
1004
1014
|
own_activity: La mia attività personale, come quando qualcuno commenta la mia proposta o mi menziona
|
|
1005
1015
|
receive_notifications_about: Voglio ricevere le notifiche
|
|
1006
1016
|
update_notifications_settings: Salva le modifiche
|