From e7cc4880b0d294a989b757aee0c17abee5601aa7 Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 21 Nov 2024 08:13:21 +0000 Subject: [PATCH 1/2] use MSC4174 --- src/matrix/push/Pusher.ts | 13 +++++++++++++ src/platform/web/dom/NotificationService.js | 3 +-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/matrix/push/Pusher.ts b/src/matrix/push/Pusher.ts index 9f970322b3..c32227aa29 100644 --- a/src/matrix/push/Pusher.ts +++ b/src/matrix/push/Pusher.ts @@ -56,6 +56,19 @@ export class Pusher { }); } + static webpushPusher(appId: string, pushkey: string, data: IPusherData): Pusher { + return new Pusher({ + kind: "webpush", + append: true, // as pushkeys are shared between multiple users on one origin + data, + pushkey, + app_id: appId, + app_display_name: "Hydrogen", + device_display_name: "Hydrogen", + lang: "en" + }); + } + static createDefaultPayload(sessionId: string): {session_id: string} { return {session_id: sessionId}; } diff --git a/src/platform/web/dom/NotificationService.js b/src/platform/web/dom/NotificationService.js index 86b2ca6999..9e1368b5ae 100644 --- a/src/platform/web/dom/NotificationService.js +++ b/src/platform/web/dom/NotificationService.js @@ -37,8 +37,7 @@ export class NotificationService { events_only: true, default_payload: defaultPayload }; - return pusherFactory.httpPusher( - this._pushConfig.gatewayUrl, + return pusherFactory.webpushPusher( this._pushConfig.appId, pushkey, data From f3437efbd154a3109f884ee5443bf3070d204f43 Mon Sep 17 00:00:00 2001 From: Mathieu Velten Date: Thu, 28 Nov 2024 23:27:52 +0100 Subject: [PATCH 2/2] Add support for detecting webpush capability and fetch the vapid key --- src/matrix/Session.js | 2 +- src/matrix/net/HomeServerApi.ts | 4 +++ src/platform/web/dom/NotificationService.js | 35 ++++++++++++++++----- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/matrix/Session.js b/src/matrix/Session.js index 348b626b7b..5a83ff3ab7 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -946,7 +946,7 @@ export class Session { async _enablePush() { return this._platform.logger.run("enablePush", async log => { const defaultPayload = Pusher.createDefaultPayload(this._sessionInfo.id); - const pusher = await this._platform.notificationService.enablePush(Pusher, defaultPayload); + const pusher = await this._platform.notificationService.enablePush(Pusher, defaultPayload, this._hsApi); if (!pusher) { log.set("no_pusher", true); return false; diff --git a/src/matrix/net/HomeServerApi.ts b/src/matrix/net/HomeServerApi.ts index 7f498bba6e..bba2743200 100644 --- a/src/matrix/net/HomeServerApi.ts +++ b/src/matrix/net/HomeServerApi.ts @@ -223,6 +223,10 @@ export class HomeServerApi { return this._unauthedRequest("GET", `${this._homeserver}/_matrix/client/versions`, undefined, undefined, options); } + capabilities(options?: BaseRequestOptions): IHomeServerRequest { + return this._get("/capabilities", undefined, undefined, options); + } + uploadKeys(dehydratedDeviceId: string, payload: Record, options?: BaseRequestOptions): IHomeServerRequest { let path = "/keys/upload"; if (dehydratedDeviceId) { diff --git a/src/platform/web/dom/NotificationService.js b/src/platform/web/dom/NotificationService.js index 9e1368b5ae..d954d81f73 100644 --- a/src/platform/web/dom/NotificationService.js +++ b/src/platform/web/dom/NotificationService.js @@ -20,12 +20,24 @@ export class NotificationService { this._pushConfig = pushConfig; } - async enablePush(pusherFactory, defaultPayload) { + async enablePush(pusherFactory, defaultPayload, hsApi) { const registration = await this._serviceWorkerHandler?.getRegistration(); if (registration?.pushManager) { + const response = await hsApi.capabilities().response(); + var webPushCapability = response?.capabilities?.["m.webpush"] + if (!webPushCapability) + webPushCapability = response?.capabilities?.["org.matrix.msc4174.webpush"] + + var supportDirectWebPush = false; + var applicationServerKey = this._pushConfig.applicationServerKey + if (webPushCapability && webPushCapability?.enabled == true) { + supportDirectWebPush = true; + applicationServerKey = webPushCapability?.vapid + } + const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, - applicationServerKey: this._pushConfig.applicationServerKey, + applicationServerKey: applicationServerKey, }); const subscriptionData = subscription.toJSON(); const pushkey = subscriptionData.keys.p256dh; @@ -37,11 +49,20 @@ export class NotificationService { events_only: true, default_payload: defaultPayload }; - return pusherFactory.webpushPusher( - this._pushConfig.appId, - pushkey, - data - ); + if (supportDirectWebPush) { + return pusherFactory.webpushPusher( + this._pushConfig.appId, + pushkey, + data + ); + } else { + return pusherFactory.httpPusher( + this._pushConfig.gatewayUrl, + this._pushConfig.appId, + pushkey, + data + ); + } } }