From 8ff213af4ef37f43648ccc6deafcc993c7a0564d Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 21 Oct 2022 22:37:52 +0200 Subject: [PATCH] Add the ability to unsubscribe from push notifications --- app/controllers/ajax/web_push_controller.rb | 13 +++++++ .../retrospring/features/webpush/index.ts | 3 ++ .../features/webpush/unsubscribe.ts | 36 +++++++++++++++++++ config/routes.rb | 1 + 4 files changed, 53 insertions(+) create mode 100644 app/javascript/retrospring/features/webpush/unsubscribe.ts diff --git a/app/controllers/ajax/web_push_controller.rb b/app/controllers/ajax/web_push_controller.rb index 49d8a497..b3a671eb 100644 --- a/app/controllers/ajax/web_push_controller.rb +++ b/app/controllers/ajax/web_push_controller.rb @@ -18,4 +18,17 @@ class Ajax::WebPushController < AjaxController @response[:status] = :okay @response[:success] = true end + + def unsubscribe + params.permit(:endpoint) + + if params.key?(:endpoint) + current_user.web_push_subscriptions.where("subscription ->> 'endpoint' = ?", params[:endpoint]).destroy + else + current_user.web_push_subscriptions.destroy_all + end + + @response[:status] = :okay + @response[:success] = true + end end diff --git a/app/javascript/retrospring/features/webpush/index.ts b/app/javascript/retrospring/features/webpush/index.ts index 2c10566b..e9149684 100644 --- a/app/javascript/retrospring/features/webpush/index.ts +++ b/app/javascript/retrospring/features/webpush/index.ts @@ -1,6 +1,7 @@ import registerEvents from 'retrospring/utilities/registerEvents'; import { enableHandler } from './enable'; import { dismissHandler } from "./dismiss"; +import { unsubscribeHandler } from "retrospring/features/webpush/unsubscribe"; export default (): void => { const swCapable = document.body.classList.contains('cap-service-worker'); @@ -16,6 +17,8 @@ export default (): void => { registerEvents([ {type: 'click', target: '[data-action="push-enable"]', handler: enableHandler, global: true}, {type: 'click', target: '[data-action="push-dismiss"]', handler: dismissHandler, global: true}, + {type: 'click', target: '[data-action="push-disable"]', handler: () => unsubscribeHandler(false), global: true}, + {type: 'click', target: '[data-action="push-remove-all"]', handler: () => unsubscribeHandler(true), global: true}, ]); } } diff --git a/app/javascript/retrospring/features/webpush/unsubscribe.ts b/app/javascript/retrospring/features/webpush/unsubscribe.ts new file mode 100644 index 00000000..c89a8d7e --- /dev/null +++ b/app/javascript/retrospring/features/webpush/unsubscribe.ts @@ -0,0 +1,36 @@ +import { destroy } from '@rails/request.js'; +import { showErrorNotification, showNotification } from "utilities/notifications"; +import I18n from "retrospring/i18n"; + +export function unsubscribeHandler(all = false): void { + getSubscription().then(subscription => { + const body = all ? { endpoint: subscription.endpoint } : undefined; + + destroy('/ajax/webpush', { + body, + contentType: 'application/json', + }).then(async response => { + const data = await response.json; + + if (data.success) { + subscription?.unsubscribe().then(() => { + showNotification(I18n.translate("frontend.push_notifications.unsubscribe.success")); + }).catch(error => { + console.error("Tried to unsubscribe this browser but was unable to.\n" + + "As we've been unsubscribed on the server-side, this should not be an issue.", + error); + }) + } else { + showErrorNotification(I18n.translate("frontend.push_notifications.unsubscribe.fail")); + } + }).catch(error => { + showErrorNotification(I18n.translate("frontend.push_notifications.unsubscribe.error")); + console.error(error); + }); + }) +} + +async function getSubscription(): Promise { + const registration = await navigator.serviceWorker.getRegistration('/'); + return await registration.pushManager.getSubscription(); +} diff --git a/config/routes.rb b/config/routes.rb index c3770c08..55300166 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -136,6 +136,7 @@ Rails.application.routes.draw do post "/unsubscribe", to: "subscription#unsubscribe", as: :unsubscribe_answer get "/webpush/key", to: "web_push#key", as: :webpush_key post "/webpush", to: "web_push#subscribe", as: :webpush_subscribe + delete "/webpush", to: "web_push#unsubscribe", as: :webpush_unsubscribe end resource :anonymous_block, controller: :anonymous_block, only: %i[create destroy]