From 75be87c144a86928700062a136966ff627af928f Mon Sep 17 00:00:00 2001 From: Vasilii Mikhailovskii Date: Thu, 21 Nov 2024 16:11:23 +0200 Subject: [PATCH] test web push --- apps/frontend/components.d.ts | 4 + apps/frontend/package.json | 5 +- apps/frontend/public/service-worker.js | 47 ++++-- .../CreateMessageDeliveryMethodSection.vue | 57 ++++--- .../create/CreateMessageDeliveryOption.vue | 23 +++ .../CreateMessageDeliveryOptionTelegram.vue | 32 ++++ .../CreateMessageDeliveryOptionWebPush.vue | 100 ++++++++++++ .../create/CreateMessageDeliveryOptions.vue | 30 ++++ .../frontend/src/constants/deliveryOptions.ts | 9 +- .../types/DBDocumentTypes/QRCodeDocument.ts | 2 +- package-lock.json | 149 ++++++++++++++++-- package.json | 5 + .../generate-keys.js | 5 + .../package.json | 33 ++++ 14 files changed, 438 insertions(+), 63 deletions(-) create mode 100644 apps/frontend/src/components/create/CreateMessageDeliveryOption.vue create mode 100644 apps/frontend/src/components/create/CreateMessageDeliveryOptionTelegram.vue create mode 100644 apps/frontend/src/components/create/CreateMessageDeliveryOptionWebPush.vue create mode 100644 apps/frontend/src/components/create/CreateMessageDeliveryOptions.vue create mode 100644 services/message-delivery-method-web-push/generate-keys.js create mode 100644 services/message-delivery-method-web-push/package.json diff --git a/apps/frontend/components.d.ts b/apps/frontend/components.d.ts index 3196e08..0279195 100644 --- a/apps/frontend/components.d.ts +++ b/apps/frontend/components.d.ts @@ -13,6 +13,10 @@ declare module 'vue' { Checkbox: typeof import('primevue/checkbox')['default'] CreateActionsSection: typeof import('./src/components/create/CreateActionsSection.vue')['default'] CreateMessageDeliveryMethodSection: typeof import('./src/components/create/CreateMessageDeliveryMethodSection.vue')['default'] + CreateMessageDeliveryOption: typeof import('./src/components/create/CreateMessageDeliveryOption.vue')['default'] + CreateMessageDeliveryOptions: typeof import('./src/components/create/CreateMessageDeliveryOptions.vue')['default'] + CreateMessageDeliveryOptionTelegram: typeof import('./src/components/create/CreateMessageDeliveryOptionTelegram.vue')['default'] + CreateMessageDeliveryOptionWebPush: typeof import('./src/components/create/CreateMessageDeliveryOptionWebPush.vue')['default'] CreatePlacementSection: typeof import('./src/components/create/CreatePlacementSection.vue')['default'] CreatePredefinedMessagesSection: typeof import('./src/components/create/CreatePredefinedMessagesSection.vue')['default'] CreateSection: typeof import('./src/components/create/CreateSection.vue')['default'] diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 589f4c4..c67a51a 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -3,6 +3,7 @@ "version": "0.0.0", "private": true, "type": "module", + "license": "@hereconnect/license", "scripts": { "dev": "vite", "build": "run-p type-check \"build-only {@}\" --", @@ -14,10 +15,6 @@ "lint": "eslint . --fix", "format": "prettier --write src/" }, - "engines": { - "node": ">=v20.10.0", - "pnpm": ">=8.15.0" - }, "dependencies": { "@f3ve/vue-markdown-it": "^0.2.3", "@primevue/forms": "^4.2.1", diff --git a/apps/frontend/public/service-worker.js b/apps/frontend/public/service-worker.js index 61bd075..6c530b2 100644 --- a/apps/frontend/public/service-worker.js +++ b/apps/frontend/public/service-worker.js @@ -34,28 +34,41 @@ self.addEventListener('push', (event) => { }) self.addEventListener('notificationclick', (event) => { + console.log('клик на уведомление', event.notification) event.notification.close() // Открытие URL из данных уведомления event.waitUntil( - clients.matchAll({ type: 'window' }).then((clientList) => { - for (const client of clientList) { - if (client.url === event.notification.data.url && 'focus' in client) { - console.log('клик на уведомление', event.notification.tag) + clients + .matchAll({ type: 'window', includeUncontrolled: true }) + .then((clientList) => { + for (const client of clientList) { + console.log('client.url', client.url) + if (client.url === event.notification.data.url && 'focus' in client) { + console.log('фокус') - return Promise.all([ - client.focus(), - client.postMessage({ - type: 'notificationClick', - tag: event.notification.tag, - payload: event.notification.payload, - }), - ]) + return Promise.all([ + client.focus(), + client.postMessage({ + type: 'notificationClick', + tag: event.notification.tag, + payload: event.notification.payload, + }), + ]) + } } - } - if (clients.openWindow) { - return clients.openWindow(event.notification.data.url) - } - }), + if (clients.openWindow) { + console.log('новое окно') + return clients.openWindow(event.notification.data.url).then((client) => { + if (client) { + return client.focus() + } + console.log('новое окно не открылось') + }) + } + }) + .catch((error) => { + console.error(error) + }), ) }) diff --git a/apps/frontend/src/components/create/CreateMessageDeliveryMethodSection.vue b/apps/frontend/src/components/create/CreateMessageDeliveryMethodSection.vue index 6d686e9..136df4b 100644 --- a/apps/frontend/src/components/create/CreateMessageDeliveryMethodSection.vue +++ b/apps/frontend/src/components/create/CreateMessageDeliveryMethodSection.vue @@ -2,45 +2,42 @@

Куда отправлять сообщения?

Выберите, как вы хотите получать сообщения.

-
-
- + + + +
diff --git a/apps/frontend/src/components/create/CreateMessageDeliveryOption.vue b/apps/frontend/src/components/create/CreateMessageDeliveryOption.vue new file mode 100644 index 0000000..dbe8711 --- /dev/null +++ b/apps/frontend/src/components/create/CreateMessageDeliveryOption.vue @@ -0,0 +1,23 @@ + + + diff --git a/apps/frontend/src/components/create/CreateMessageDeliveryOptionTelegram.vue b/apps/frontend/src/components/create/CreateMessageDeliveryOptionTelegram.vue new file mode 100644 index 0000000..b414804 --- /dev/null +++ b/apps/frontend/src/components/create/CreateMessageDeliveryOptionTelegram.vue @@ -0,0 +1,32 @@ + + + diff --git a/apps/frontend/src/components/create/CreateMessageDeliveryOptionWebPush.vue b/apps/frontend/src/components/create/CreateMessageDeliveryOptionWebPush.vue new file mode 100644 index 0000000..ee3d3d8 --- /dev/null +++ b/apps/frontend/src/components/create/CreateMessageDeliveryOptionWebPush.vue @@ -0,0 +1,100 @@ + + + diff --git a/apps/frontend/src/components/create/CreateMessageDeliveryOptions.vue b/apps/frontend/src/components/create/CreateMessageDeliveryOptions.vue new file mode 100644 index 0000000..e3d2e12 --- /dev/null +++ b/apps/frontend/src/components/create/CreateMessageDeliveryOptions.vue @@ -0,0 +1,30 @@ + + + diff --git a/apps/frontend/src/constants/deliveryOptions.ts b/apps/frontend/src/constants/deliveryOptions.ts index e983849..ab79b74 100644 --- a/apps/frontend/src/constants/deliveryOptions.ts +++ b/apps/frontend/src/constants/deliveryOptions.ts @@ -1,8 +1,13 @@ +export const DELIVERY_METHOD_TELEGRAM = 'telegram' +export const DELIVERY_METHOD_WEB_PUSH = 'webPush' + // Массив вариантов доставки export const deliveryOptions = [ { label: 'В браузере (push-уведомления)', - method: 'webPushSubscription', + method: DELIVERY_METHOD_WEB_PUSH, }, - { label: 'Telegram', method: 'telegram' }, + { label: 'Telegram', method: DELIVERY_METHOD_TELEGRAM }, ] as const + +export type DeliveryOption = (typeof deliveryOptions)[number] diff --git a/apps/frontend/src/types/DBDocumentTypes/QRCodeDocument.ts b/apps/frontend/src/types/DBDocumentTypes/QRCodeDocument.ts index 31b939d..83a37e5 100644 --- a/apps/frontend/src/types/DBDocumentTypes/QRCodeDocument.ts +++ b/apps/frontend/src/types/DBDocumentTypes/QRCodeDocument.ts @@ -26,7 +26,7 @@ export interface QRCodeDocument extends BaseDocument { /** Название объекта, для которого создан QR‑код, например "Мой автомобиль" */ name: string - messageDeliveryMethod: 'telegram' | 'webPushSubscription' + messageDeliveryMethod: 'telegram' | 'webPush' /** Тип объекта, для которого создан QR‑код, например "car" */ placement: 'car' | 'pet' | 'door' | 'store' | 'restaurant_table' | 'other' diff --git a/package-lock.json b/package-lock.json index c780930..621e879 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,11 @@ "": { "name": "@hereconnect/monorepo", "version": "1.0.0", + "license": "@hereconnect/license", + "engines": { + "node": ">=v20.10.0", + "pnpm": ">=8.15.0" + }, "workspaces": { "packages": [ "apps/*", @@ -18,6 +23,7 @@ "apps/frontend": { "name": "@hereconnect/frontend", "version": "0.0.0", + "license": "@hereconnect/license", "dependencies": { "@f3ve/vue-markdown-it": "^0.2.3", "@primevue/forms": "^4.2.1", @@ -67,10 +73,6 @@ "vite-plugin-vue-devtools": "^7.5.4", "vitest": "^2.1.4", "vue-tsc": "^2.1.10" - }, - "engines": { - "node": ">=v20.10.0", - "pnpm": ">=8.15.0" } }, "node_modules/@alloc/quick-lru": { @@ -1182,6 +1184,10 @@ "resolved": "apps/frontend", "link": true }, + "node_modules/@hereconnect/message-delivery-method-web-push": { + "resolved": "services/message-delivery-method-web-push", + "link": true + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -2752,7 +2758,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, "license": "MIT", "dependencies": { "debug": "^4.3.4" @@ -2843,6 +2848,18 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -2935,6 +2952,12 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "license": "MIT" + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -3011,6 +3034,12 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", @@ -3407,7 +3436,6 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3577,6 +3605,15 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/editorconfig": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", @@ -4485,6 +4522,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/http_ece": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz", + "integrity": "sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -4503,7 +4549,6 @@ "version": "7.0.5", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.0.2", @@ -4961,6 +5006,27 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5228,6 +5294,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -5243,6 +5315,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -5286,7 +5367,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/muggle-string": { @@ -6577,11 +6657,30 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT" }, "node_modules/saxes": { @@ -7900,6 +7999,25 @@ "node": ">=18" } }, + "node_modules/web-push": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/web-push/-/web-push-3.6.7.tgz", + "integrity": "sha512-OpiIUe8cuGjrj3mMBFWY+e4MMIkW3SVT+7vEIjvD9kejGUypv8GPDf84JdPWskK8zMRIJ6xYGm+Kxr8YkPyA0A==", + "license": "MPL-2.0", + "dependencies": { + "asn1.js": "^5.3.0", + "http_ece": "1.2.0", + "https-proxy-agent": "^7.0.0", + "jws": "^4.0.0", + "minimist": "^1.2.5" + }, + "bin": { + "web-push": "src/cli.js" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -8160,6 +8278,19 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "services/message-delivery-method-web-push": { + "name": "@hereconnect/message-delivery-method-web-push", + "version": "1.0.0", + "license": "@hereconnect/license", + "dependencies": { + "web-push": "^3.6.7" + }, + "devDependencies": {}, + "engines": { + "node": ">= 14.0.0", + "npm": ">= 6.0.0" + } } } } diff --git a/package.json b/package.json index b804e2c..322b00b 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,11 @@ "name": "@hereconnect/monorepo", "version": "1.0.0", "private": true, + "license": "@hereconnect/license", + "engines": { + "node": ">=v20.10.0", + "pnpm": ">=8.15.0" + }, "workspaces": { "packages": [ "apps/*", diff --git a/services/message-delivery-method-web-push/generate-keys.js b/services/message-delivery-method-web-push/generate-keys.js new file mode 100644 index 0000000..dc91d26 --- /dev/null +++ b/services/message-delivery-method-web-push/generate-keys.js @@ -0,0 +1,5 @@ +import webpush from 'web-push'; + +const vapidKeys = webpush.generateVAPIDKeys(); + +console.log(vapidKeys) diff --git a/services/message-delivery-method-web-push/package.json b/services/message-delivery-method-web-push/package.json new file mode 100644 index 0000000..a8ddaf2 --- /dev/null +++ b/services/message-delivery-method-web-push/package.json @@ -0,0 +1,33 @@ +{ + "name": "@hereconnect/message-delivery-method-web-push", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "license": "@hereconnect/license", + "private": true, + "engines": { + "node": ">= 14.0.0", + "npm": ">= 6.0.0" + }, + "homepage": "", + "repository": { + "type": "git", + "url": "" + }, + "bugs": "", + "keywords": [], + "author": { + "name": "", + "email": "", + "url": "" + }, + "contributors": [], + "scripts": { + "dev": "", + "test": "" + }, + "dependencies": { + "web-push": "^3.6.7" + } +}