From dc027f9f0ec4b9773d00c736a5c710643fceb0b7 Mon Sep 17 00:00:00 2001 From: Juan Castro Date: Fri, 23 Oct 2026 15:04:03 -0400 Subject: [PATCH] fix(push): label app messages with the sending app's stamped name Taps target the app by uid, since the stamped name is the app's title. --- .../services/push/PushService.delivery.test.ts | 4 ++-- src/backend/services/push/PushService.ts | 11 +++++++---- src/backend/services/push/pushMessage.test.ts | 12 ++++++------ src/backend/services/push/pushMessage.ts | 8 ++++---- src/backend/services/push/types.ts | 2 +- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/backend/services/push/PushService.delivery.test.ts b/src/backend/services/push/PushService.delivery.test.ts index 5c17920a2..690b7ed14 100644 --- a/src/backend/services/push/PushService.delivery.test.ts +++ b/src/backend/services/push/PushService.delivery.test.ts @@ -234,7 +234,7 @@ describe('PushService delivery', () => { title: 'New reply', body: 'see you at 5', group: 'room-7', - target: { app: app.name }, + target: { app: app.uid }, }); }); @@ -262,7 +262,7 @@ describe('PushService delivery', () => { expect(message).toMatchObject({ title: 'stamped-name', body: 'New notification from stamped-name', - target: { app: 'stamped-name' }, + target: { app: app.uid }, ttl: 90, sensitive: true, }); diff --git a/src/backend/services/push/PushService.ts b/src/backend/services/push/PushService.ts index fab652b42..ea8010a2d 100644 --- a/src/backend/services/push/PushService.ts +++ b/src/backend/services/push/PushService.ts @@ -25,7 +25,10 @@ import { type PushDeviceRegistration, } from '../../stores/push/PushDeviceStore.js'; import { runWithConcurrencyLimitSettled } from '../../util/concurrency.js'; -import { APP_MESSAGE_TYPE } from '../notification/appMessage.js'; +import { + APP_MESSAGE_TYPE, + appMessageSender, +} from '../notification/appMessage.js'; import { PuterService } from '../types.js'; import { hasPushConsent } from './pushConsent.js'; import { buildPushMessage, fitPushMessage } from './pushMessage.js'; @@ -166,7 +169,7 @@ export class PushService extends PuterService { if (appUid && !appName) return; const built = buildPushMessage( { uid, type, value }, - appName ? { name: appName } : null, + appUid && appName ? { uid: appUid, name: appName } : null, ); if (!built) return; const message = fitPushMessage(built); @@ -188,8 +191,8 @@ export class PushService extends PuterService { ): Promise { const stamped = (value.app as { name?: unknown } | undefined)?.name; if (typeof stamped === 'string' && stamped) return stamped; - const app = await this.stores.app.getByUid(appUid); - return typeof app?.name === 'string' && app.name ? app.name : null; + const row = await this.stores.app.getByUid(appUid); + return row ? (appMessageSender(appUid, row).name ?? null) : null; } /** The user's consent for the app, or their Puter preference without one. */ diff --git a/src/backend/services/push/pushMessage.test.ts b/src/backend/services/push/pushMessage.test.ts index edd271040..3458ed63b 100644 --- a/src/backend/services/push/pushMessage.test.ts +++ b/src/backend/services/push/pushMessage.test.ts @@ -25,7 +25,7 @@ import { } from './pushMessage.js'; import type { PushMessage } from './types.js'; -const app = { name: 'chat-app' }; +const app = { uid: 'app-uid-1', name: 'Chat' }; const bytes = (message: PushMessage): number => Buffer.byteLength(JSON.stringify(message), 'utf8'); @@ -123,7 +123,7 @@ describe('buildPushMessage', () => { body: 'see you at 5', icon: 'https://chat.example/icon.png', group: 'room-7', - target: { app: 'chat-app', path: '/rooms/7' }, + target: { app: 'app-uid-1', path: '/rooms/7' }, data: { room: 7 }, ttl: 120, priority: 'normal', @@ -136,7 +136,7 @@ describe('buildPushMessage', () => { app, ); expect(message?.group).toBe('n5'); - expect(message?.target).toEqual({ app: 'chat-app' }); + expect(message?.target).toEqual({ app: 'app-uid-1' }); }); it('replaces a sensitive app message with a generic one', () => { @@ -158,10 +158,10 @@ describe('buildPushMessage', () => { ); expect(message).toEqual({ uid: 'n6', - title: 'chat-app', - body: 'New notification from chat-app', + title: 'Chat', + body: 'New notification from Chat', group: 'n6', - target: { app: 'chat-app' }, + target: { app: 'app-uid-1' }, ttl: 60, priority: 'normal', sensitive: true, diff --git a/src/backend/services/push/pushMessage.ts b/src/backend/services/push/pushMessage.ts index 9db295202..4e852691c 100644 --- a/src/backend/services/push/pushMessage.ts +++ b/src/backend/services/push/pushMessage.ts @@ -85,7 +85,7 @@ const storedTitle = (source: PushSource): PushMessage | null => { const appMessage = ( source: PushSource, - app: { name: string }, + app: { uid: string; name: string }, ): PushMessage | null => { const value = source.value; const title = str(value.title); @@ -105,11 +105,11 @@ const appMessage = ( ...base, title: app.name, body: `New notification from ${app.name}`, - target: { app: app.name }, + target: { app: app.uid }, sensitive: true, }; } - const target: PushTarget = { app: app.name }; + const target: PushTarget = { app: app.uid }; const path = str(value.target); if (path) target.path = path; const body = str(value.text); @@ -127,7 +127,7 @@ const appMessage = ( /** Null for a type with no push wording, or a value missing its title. */ export const buildPushMessage = ( source: PushSource, - app: { name: string } | null, + app: { uid: string; name: string } | null, ): PushMessage | null => { switch (source.type) { case 'share.received': diff --git a/src/backend/services/push/types.ts b/src/backend/services/push/types.ts index b21612faf..04d9a981c 100644 --- a/src/backend/services/push/types.ts +++ b/src/backend/services/push/types.ts @@ -23,7 +23,7 @@ export type { PushPlatform }; /** Where a tap leads, read by Puter's own client. No app means the desktop. */ export interface PushTarget { - /** App name. */ + /** App uid. */ app?: string; path?: string; }