FEATURE: Handle user agent push subscription change events (#11994)

A user browser may rotate a user subscription endpoint/keys
anytime.

Currently, Discourse will receive a 4XX response while trying to
deliver a push notification and silently unsubscribe the device.

With this change, we will gracefully handle desativating the old
subscription and the replacement creation with the need for the user
to resubscribe manually every time it breaks.

https://meta.discourse.org/t/-/125179?u=falco
This commit is contained in:
Rafael dos Santos Silva 2021-02-08 12:09:52 -03:00 committed by GitHub
parent 7e6cb1ff2e
commit ceab1c9fdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 29 additions and 1 deletions

View File

@ -186,7 +186,35 @@ self.addEventListener('notificationclick', function(event) {
self.addEventListener('message', function(event) { self.addEventListener('message', function(event) {
if('lastAction' in event.data){ if('lastAction' in event.data){
lastAction = event.data.lastAction; lastAction = event.data.lastAction;
}}); }
});
self.addEventListener('pushsubscriptionchange', function(event) {
event.waitUntil(
Promise.all(
fetch('<%= Discourse.base_url %>/push_notifications/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body: new URLSearchParams({
"subscription[endpoint]": event.newSubscription.endpoint,
"subscription[keys][auth]": event.newSubscription.toJSON().keys.auth,
"subscription[keys][p256dh]": event.newSubscription.toJSON().keys.p256dh,
"send_confirmation": false
})
}),
fetch('<%= Discourse.base_url %>/push_notifications/unsubscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body: new URLSearchParams({
"subscription[endpoint]": event.oldSubscription.endpoint,
"subscription[keys][auth]": event.oldSubscription.toJSON().keys.auth,
"subscription[keys][p256dh]": event.oldSubscription.toJSON().keys.p256dh
})
})
)
);
});
<% DiscoursePluginRegistry.service_workers.each do |js| %> <% DiscoursePluginRegistry.service_workers.each do |js| %>
<%=raw "#{File.read(js)}" %> <%=raw "#{File.read(js)}" %>
<% end %> <% end %>