From 544d148f2df7518c3168f43cb6fa30323138c3ca Mon Sep 17 00:00:00 2001 From: boufni95 Date: Wed, 23 Jul 2025 20:07:21 +0000 Subject: [PATCH] encrypted notification --- env.example | 2 ++ src/services/ShockPush/index.ts | 4 ++-- src/services/main/index.ts | 25 +++++++++++++++++------ src/services/main/notificationsManager.ts | 4 ++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/env.example b/env.example index f85faf5d..83c3a411 100644 --- a/env.example +++ b/env.example @@ -33,6 +33,8 @@ #PORT=1776 #JWT_SECRET= +#SHOCK_PUSH_URL= + #Lightning Address Bridge #BRIDGE_URL=https://shockwallet.app diff --git a/src/services/ShockPush/index.ts b/src/services/ShockPush/index.ts index cbf3fa77..8e84fd5e 100644 --- a/src/services/ShockPush/index.ts +++ b/src/services/ShockPush/index.ts @@ -52,8 +52,8 @@ export class ShockPush { return nip98Header } - SendNotification = async (message: string, messagingToken: string) => { - const res = await this.client.SendNotification({ recipient_registration_tokens: [messagingToken], data: message }) + SendNotification = async (message: string, messagingTokens: string[]) => { + const res = await this.client.SendNotification({ recipient_registration_tokens: messagingTokens, data: message }) if (res.status !== 'OK') { this.logger(ERROR, `failed to send notification: ${res.status}`) } diff --git a/src/services/main/index.ts b/src/services/main/index.ts index 05cb4128..21e5233f 100644 --- a/src/services/main/index.ts +++ b/src/services/main/index.ts @@ -1,3 +1,4 @@ +import { nip44 } from 'nostr-tools' import fetch from "node-fetch" import Storage, { LoadStorageSettingsFromEnv } from '../storage/index.js' import * as Types from '../../../proto/autogenerated/ts/types.js' @@ -29,6 +30,7 @@ import webRTC from "../webRTC/index.js" import { ManagementManager } from "./managementManager.js" import { Agent } from "https" import { NotificationsManager } from "./notificationsManager.js" +import { ApplicationUser } from '../storage/entity/ApplicationUser.js' type UserOperationsSub = { id: string @@ -361,16 +363,27 @@ export default class { getLogger({ appName: app.name })("cannot notify user, not a nostr user") return } - const devices = await this.storage.applicationStorage.GetAppUserDevices(user.identifier) + const message: Types.LiveUserOperation & { requestId: string, status: 'OK' } = { operation: op, requestId: "GetLiveUserOperations", status: 'OK' } const j = JSON.stringify(message) this.nostrSend({ type: 'app', appId: app.app_id }, { type: 'content', content: j, pub: user.nostr_public_key }) - for (const device of devices) { - this.notificationsManager.SendNotification(JSON.stringify(message), device.firebase_messaging_token, { - pubkey: app.nostr_public_key!, - privateKey: app.nostr_private_key! - }) + this.SendEncryptedNotification(app, user, op) + } + + async SendEncryptedNotification(app: Application, appUser: ApplicationUser, op: Types.UserOperation) { + const devices = await this.storage.applicationStorage.GetAppUserDevices(appUser.identifier) + if (devices.length === 0 || !app.nostr_public_key || !app.nostr_private_key || !appUser.nostr_public_key) { + return } + const tokens = devices.map(d => d.firebase_messaging_token) + const ck = nip44.getConversationKey(Buffer.from(app.nostr_public_key, 'hex'), appUser.nostr_public_key) + const j = JSON.stringify(op) + const encrypted = nip44.encrypt(j, ck) + const encryptedData: { encrypted: string, app_npub: string } = { encrypted, app_npub: app.nostr_public_key } + this.notificationsManager.SendNotification(JSON.stringify(encryptedData), tokens, { + pubkey: app.nostr_public_key!, + privateKey: app.nostr_private_key! + }) } async UpdateBeacon(app: Application, content: { type: 'service', name: string }) { diff --git a/src/services/main/notificationsManager.ts b/src/services/main/notificationsManager.ts index 92ac13fd..55b3ddff 100644 --- a/src/services/main/notificationsManager.ts +++ b/src/services/main/notificationsManager.ts @@ -20,12 +20,12 @@ export class NotificationsManager { return newClient } - SendNotification = async (message: string, messagingToken: string, pair: PushPair) => { + SendNotification = async (message: string, messagingTokens: string[], pair: PushPair) => { if (!this.shockPushBaseUrl) { this.logger("ShockPush is not configured, skipping notification") return } const client = this.getClient(pair) - await client.SendNotification(message, messagingToken) + await client.SendNotification(message, messagingTokens) } } \ No newline at end of file