encrypted notification

This commit is contained in:
boufni95 2025-07-23 20:07:21 +00:00
parent 6b43f7699b
commit 544d148f2d
4 changed files with 25 additions and 10 deletions

View file

@ -33,6 +33,8 @@
#PORT=1776 #PORT=1776
#JWT_SECRET= #JWT_SECRET=
#SHOCK_PUSH_URL=
#Lightning Address Bridge #Lightning Address Bridge
#BRIDGE_URL=https://shockwallet.app #BRIDGE_URL=https://shockwallet.app

View file

@ -52,8 +52,8 @@ export class ShockPush {
return nip98Header return nip98Header
} }
SendNotification = async (message: string, messagingToken: string) => { SendNotification = async (message: string, messagingTokens: string[]) => {
const res = await this.client.SendNotification({ recipient_registration_tokens: [messagingToken], data: message }) const res = await this.client.SendNotification({ recipient_registration_tokens: messagingTokens, data: message })
if (res.status !== 'OK') { if (res.status !== 'OK') {
this.logger(ERROR, `failed to send notification: ${res.status}`) this.logger(ERROR, `failed to send notification: ${res.status}`)
} }

View file

@ -1,3 +1,4 @@
import { nip44 } from 'nostr-tools'
import fetch from "node-fetch" import fetch from "node-fetch"
import Storage, { LoadStorageSettingsFromEnv } from '../storage/index.js' import Storage, { LoadStorageSettingsFromEnv } from '../storage/index.js'
import * as Types from '../../../proto/autogenerated/ts/types.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 { ManagementManager } from "./managementManager.js"
import { Agent } from "https" import { Agent } from "https"
import { NotificationsManager } from "./notificationsManager.js" import { NotificationsManager } from "./notificationsManager.js"
import { ApplicationUser } from '../storage/entity/ApplicationUser.js'
type UserOperationsSub = { type UserOperationsSub = {
id: string id: string
@ -361,17 +363,28 @@ export default class {
getLogger({ appName: app.name })("cannot notify user, not a nostr user") getLogger({ appName: app.name })("cannot notify user, not a nostr user")
return 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 message: Types.LiveUserOperation & { requestId: string, status: 'OK' } = { operation: op, requestId: "GetLiveUserOperations", status: 'OK' }
const j = JSON.stringify(message) const j = JSON.stringify(message)
this.nostrSend({ type: 'app', appId: app.app_id }, { type: 'content', content: j, pub: user.nostr_public_key }) this.nostrSend({ type: 'app', appId: app.app_id }, { type: 'content', content: j, pub: user.nostr_public_key })
for (const device of devices) { this.SendEncryptedNotification(app, user, op)
this.notificationsManager.SendNotification(JSON.stringify(message), device.firebase_messaging_token, { }
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!, pubkey: app.nostr_public_key!,
privateKey: app.nostr_private_key! privateKey: app.nostr_private_key!
}) })
} }
}
async UpdateBeacon(app: Application, content: { type: 'service', name: string }) { async UpdateBeacon(app: Application, content: { type: 'service', name: string }) {
if (!app.nostr_public_key) { if (!app.nostr_public_key) {

View file

@ -20,12 +20,12 @@ export class NotificationsManager {
return newClient return newClient
} }
SendNotification = async (message: string, messagingToken: string, pair: PushPair) => { SendNotification = async (message: string, messagingTokens: string[], pair: PushPair) => {
if (!this.shockPushBaseUrl) { if (!this.shockPushBaseUrl) {
this.logger("ShockPush is not configured, skipping notification") this.logger("ShockPush is not configured, skipping notification")
return return
} }
const client = this.getClient(pair) const client = this.getClient(pair)
await client.SendNotification(message, messagingToken) await client.SendNotification(message, messagingTokens)
} }
} }