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/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..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,12 +49,20 @@ export class NotificationService { events_only: true, default_payload: defaultPayload }; - return pusherFactory.httpPusher( - this._pushConfig.gatewayUrl, - 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 + ); + } } }