From 2f5c5922e020fca5f0032ce103527515fcd00f22 Mon Sep 17 00:00:00 2001 From: Vasilii Mikhailovskii Date: Tue, 3 Dec 2024 13:56:24 +0200 Subject: [PATCH] ci --- .../deploy-service-db-migrations.yaml | 4 +- .../src/DBDocuments/ServerSettingsDocument.ts | 29 ++--- .../src/dbs.ts | 16 ++- .../src/generate-keys.ts | 45 -------- .../src/setupVapidDetails.ts | 107 ++++++++---------- .../src/test-send-notification-cancel.js | 65 ----------- .../src/test-send-notification.js | 97 ---------------- 7 files changed, 73 insertions(+), 290 deletions(-) delete mode 100644 services/message-delivery-method-web-push/src/generate-keys.ts delete mode 100644 services/message-delivery-method-web-push/src/test-send-notification-cancel.js delete mode 100644 services/message-delivery-method-web-push/src/test-send-notification.js diff --git a/.gitea/workflows/deploy-service-db-migrations.yaml b/.gitea/workflows/deploy-service-db-migrations.yaml index d2913d5..984e880 100644 --- a/.gitea/workflows/deploy-service-db-migrations.yaml +++ b/.gitea/workflows/deploy-service-db-migrations.yaml @@ -5,8 +5,8 @@ on: branches: - main paths: - - 'services/db-migrate/**' - - '.gitea/workflows/deploy-db-migrate.yaml' + - 'services/db-migrations/**' + - '.gitea/workflows/deploy-service-db-migrations.yaml' jobs: db-migrations: diff --git a/packages/types/src/DBDocuments/ServerSettingsDocument.ts b/packages/types/src/DBDocuments/ServerSettingsDocument.ts index a20e0f2..9342a44 100644 --- a/packages/types/src/DBDocuments/ServerSettingsDocument.ts +++ b/packages/types/src/DBDocuments/ServerSettingsDocument.ts @@ -1,24 +1,11 @@ import type { BaseDocument } from "./BaseDocument"; -type MessageDeliveryMethodWebPushVapid = { - name: "message_delivery_method_web_push_vapid"; - value: { - subject: string; - keys: { - publicKey: string; - privateKey: string; - }; - }; -}; -type MessageDeliveryMethodWebPushGcmApiKey = { - name: "message_delivery_method_web_push_gcm_api_key"; - value: string; -}; - -export type ServerSettingsDocument = ( - | MessageDeliveryMethodWebPushVapid - | MessageDeliveryMethodWebPushGcmApiKey -) & { - _id: string; // Формат: "server_settings:" +export interface MessageDeliveryMethodWebPushVapid extends BaseDocument { + _id: "server_settings:message_delivery_method_web_push_vapid_keys"; // Формат: "server_settings:" type: "server_settings"; -} & BaseDocument; + name: "message_delivery_method_web_push_vapid_keys"; + value: { + publicKey: string; + privateKey: string; + }; +} diff --git a/services/message-delivery-method-web-push/src/dbs.ts b/services/message-delivery-method-web-push/src/dbs.ts index 404aa39..06fea02 100644 --- a/services/message-delivery-method-web-push/src/dbs.ts +++ b/services/message-delivery-method-web-push/src/dbs.ts @@ -1,10 +1,11 @@ import PouchDB from "./PouchDB"; -import type { +import { MessageDocument, QRCodeDocument, - ServerSettingsDocument, + MessageDeliveryMethodWebPushVapid, UserChatSettingsDocument, WebPushSubscriptionDocument, + PublicSettingsDocument, } from "@hereconnect/types"; import { PushSubscription } from "web-push"; @@ -18,12 +19,20 @@ if (!process.env.API_URL) { export const messagesDbUrl = `${process.env.API_URL}/messages`; -export const serverSettingsDb = new PouchDB( +export const serverSettingsDb = new PouchDB( `${process.env.API_URL}/server_settings`, { skip_setup: true, }, ); + +export const publicSettingsDb = new PouchDB( + `${process.env.API_URL}/public_settings`, + { + skip_setup: true, + }, +); + export const qrDb = new PouchDB(`${process.env.API_URL}/qr`, { skip_setup: true, }); @@ -57,6 +66,7 @@ export const checkDatabases = async () => { const entries = await Promise.all( Object.entries({ serverSettingsDb, + publicSettingsDb, qrDb, webPushSubscriptionsDb, messagesDb, diff --git a/services/message-delivery-method-web-push/src/generate-keys.ts b/services/message-delivery-method-web-push/src/generate-keys.ts deleted file mode 100644 index 1053115..0000000 --- a/services/message-delivery-method-web-push/src/generate-keys.ts +++ /dev/null @@ -1,45 +0,0 @@ -import webpush from "web-push"; -import PouchDB from "./PouchDB"; -import { ServerSettingsDocument } from "@hereconnect/types"; - -if (!process.env.VAPID_SUBJECT) { - throw new Error("VAPID_SUBJECT env is empty!"); -} - -const vapidKeys = webpush.generateVAPIDKeys(); - -await new PouchDB( - `${process.env.API_URL}/server_settings`, - { skip_setup: true }, -).put({ - _id: "server_settings:message_delivery_method_web_push_vapid", - type: "server_settings", - name: "message_delivery_method_web_push_vapid", - value: { - subject: process.env.VAPID_SUBJECT, - keys: vapidKeys, - }, - created_at: new Date().toISOString(), -}); - -await new PouchDB(`${process.env.API_URL}/public_settings`, { - skip_setup: true, -}).put({ - _id: "public_settings:message_delivery_method_web_push_vapid_public_key", - type: "public_settings", - name: "message_delivery_method_web_push_vapid_public_key", - value: vapidKeys.publicKey, - created_at: new Date().toISOString(), -}); - -if (process.env.GCM_API_KEY) { - await new PouchDB(`${process.env.API_URL}/public_settings`, { - skip_setup: true, - }).put({ - _id: "server_settings:message_delivery_method_web_push_gcm_api_key", - type: "server_settings", - name: "message_delivery_method_web_push_gcm_api_key", - value: process.env.GCM_API_KEY, - created_at: new Date().toISOString(), - }); -} diff --git a/services/message-delivery-method-web-push/src/setupVapidDetails.ts b/services/message-delivery-method-web-push/src/setupVapidDetails.ts index fcf73d1..da99c09 100644 --- a/services/message-delivery-method-web-push/src/setupVapidDetails.ts +++ b/services/message-delivery-method-web-push/src/setupVapidDetails.ts @@ -1,78 +1,71 @@ import webpush from "web-push"; -import { serverSettingsDb } from "./dbs"; -import { ServerSettingsDocument } from "@hereconnect/types"; - -function isType( - doc: ServerSettingsDocument | null | undefined, - name: N, -): doc is ServerSettingsDocument & { name: N } { - return !!(doc && doc.name === name); -} +import { publicSettingsDb, serverSettingsDb } from "./dbs"; +import PouchDB from "./PouchDB"; export const setupVapidDetails = async () => { + const subject = process.env.VAPID_SUBJECT; + if (!subject) { + throw new Error("VAPID_SUBJECT env is empty!"); + } + const changes = serverSettingsDb.changes({ since: "now", live: true, include_docs: true, - doc_ids: [ - "server_settings:message_delivery_method_web_push_vapid", - "public_settings:message_delivery_method_web_push_gcm_api_key", - ], + doc_ids: ["server_settings:message_delivery_method_web_push_vapid_keys"], }); - const { - rows: [vapidDetailsRow, gcmApiRow], - } = await serverSettingsDb.allDocs({ - keys: [ - "server_settings:message_delivery_method_web_push_vapid", - "public_settings:message_delivery_method_web_push_gcm_api_key", - ], - include_docs: true, - }); + const vapidDetailsKeysDoc = await serverSettingsDb + .get("server_settings:message_delivery_method_web_push_vapid_keys") + .catch(async (error) => { + if (error.name !== "not_found") { + throw new Error( + `server_settings:message_delivery_method_web_push_vapid_keys not found: ${error}`, + ); + } - if ( - !("doc" in vapidDetailsRow) || - !isType(vapidDetailsRow.doc, "message_delivery_method_web_push_vapid") - ) { - throw new Error( - `VAPID details ${"error" in vapidDetailsRow ? vapidDetailsRow.error : "not exists"}`, - ); - } + const vapidKeys = webpush.generateVAPIDKeys(); + const doc = { + _id: "server_settings:message_delivery_method_web_push_vapid_keys", + type: "server_settings", + name: "message_delivery_method_web_push_vapid_keys", + value: vapidKeys, + created_at: new Date().toISOString(), + } as const; - if ( - "doc" in gcmApiRow && - isType(gcmApiRow.doc, "message_delivery_method_web_push_gcm_api_key") - ) { - webpush.setGCMAPIKey(gcmApiRow.doc.value); - } + await Promise.all([ + serverSettingsDb.put(doc), + publicSettingsDb.put({ + _id: "public_settings:message_delivery_method_web_push_vapid_public_key", + type: "public_settings", + name: "message_delivery_method_web_push_vapid_public_key", + value: vapidKeys.publicKey, + created_at: new Date().toISOString(), + }), + ]); + + console.log("created new vapid keys"); + return doc; + }); webpush.setVapidDetails( - vapidDetailsRow.doc.value.subject, - vapidDetailsRow.doc.value.keys.publicKey, - vapidDetailsRow.doc.value.keys.privateKey, + subject, + vapidDetailsKeysDoc.value.publicKey, + vapidDetailsKeysDoc.value.privateKey, ); + if (process.env.GCM_API_KEY) { + webpush.setGCMAPIKey(process.env.GCM_API_KEY); + } + changes.on("change", (change) => { - if (!change.doc) { + const doc = change.doc; + if (!doc) { return; } - if (isType(change.doc, "message_delivery_method_web_push_vapid")) { - console.log("update vapid details"); - webpush.setVapidDetails( - change.doc.value.subject, - change.doc.value.keys.publicKey, - change.doc.value.keys.privateKey, - ); - return; - } - - if ( - "doc" in change && - isType(change.doc, "message_delivery_method_web_push_gcm_api_key") - ) { - console.log("update gcm api key"); - webpush.setGCMAPIKey(change.doc.value); - } + console.log("update vapid details"); + webpush.setVapidDetails(subject, doc.value.publicKey, doc.value.privateKey); + return; }); }; diff --git a/services/message-delivery-method-web-push/src/test-send-notification-cancel.js b/services/message-delivery-method-web-push/src/test-send-notification-cancel.js deleted file mode 100644 index 0e503b7..0000000 --- a/services/message-delivery-method-web-push/src/test-send-notification-cancel.js +++ /dev/null @@ -1,65 +0,0 @@ -import webpush from "web-push"; -import PouchDB from "./PouchDB.js"; - -if (!process.env.API_URL) { - throw new Error(`env API_URL is not set`); -} - -const settings = await new PouchDB(`${process.env.API_URL}/server_settings`, { - skip_setup: true, -}).get("server_settings:message_delivery_method_web_push:vapid"); - -webpush.setVapidDetails( - settings.vapid.subject, - settings.vapid.keys.publicKey, - settings.vapid.keys.privateKey, -); - -const notification = { - type: "cancelNotification", - notification: { - title: "test", - options: { - icon: "/images/qr-code-logo-200x200.jpg", - body: "Test push message from DevTools.", - tag: "2105ef6f-3ca6-4f99-b258-0ca23f014309", - // requireInteraction: true, - // silent: false, - // vibrate: [200, 100, 200, 100, 200, 100, 200], - data: { - url: "/chat/6ilhxu/13trvu", - payload: { tag: "2105ef6f-3ca6-4f99-b258-0ca23f014309" }, - }, - }, - }, -}; - -const { rows } = await new PouchDB( - `${process.env.API_URL}/web_push_subscriptions`, - { skip_setup: true }, -).allDocs( - process.env.WEB_PUSH_SUBSCRIPTION_ID - ? { - key: process.env.WEB_PUSH_SUBSCRIPTION_ID, - include_docs: true, - } - : { - startkey: "web_push_subscription:", - endkey: "web_push_subscription:\uFFFF", - include_docs: true, - }, -); - -await Promise.allSettled( - rows.map(async ({ doc }) => { - await webpush.sendNotification( - doc.subscription, - JSON.stringify(notification), - ); - console.log("sent ", doc._id); - }), -); - -// issues: -// 1. NO SOUND -// 2. SAFARI NO OPEN PAGE diff --git a/services/message-delivery-method-web-push/src/test-send-notification.js b/services/message-delivery-method-web-push/src/test-send-notification.js deleted file mode 100644 index 8e83c59..0000000 --- a/services/message-delivery-method-web-push/src/test-send-notification.js +++ /dev/null @@ -1,97 +0,0 @@ -import webpush from "web-push"; -import PouchDB from "./PouchDB.js"; - -if (!process.env.API_URL) { - throw new Error(`env API_URL is not set`); -} - -const { - rows: [ - { - doc: { value: vapidDetails }, - }, - { doc: gcmApiSettingsDoc }, - ], -} = await new PouchDB(`${process.env.API_URL}/server_settings`, { - skip_setup: true, -}).allDocs({ - keys: [ - "server_settings:message_delivery_method_web_push_vapid", - "public_settings:message_delivery_method_web_push_gcm_api_key", - ], - include_docs: true, -}); - -webpush.setVapidDetails( - vapidDetails.subject, - vapidDetails.keys.publicKey, - vapidDetails.keys.privateKey, -); - -if (gcmApiSettingsDoc) { - console.log(gcmApiSettingsDoc.value); - webpush.setGCMAPIKey(gcmApiSettingsDoc.value); -} - -// optionally provide an identifier that the push service uses to coalesce notifications -const topic = "chat-6ilhxu-13trvu"; - -const notification = { - type: "notification", - notification: { - title: "test", - options: { - icon: "/images/qr-code-logo-200x200.jpg", - body: "Test push message from server.", - tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f", - requireInteraction: true, - // silent: false, - // vibrate: [200, 100, 200, 100, 200, 100, 200], - // actions: [ - // { - // action: "open_url", - // title: "Открыть", - // }, - // ], - data: { - url: "/chat/6ilhxu/13trvu", - payload: { tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f" }, - }, - }, - }, -}; - -const { rows } = await new PouchDB( - `${process.env.API_URL}/web_push_subscriptions`, - { skip_setup: true }, -).allDocs( - process.env.WEB_PUSH_SUBSCRIPTION_ID - ? { - key: process.env.WEB_PUSH_SUBSCRIPTION_ID, - include_docs: true, - } - : { - startkey: "web_push_subscription:", - endkey: "web_push_subscription:\uFFFF", - include_docs: true, - }, -); - -const result = await Promise.allSettled( - rows.map(async ({ doc }) => { - await webpush.sendNotification( - doc.subscription, - JSON.stringify(notification), - { - urgency: "high", - topic, - }, - ); - console.log("sent ", doc._id); - }), -); -console.log(result); - -// issues: -// 1. NO SOUND -// 2. SAFARI NO OPEN PAGE