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.
This commit is contained in:
Juan Castro committed 2026-10-24 16:07:58 -04:00
1 parent 4fd9fae926
commit dc027f9f0e
5 files changed
+20 -17

No files matched your search

@@ -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,
});
+7 -4
View File
@@ -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<string | null> {
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. */
@@ -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,
+4 -4
View File
@@ -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':
+1 -1
View File
@@ -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;
}