@waiaas/push-relay 2.9.0-rc.8 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAiBA,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC"}
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAkBA,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC"}
package/dist/bin.js CHANGED
@@ -9,6 +9,7 @@ import { PushwooshProvider } from './providers/pushwoosh-provider.js';
9
9
  import { FcmProvider } from './providers/fcm-provider.js';
10
10
  import { ConfigurablePayloadTransformer } from './transformer/payload-transformer.js';
11
11
  import { createServer } from './server.js';
12
+ import { routeByTopic } from './message-router.js';
12
13
  const require = createRequire(import.meta.url);
13
14
  const pkg = require('../package.json');
14
15
  export const VERSION = pkg.version;
@@ -53,16 +54,32 @@ async function main() {
53
54
  notifyTopicPrefix: config.relay.notify_topic_prefix,
54
55
  walletNames: config.relay.wallet_names,
55
56
  transformer,
56
- onMessage: async (walletName, payload) => {
57
- const tokens = registry.getTokensByWalletName(walletName);
58
- if (tokens.length === 0)
57
+ onMessage: async (walletName, payload, topic) => {
58
+ console.log(`[push-relay] Received ${payload.category} for wallet "${walletName}" on topic "${topic}" (title=${payload.title ?? 'none'})`);
59
+ const route = routeByTopic(walletName, topic, config.relay.sign_topic_prefix, config.relay.notify_topic_prefix, (token) => registry.getBySubscriptionToken(token));
60
+ if (route.action === 'skip_base') {
61
+ console.log(`[push-relay] Base topic "${topic}" — skipping push (no broadcast)`);
59
62
  return;
60
- const result = await provider.send(tokens, payload);
61
- if (result.invalidTokens.length > 0) {
62
- registry.removeTokens(result.invalidTokens);
63
- console.log(`[push-relay] Removed ${result.invalidTokens.length} invalid token(s)`);
64
63
  }
65
- console.log(`[push-relay] ${payload.category} ${walletName}: sent=${result.sent}, failed=${result.failed}`);
64
+ if (route.action === 'skip_unknown') {
65
+ console.log(`[push-relay] Cannot extract subscriptionToken from topic "${topic}", skipping`);
66
+ return;
67
+ }
68
+ if (route.action === 'skip_no_device') {
69
+ console.log(`[push-relay] No device found for subscriptionToken "${route.subscriptionToken}", skipping`);
70
+ return;
71
+ }
72
+ try {
73
+ const result = await provider.send([route.device.pushToken], payload);
74
+ if (result.invalidTokens.length > 0) {
75
+ registry.removeTokens(result.invalidTokens);
76
+ console.log(`[push-relay] Removed ${result.invalidTokens.length} invalid token(s)`);
77
+ }
78
+ console.log(`[push-relay] ${payload.category} → ${walletName} (device=${route.subscriptionToken}): sent=${result.sent}, failed=${result.failed}`);
79
+ }
80
+ catch (sendErr) {
81
+ console.error(`[push-relay] Failed to send push to ${walletName} (device=${route.subscriptionToken}):`, sendErr.message);
82
+ }
66
83
  },
67
84
  onError: (err) => {
68
85
  console.error('[push-relay] Error:', err.message);
@@ -71,6 +88,18 @@ async function main() {
71
88
  // Start ntfy subscription
72
89
  subscriber.start();
73
90
  console.log(`[push-relay] Subscribing to ${config.relay.wallet_names.length} wallet(s): ${config.relay.wallet_names.join(', ')}`);
91
+ // Restore subscription-token-based topics from DB
92
+ const devices = registry.listAll();
93
+ let restoredTopics = 0;
94
+ for (const device of devices) {
95
+ if (device.subscriptionToken) {
96
+ subscriber.addTopics(device.walletName, `${config.relay.sign_topic_prefix}-${device.walletName}-${device.subscriptionToken}`, `${config.relay.notify_topic_prefix}-${device.walletName}-${device.subscriptionToken}`);
97
+ restoredTopics++;
98
+ }
99
+ }
100
+ if (restoredTopics > 0) {
101
+ console.log(`[push-relay] Restored ${restoredTopics} device topic(s) from DB`);
102
+ }
74
103
  // Create and start HTTP server
75
104
  const app = createServer({
76
105
  registry,
@@ -78,6 +107,8 @@ async function main() {
78
107
  provider,
79
108
  apiKey: config.relay.server.api_key,
80
109
  ntfyServer: config.relay.ntfy_server,
110
+ signTopicPrefix: config.relay.sign_topic_prefix,
111
+ notifyTopicPrefix: config.relay.notify_topic_prefix,
81
112
  version: VERSION,
82
113
  });
83
114
  const server = serve({
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAC9D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC;AAE3C,iBAAiB;AACjB,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;AACzF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;AAE9E,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,WAAW,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEvC,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IAE7C,2BAA2B;IAC3B,IAAI,QAAuB,CAAC;IAC5B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC/C,QAAQ,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAU,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAI,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IAED,2BAA2B;IAC3B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,4CAA4C;IAC5C,IAAI,WAA4C,CAAC;IACjD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,WAAW,GAAG,IAAI,8BAA8B,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IAC1F,CAAC;IAED,6BAA6B;IAC7B,MAAM,UAAU,GAAG,IAAI,cAAc,CAAC;QACpC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;QACpC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB;QAC/C,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB;QACnD,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY;QACtC,WAAW;QACX,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC9C,OAAO,CAAC,GAAG,CACT,yBAAyB,OAAO,CAAC,QAAQ,gBAAgB,UAAU,eAAe,KAAK,YAAY,OAAO,CAAC,KAAK,IAAI,MAAM,GAAG,CAC9H,CAAC;YAEF,MAAM,KAAK,GAAG,YAAY,CACxB,UAAU,EACV,KAAK,EACL,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAC9B,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAChC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAClD,CAAC;YAEF,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,kCAAkC,CAAC,CAAC;gBACjF,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,6DAA6D,KAAK,aAAa,CAAC,CAAC;gBAC7F,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;gBACtC,OAAO,CAAC,GAAG,CAAC,uDAAuD,KAAK,CAAC,iBAAiB,aAAa,CAAC,CAAC;gBACzG,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;gBACvE,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;oBAC5C,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,aAAa,CAAC,MAAM,mBAAmB,CAAC,CAAC;gBACtF,CAAC;gBACD,OAAO,CAAC,GAAG,CACT,gBAAgB,OAAO,CAAC,QAAQ,MAAM,UAAU,YAAY,KAAK,CAAC,iBAAiB,WAAW,MAAM,CAAC,IAAI,YAAY,MAAM,CAAC,MAAM,EAAE,CACrI,CAAC;YACJ,CAAC;YAAC,OAAO,OAAO,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CACX,uCAAuC,UAAU,YAAY,KAAK,CAAC,iBAAiB,IAAI,EACvF,OAAiB,CAAC,OAAO,CAC3B,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACf,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;KACF,CAAC,CAAC;IAEH,0BAA0B;IAC1B,UAAU,CAAC,KAAK,EAAE,CAAC;IACnB,OAAO,CAAC,GAAG,CACT,+BAA+B,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,eAAe,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrH,CAAC;IAEF,kDAAkD;IAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IACnC,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC7B,UAAU,CAAC,SAAS,CAClB,MAAM,CAAC,UAAU,EACjB,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,iBAAiB,EAAE,EACpF,GAAG,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,iBAAiB,EAAE,CACvF,CAAC;YACF,cAAc,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IACD,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,cAAc,0BAA0B,CAAC,CAAC;IACjF,CAAC;IAED,+BAA+B;IAC/B,MAAM,GAAG,GAAG,YAAY,CAAC;QACvB,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;QACnC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;QACpC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB;QAC/C,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB;QACnD,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,KAAK,CAAC;QACnB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI;QAC9B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI;KACnC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CACT,iBAAiB,OAAO,iBAAiB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAChG,CAAC;IAEF,oBAAoB;IACpB,MAAM,mBAAmB,GAAG,MAAM,CAAC;IAEnC,KAAK,UAAU,QAAQ,CAAC,MAAc;QACpC,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,6BAA6B,CAAC,CAAC;QAEjE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACxB,aAAa,CAAC,KAAK,EAAE,CAAC;QAEtB,qCAAqC;QACrC,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;QAExB,uBAAuB;QACvB,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,oBAAoB;QACpB,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEjB,YAAY,CAAC,aAAa,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { DeviceRecord } from './registry/device-registry.js';
2
+ export interface TopicRoutingResult {
3
+ action: 'skip_base' | 'skip_unknown' | 'skip_no_device' | 'unicast';
4
+ subscriptionToken?: string;
5
+ device?: DeviceRecord;
6
+ }
7
+ /**
8
+ * Determine routing for an incoming ntfy message based on its topic.
9
+ *
10
+ * - Base topics (waiaas-sign-{wallet}, waiaas-notify-{wallet}) → skip (no broadcast)
11
+ * - Device topics (waiaas-sign-{wallet}-{token}) → unicast to the matching device
12
+ * - Unknown topic format → skip
13
+ */
14
+ export declare function routeByTopic(walletName: string, topic: string, signTopicPrefix: string, notifyTopicPrefix: string, getDevice: (subscriptionToken: string) => DeviceRecord | null): TopicRoutingResult;
15
+ //# sourceMappingURL=message-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-router.d.ts","sourceRoot":"","sources":["../src/message-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,GAC5D,kBAAkB,CA2BpB"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Determine routing for an incoming ntfy message based on its topic.
3
+ *
4
+ * - Base topics (waiaas-sign-{wallet}, waiaas-notify-{wallet}) → skip (no broadcast)
5
+ * - Device topics (waiaas-sign-{wallet}-{token}) → unicast to the matching device
6
+ * - Unknown topic format → skip
7
+ */
8
+ export function routeByTopic(walletName, topic, signTopicPrefix, notifyTopicPrefix, getDevice) {
9
+ const signBase = `${signTopicPrefix}-${walletName}`;
10
+ const notifyBase = `${notifyTopicPrefix}-${walletName}`;
11
+ // Skip base topics — no broadcast
12
+ if (topic === signBase || topic === notifyBase) {
13
+ return { action: 'skip_base' };
14
+ }
15
+ // Extract subscriptionToken from device topic suffix
16
+ let subscriptionToken;
17
+ if (topic.startsWith(`${signBase}-`)) {
18
+ subscriptionToken = topic.slice(signBase.length + 1);
19
+ }
20
+ else if (topic.startsWith(`${notifyBase}-`)) {
21
+ subscriptionToken = topic.slice(notifyBase.length + 1);
22
+ }
23
+ if (!subscriptionToken) {
24
+ return { action: 'skip_unknown' };
25
+ }
26
+ const device = getDevice(subscriptionToken);
27
+ if (!device) {
28
+ return { action: 'skip_no_device', subscriptionToken };
29
+ }
30
+ return { action: 'unicast', subscriptionToken, device };
31
+ }
32
+ //# sourceMappingURL=message-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-router.js","sourceRoot":"","sources":["../src/message-router.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,UAAkB,EAClB,KAAa,EACb,eAAuB,EACvB,iBAAyB,EACzB,SAA6D;IAE7D,MAAM,QAAQ,GAAG,GAAG,eAAe,IAAI,UAAU,EAAE,CAAC;IACpD,MAAM,UAAU,GAAG,GAAG,iBAAiB,IAAI,UAAU,EAAE,CAAC;IAExD,kCAAkC;IAClC,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QAC/C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjC,CAAC;IAED,qDAAqD;IACrD,IAAI,iBAAqC,CAAC;IAC1C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;QACrC,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,UAAU,GAAG,CAAC,EAAE,CAAC;QAC9C,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACzD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC"}
@@ -2,6 +2,7 @@ export interface DeviceRecord {
2
2
  pushToken: string;
3
3
  walletName: string;
4
4
  platform: 'ios' | 'android';
5
+ subscriptionToken: string | null;
5
6
  createdAt: number;
6
7
  updatedAt: number;
7
8
  }
@@ -9,10 +10,16 @@ export declare class DeviceRegistry {
9
10
  private readonly db;
10
11
  constructor(dbPath: string);
11
12
  private init;
12
- register(walletName: string, pushToken: string, platform: 'ios' | 'android'): void;
13
+ register(walletName: string, pushToken: string, platform: 'ios' | 'android'): {
14
+ subscriptionToken: string;
15
+ };
16
+ getSubscriptionToken(pushToken: string): string | null;
13
17
  unregister(pushToken: string): boolean;
14
18
  getTokensByWalletName(walletName: string): string[];
15
19
  removeTokens(tokens: string[]): void;
20
+ getByPushToken(pushToken: string): DeviceRecord | null;
21
+ getBySubscriptionToken(token: string): DeviceRecord | null;
22
+ listAll(): DeviceRecord[];
16
23
  count(): number;
17
24
  close(): void;
18
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"device-registry.d.ts","sourceRoot":"","sources":["../../src/registry/device-registry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,EAAE,MAAM;IAO1B,OAAO,CAAC,IAAI;IAeZ,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI;IAYlF,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAKtC,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAOnD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAMpC,KAAK,IAAI,MAAM;IAKf,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"device-registry.d.ts","sourceRoot":"","sources":["../../src/registry/device-registry.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,EAAE,MAAM;IAO1B,OAAO,CAAC,IAAI;IAuBZ,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE;IAkB3G,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMtD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAKtC,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAOnD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAMpC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAmBtD,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAmB1D,OAAO,IAAI,YAAY,EAAE;IAkBzB,KAAK,IAAI,MAAM;IAKf,KAAK,IAAI,IAAI;CAGd"}
@@ -1,4 +1,5 @@
1
1
  import Database from 'better-sqlite3';
2
+ import { randomBytes } from 'node:crypto';
2
3
  export class DeviceRegistry {
3
4
  db;
4
5
  constructor(dbPath) {
@@ -13,6 +14,7 @@ export class DeviceRegistry {
13
14
  push_token TEXT PRIMARY KEY,
14
15
  wallet_name TEXT NOT NULL,
15
16
  platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
17
+ subscription_token TEXT,
16
18
  created_at INTEGER NOT NULL DEFAULT (unixepoch()),
17
19
  updated_at INTEGER NOT NULL DEFAULT (unixepoch())
18
20
  )
@@ -20,17 +22,35 @@ export class DeviceRegistry {
20
22
  this.db.exec(`
21
23
  CREATE INDEX IF NOT EXISTS idx_devices_wallet_name ON devices(wallet_name)
22
24
  `);
25
+ // Migration: add subscription_token column if missing (existing DBs)
26
+ // SQLite does not allow UNIQUE constraint in ALTER TABLE ADD COLUMN
27
+ const cols = this.db.prepare("PRAGMA table_info('devices')").all().map(c => c.name);
28
+ if (!cols.includes('subscription_token')) {
29
+ this.db.exec(`ALTER TABLE devices ADD COLUMN subscription_token TEXT`);
30
+ }
31
+ this.db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_devices_subscription_token ON devices(subscription_token)`);
23
32
  }
24
33
  register(walletName, pushToken, platform) {
25
34
  const now = Math.floor(Date.now() / 1000);
35
+ const newToken = randomBytes(4).toString('hex');
26
36
  this.db.prepare(`
27
- INSERT INTO devices (push_token, wallet_name, platform, created_at, updated_at)
28
- VALUES (?, ?, ?, ?, ?)
37
+ INSERT INTO devices (push_token, wallet_name, platform, subscription_token, created_at, updated_at)
38
+ VALUES (?, ?, ?, ?, ?, ?)
29
39
  ON CONFLICT(push_token) DO UPDATE SET
30
40
  wallet_name = excluded.wallet_name,
31
41
  platform = excluded.platform,
42
+ subscription_token = COALESCE(devices.subscription_token, excluded.subscription_token),
32
43
  updated_at = excluded.updated_at
33
- `).run(pushToken, walletName, platform, now, now);
44
+ `).run(pushToken, walletName, platform, newToken, now, now);
45
+ // Retrieve the actual token (may be the existing one on conflict)
46
+ const row = this.db.prepare('SELECT subscription_token FROM devices WHERE push_token = ?')
47
+ .get(pushToken);
48
+ return { subscriptionToken: row.subscription_token };
49
+ }
50
+ getSubscriptionToken(pushToken) {
51
+ const row = this.db.prepare('SELECT subscription_token FROM devices WHERE push_token = ?')
52
+ .get(pushToken);
53
+ return row?.subscription_token ?? null;
34
54
  }
35
55
  unregister(pushToken) {
36
56
  const result = this.db.prepare('DELETE FROM devices WHERE push_token = ?').run(pushToken);
@@ -48,6 +68,52 @@ export class DeviceRegistry {
48
68
  const placeholders = tokens.map(() => '?').join(',');
49
69
  this.db.prepare(`DELETE FROM devices WHERE push_token IN (${placeholders})`).run(...tokens);
50
70
  }
71
+ getByPushToken(pushToken) {
72
+ const row = this.db.prepare(`
73
+ SELECT push_token, wallet_name, platform, subscription_token, created_at, updated_at
74
+ FROM devices WHERE push_token = ?
75
+ `).get(pushToken);
76
+ if (!row)
77
+ return null;
78
+ return {
79
+ pushToken: row.push_token,
80
+ walletName: row.wallet_name,
81
+ platform: row.platform,
82
+ subscriptionToken: row.subscription_token,
83
+ createdAt: row.created_at,
84
+ updatedAt: row.updated_at,
85
+ };
86
+ }
87
+ getBySubscriptionToken(token) {
88
+ const row = this.db.prepare(`
89
+ SELECT push_token, wallet_name, platform, subscription_token, created_at, updated_at
90
+ FROM devices WHERE subscription_token = ?
91
+ `).get(token);
92
+ if (!row)
93
+ return null;
94
+ return {
95
+ pushToken: row.push_token,
96
+ walletName: row.wallet_name,
97
+ platform: row.platform,
98
+ subscriptionToken: row.subscription_token,
99
+ createdAt: row.created_at,
100
+ updatedAt: row.updated_at,
101
+ };
102
+ }
103
+ listAll() {
104
+ const rows = this.db.prepare(`
105
+ SELECT push_token, wallet_name, platform, subscription_token, created_at, updated_at
106
+ FROM devices
107
+ `).all();
108
+ return rows.map((row) => ({
109
+ pushToken: row.push_token,
110
+ walletName: row.wallet_name,
111
+ platform: row.platform,
112
+ subscriptionToken: row.subscription_token,
113
+ createdAt: row.created_at,
114
+ updatedAt: row.updated_at,
115
+ }));
116
+ }
51
117
  count() {
52
118
  const row = this.db.prepare('SELECT COUNT(*) as count FROM devices').get();
53
119
  return row.count;
@@ -1 +1 @@
1
- {"version":3,"file":"device-registry.js","sourceRoot":"","sources":["../../src/registry/device-registry.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAUtC,MAAM,OAAO,cAAc;IACR,EAAE,CAAoB;IAEvC,YAAY,MAAc;QACxB,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAEO,IAAI;QACV,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;KAQZ,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;KAEZ,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,UAAkB,EAAE,SAAiB,EAAE,QAA2B;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;;KAOf,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1F,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,qBAAqB,CAAC,UAAkB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE;aACjB,OAAO,CAAC,sDAAsD,CAAC;aAC/D,GAAG,CAAC,UAAU,CAAkC,CAAC;QACpD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,YAAY,CAAC,MAAgB;QAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,4CAA4C,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC9F,CAAC;IAED,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,EAAuB,CAAC;QAChG,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"device-registry.js","sourceRoot":"","sources":["../../src/registry/device-registry.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@ export interface DeviceRoutesOpts {
6
6
  registry: DeviceRegistry;
7
7
  subscriber: NtfySubscriber;
8
8
  provider: IPushProvider;
9
+ signTopicPrefix: string;
10
+ notifyTopicPrefix: string;
9
11
  version?: string;
10
12
  }
11
13
  export declare function createDeviceRoutes(opts: DeviceRoutesOpts): Hono;
@@ -1 +1 @@
1
- {"version":3,"file":"device-routes.d.ts","sourceRoot":"","sources":["../../src/registry/device-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAQnE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CA8C/D"}
1
+ {"version":3,"file":"device-routes.d.ts","sourceRoot":"","sources":["../../src/registry/device-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAQnE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CA6E/D"}
@@ -7,7 +7,7 @@ const DeviceRegistrationSchema = z.object({
7
7
  });
8
8
  export function createDeviceRoutes(opts) {
9
9
  const app = new Hono();
10
- const { registry, subscriber, provider, version } = opts;
10
+ const { registry, subscriber, provider, signTopicPrefix, notifyTopicPrefix, version } = opts;
11
11
  // POST /devices — register device token
12
12
  app.post('/devices', async (c) => {
13
13
  const body = await c.req.json();
@@ -16,16 +16,34 @@ export function createDeviceRoutes(opts) {
16
16
  return c.json({ error: 'Invalid request', details: parsed.error.issues }, 400);
17
17
  }
18
18
  const { walletName, pushToken, platform } = parsed.data;
19
- registry.register(walletName, pushToken, platform);
20
- return c.json({ status: 'registered' }, 201);
19
+ const result = registry.register(walletName, pushToken, platform);
20
+ const token = result.subscriptionToken;
21
+ // Dynamically subscribe to subscription-token-based topics
22
+ subscriber.addTopics(walletName, `${signTopicPrefix}-${walletName}-${token}`, `${notifyTopicPrefix}-${walletName}-${token}`);
23
+ return c.json({ status: 'registered', subscription_token: token }, 201);
24
+ });
25
+ // GET /devices/:token/subscription-token — get subscription token for a device
26
+ app.get('/devices/:token/subscription-token', (c) => {
27
+ const token = c.req.param('token');
28
+ const subToken = registry.getSubscriptionToken(token);
29
+ if (subToken === null) {
30
+ return c.json({ error: 'Device not found' }, 404);
31
+ }
32
+ return c.json({ subscription_token: subToken });
21
33
  });
22
34
  // DELETE /devices/:token — unregister device token
23
35
  app.delete('/devices/:token', (c) => {
24
- const token = c.req.param('token');
25
- const removed = registry.unregister(token);
36
+ const pushToken = c.req.param('token');
37
+ // Look up device before deletion to get topic info
38
+ const device = registry.getByPushToken(pushToken);
39
+ const removed = registry.unregister(pushToken);
26
40
  if (!removed) {
27
41
  return c.json({ error: 'Token not found' }, 404);
28
42
  }
43
+ // Dynamically unsubscribe from subscription-token-based topics
44
+ if (device?.subscriptionToken) {
45
+ subscriber.removeTopics(`${signTopicPrefix}-${device.walletName}-${device.subscriptionToken}`, `${notifyTopicPrefix}-${device.walletName}-${device.subscriptionToken}`);
46
+ }
29
47
  return c.body(null, 204);
30
48
  });
31
49
  // GET /health — health check
@@ -1 +1 @@
1
- {"version":3,"file":"device-routes.js","sourceRoot":"","sources":["../../src/registry/device-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;CACrC,CAAC,CAAC;AASH,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEzD,wCAAwC;IACxC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAY,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;QACxD,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,mDAAmD;IACnD,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,cAAc,EAAE,CAAC;QACtD,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,OAAO,IAAI,SAAS;YAC7B,IAAI,EAAE;gBACJ,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,MAAM,EAAE,UAAU,CAAC,UAAU;aAC9B;YACD,IAAI,EAAE;gBACJ,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,UAAU,EAAE,aAAa;aAC1B;YACD,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"device-routes.js","sourceRoot":"","sources":["../../src/registry/device-routes.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -8,6 +8,8 @@ export interface ServerOpts {
8
8
  provider: IPushProvider;
9
9
  apiKey: string;
10
10
  ntfyServer: string;
11
+ signTopicPrefix: string;
12
+ notifyTopicPrefix: string;
11
13
  version?: string;
12
14
  }
13
15
  export declare function createServer(opts: ServerOpts): Hono;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAkBnD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAkBnD"}
package/dist/server.js CHANGED
@@ -4,9 +4,9 @@ import { createDeviceRoutes } from './registry/device-routes.js';
4
4
  import { createSignResponseRoutes } from './relay/sign-response-routes.js';
5
5
  export function createServer(opts) {
6
6
  const app = new Hono();
7
- const { registry, subscriber, provider, apiKey, ntfyServer, version } = opts;
7
+ const { registry, subscriber, provider, apiKey, ntfyServer, signTopicPrefix, notifyTopicPrefix, version } = opts;
8
8
  // Health check is public
9
- const deviceRoutes = createDeviceRoutes({ registry, subscriber, provider, version });
9
+ const deviceRoutes = createDeviceRoutes({ registry, subscriber, provider, signTopicPrefix, notifyTopicPrefix, version });
10
10
  // Sign response relay (public — wallet apps call this without API key)
11
11
  const signResponseRoutes = createSignResponseRoutes({ ntfyServer });
12
12
  // Apply API key auth to device registration/deletion endpoints only
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAc3E,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAE7E,yBAAyB;IACzB,MAAM,YAAY,GAAG,kBAAkB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAErF,uEAAuE;IACvE,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAEpE,oEAAoE;IACpE,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAEzC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC7B,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAEnC,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAgB3E,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEjH,yBAAyB;IACzB,MAAM,YAAY,GAAG,kBAAkB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,CAAC;IAEzH,uEAAuE;IACvE,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAEpE,oEAAoE;IACpE,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAEzC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC7B,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAEnC,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -12,6 +12,14 @@ export interface ParsedNtfyMessage {
12
12
  title?: string;
13
13
  priority?: number;
14
14
  tags?: string[];
15
+ /** Present when message exceeds ntfy size limit and is auto-converted to file attachment. */
16
+ attachment?: {
17
+ name: string;
18
+ type: string;
19
+ size: number;
20
+ expires: number;
21
+ url: string;
22
+ };
15
23
  }
16
24
  export declare function determineMessageType(topic: string, signPrefix: string, notifyPrefix: string): 'sign_request' | 'notification' | null;
17
25
  export declare function mapPriority(ntfyPriority: number | undefined): 'high' | 'normal';
@@ -1 +1 @@
1
- {"version":3,"file":"message-parser.d.ts","sourceRoot":"","sources":["../../src/subscriber/message-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,EAAE,cAAc,GAAG,cAAc,CAAC;IAC1C,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,cAAc,GAAG,IAAI,CAIxC;AAED,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAE/E;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAI7D;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAI7E;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,cAAc,GAAG,cAAc,GACpC,WAAW,CAwBb"}
1
+ {"version":3,"file":"message-parser.d.ts","sourceRoot":"","sources":["../../src/subscriber/message-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,EAAE,cAAc,GAAG,cAAc,CAAC;IAC1C,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,6FAA6F;IAC7F,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,cAAc,GAAG,cAAc,GAAG,IAAI,CAIxC;AAED,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAE/E;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAI7D;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAI7E;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,cAAc,GAAG,cAAc,GACpC,WAAW,CAwBb"}
@@ -1 +1 @@
1
- {"version":3,"file":"message-parser.js","sourceRoot":"","sources":["../../src/subscriber/message-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-parser.js","sourceRoot":"","sources":["../../src/subscriber/message-parser.ts"],"names":[],"mappings":"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"}
@@ -5,13 +5,20 @@ export interface NtfySubscriberOpts {
5
5
  signTopicPrefix: string;
6
6
  notifyTopicPrefix: string;
7
7
  walletNames: string[];
8
- onMessage: (walletName: string, payload: PushPayload) => Promise<void>;
8
+ onMessage: (walletName: string, payload: PushPayload, topic: string) => Promise<void>;
9
9
  onError?: (error: Error) => void;
10
10
  transformer?: IPayloadTransformer;
11
+ /** Per-wallet topic overrides (key: walletName). When set, uses these topics instead of prefix pattern. */
12
+ topicOverrides?: Map<string, {
13
+ signTopic: string;
14
+ notifyTopic: string;
15
+ }>;
11
16
  }
12
17
  export declare class NtfySubscriber {
13
18
  private readonly opts;
14
19
  private readonly abortControllers;
20
+ /** Reverse mapping: topic → walletName */
21
+ private readonly topicWalletMap;
15
22
  private readonly transformer?;
16
23
  private _connected;
17
24
  private _topicCount;
@@ -19,9 +26,19 @@ export declare class NtfySubscriber {
19
26
  get connected(): boolean;
20
27
  get topicCount(): number;
21
28
  start(): void;
29
+ /** Dynamically add topics for a wallet (e.g. on device registration). */
30
+ addTopics(walletName: string, signTopic: string, notifyTopic: string): void;
31
+ /** Dynamically remove topics (e.g. on device unregistration). */
32
+ removeTopics(signTopic: string, notifyTopic: string): void;
22
33
  stop(): Promise<void>;
23
34
  private subscribeTopic;
24
35
  private connectSse;
36
+ /**
37
+ * Download ntfy file attachment and process as normal message.
38
+ * When message payload exceeds ntfy's size limit (~4KB), ntfy auto-converts
39
+ * to a file attachment. The attachment contains the original request JSON body.
40
+ */
41
+ private fetchAttachmentAndProcess;
25
42
  private delay;
26
43
  }
27
44
  //# sourceMappingURL=ntfy-subscriber.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ntfy-subscriber.d.ts","sourceRoot":"","sources":["../../src/subscriber/ntfy-subscriber.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AAE1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAKjF,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IACvE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAsB;IACnD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAK;gBAEZ,IAAI,EAAE,kBAAkB;IAKpC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,KAAK,IAAI,IAAI;IAYP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,OAAO,CAAC,cAAc;YAMR,UAAU;IA+ExB,OAAO,CAAC,KAAK;CAQd"}
1
+ {"version":3,"file":"ntfy-subscriber.d.ts","sourceRoot":"","sources":["../../src/subscriber/ntfy-subscriber.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AAE1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AASjF,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,2GAA2G;IAC3G,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IACvE,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAsB;IACnD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAK;gBAEZ,IAAI,EAAE,kBAAkB;IAKpC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,KAAK,IAAI,IAAI;IAab,yEAAyE;IACzE,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAW3E,iEAAiE;IACjE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAepD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,CAAC,cAAc;YAOR,UAAU;IAyHxB;;;;OAIG;YACW,yBAAyB;IA2CvC,OAAO,CAAC,KAAK;CAQd"}
@@ -1,9 +1,14 @@
1
1
  import { buildPushPayload, determineMessageType } from './message-parser.js';
2
+ import { get as httpsGet } from 'node:https';
3
+ import { get as httpGet } from 'node:http';
4
+ import { createUnzip, createBrotliDecompress } from 'node:zlib';
2
5
  const MAX_RECONNECT_DELAY_MS = 60_000;
3
6
  const INITIAL_RECONNECT_DELAY_MS = 1_000;
4
7
  export class NtfySubscriber {
5
8
  opts;
6
9
  abortControllers = new Map();
10
+ /** Reverse mapping: topic → walletName */
11
+ topicWalletMap = new Map();
7
12
  transformer;
8
13
  _connected = false;
9
14
  _topicCount = 0;
@@ -19,24 +24,53 @@ export class NtfySubscriber {
19
24
  }
20
25
  start() {
21
26
  for (const walletName of this.opts.walletNames) {
22
- const signTopic = `${this.opts.signTopicPrefix}-${walletName}`;
23
- const notifyTopic = `${this.opts.notifyTopicPrefix}-${walletName}`;
27
+ const override = this.opts.topicOverrides?.get(walletName);
28
+ const signTopic = override?.signTopic ?? `${this.opts.signTopicPrefix}-${walletName}`;
29
+ const notifyTopic = override?.notifyTopic ?? `${this.opts.notifyTopicPrefix}-${walletName}`;
24
30
  this.subscribeTopic(signTopic, walletName);
25
31
  this.subscribeTopic(notifyTopic, walletName);
26
32
  }
27
33
  this._topicCount = this.opts.walletNames.length * 2;
28
34
  this._connected = true;
29
35
  }
36
+ /** Dynamically add topics for a wallet (e.g. on device registration). */
37
+ addTopics(walletName, signTopic, notifyTopic) {
38
+ if (!this.abortControllers.has(signTopic)) {
39
+ this.subscribeTopic(signTopic, walletName);
40
+ this._topicCount++;
41
+ }
42
+ if (!this.abortControllers.has(notifyTopic)) {
43
+ this.subscribeTopic(notifyTopic, walletName);
44
+ this._topicCount++;
45
+ }
46
+ }
47
+ /** Dynamically remove topics (e.g. on device unregistration). */
48
+ removeTopics(signTopic, notifyTopic) {
49
+ if (this.abortControllers.has(signTopic)) {
50
+ this.abortControllers.get(signTopic).abort();
51
+ this.abortControllers.delete(signTopic);
52
+ this.topicWalletMap.delete(signTopic);
53
+ this._topicCount--;
54
+ }
55
+ if (this.abortControllers.has(notifyTopic)) {
56
+ this.abortControllers.get(notifyTopic).abort();
57
+ this.abortControllers.delete(notifyTopic);
58
+ this.topicWalletMap.delete(notifyTopic);
59
+ this._topicCount--;
60
+ }
61
+ }
30
62
  async stop() {
31
63
  this._connected = false;
32
64
  for (const [, controller] of this.abortControllers) {
33
65
  controller.abort();
34
66
  }
35
67
  this.abortControllers.clear();
68
+ this.topicWalletMap.clear();
36
69
  }
37
70
  subscribeTopic(topic, walletName) {
38
71
  const controller = new AbortController();
39
72
  this.abortControllers.set(topic, controller);
73
+ this.topicWalletMap.set(topic, walletName);
40
74
  void this.connectSse(topic, walletName, controller, INITIAL_RECONNECT_DELAY_MS);
41
75
  }
42
76
  async connectSse(topic, walletName, controller, reconnectDelay) {
@@ -44,47 +78,83 @@ export class NtfySubscriber {
44
78
  return;
45
79
  try {
46
80
  const url = `${this.opts.ntfyServer}/${topic}/sse`;
47
- const res = await fetch(url, { signal: controller.signal });
48
- if (!res.ok || !res.body) {
49
- throw new Error(`SSE connection failed for ${topic}: HTTP ${res.status}`);
81
+ const isHttps = url.startsWith('https');
82
+ const getter = isHttps ? httpsGet : httpGet;
83
+ const res = await new Promise((resolve, reject) => {
84
+ const req = getter(url, {
85
+ headers: {
86
+ 'Accept': 'text/event-stream',
87
+ 'Accept-Encoding': 'identity',
88
+ },
89
+ }, resolve);
90
+ req.on('error', reject);
91
+ controller.signal.addEventListener('abort', () => req.destroy(), { once: true });
92
+ });
93
+ if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
94
+ res.resume(); // Drain
95
+ throw new Error(`SSE connection failed for ${topic}: HTTP ${String(res.statusCode)}`);
50
96
  }
51
97
  // Reset reconnect delay on successful connection
52
98
  const nextDelay = INITIAL_RECONNECT_DELAY_MS;
53
- const reader = res.body.getReader();
54
- const decoder = new TextDecoder();
99
+ // Explicit decompression based on Content-Encoding header.
100
+ // node:http does NOT auto-decompress, giving us full control.
101
+ const encoding = res.headers['content-encoding'];
102
+ let dataStream = res;
103
+ if (encoding === 'gzip' || encoding === 'x-gzip' || encoding === 'deflate') {
104
+ dataStream = res.pipe(createUnzip());
105
+ }
106
+ else if (encoding === 'br') {
107
+ dataStream = res.pipe(createBrotliDecompress());
108
+ }
109
+ // Wire abort to destroy streams
110
+ controller.signal.addEventListener('abort', () => {
111
+ res.destroy();
112
+ }, { once: true });
113
+ // SSE line-based parsing via Node.js Readable events
55
114
  let buffer = '';
56
- while (!controller.signal.aborted) {
57
- const { done, value } = await reader.read();
58
- if (done)
59
- break;
60
- buffer += decoder.decode(value, { stream: true });
61
- const lines = buffer.split('\n');
62
- buffer = lines.pop() ?? '';
63
- for (const line of lines) {
64
- if (!line.startsWith('data: '))
65
- continue;
66
- const dataStr = line.slice(6).trim();
67
- if (!dataStr)
68
- continue;
69
- try {
70
- const ntfyMsg = JSON.parse(dataStr);
71
- if (!ntfyMsg.message)
115
+ await new Promise((resolve, reject) => {
116
+ dataStream.on('data', (chunk) => {
117
+ if (controller.signal.aborted)
118
+ return;
119
+ buffer += chunk.toString('utf-8');
120
+ const lines = buffer.split('\n');
121
+ buffer = lines.pop() ?? '';
122
+ for (const line of lines) {
123
+ if (!line.startsWith('data: '))
72
124
  continue;
73
- const effectiveTopic = ntfyMsg.topic ?? topic;
74
- const type = determineMessageType(effectiveTopic, this.opts.signTopicPrefix, this.opts.notifyTopicPrefix);
75
- if (!type)
125
+ const dataStr = line.slice(6).trim();
126
+ if (!dataStr)
76
127
  continue;
77
- let payload = buildPushPayload(ntfyMsg, type);
78
- if (this.transformer) {
79
- payload = this.transformer.transform(payload);
128
+ try {
129
+ const ntfyMsg = JSON.parse(dataStr);
130
+ if (!ntfyMsg.message)
131
+ continue;
132
+ // ntfy converts messages exceeding size limit to file attachments.
133
+ // Download the attachment to recover the original message. (#243)
134
+ if (ntfyMsg.attachment?.url) {
135
+ void this.fetchAttachmentAndProcess(ntfyMsg, walletName, topic);
136
+ continue;
137
+ }
138
+ const effectiveTopic = ntfyMsg.topic ?? topic;
139
+ const type = determineMessageType(effectiveTopic, this.opts.signTopicPrefix, this.opts.notifyTopicPrefix);
140
+ if (!type)
141
+ continue;
142
+ let payload = buildPushPayload(ntfyMsg, type);
143
+ if (this.transformer) {
144
+ payload = this.transformer.transform(payload);
145
+ }
146
+ void this.opts.onMessage(walletName, payload, effectiveTopic);
147
+ }
148
+ catch (err) {
149
+ this.opts.onError?.(err instanceof Error ? err : new Error(String(err)));
80
150
  }
81
- await this.opts.onMessage(walletName, payload);
82
- }
83
- catch (err) {
84
- this.opts.onError?.(err instanceof Error ? err : new Error(String(err)));
85
151
  }
86
- }
87
- }
152
+ });
153
+ dataStream.on('end', () => resolve());
154
+ dataStream.on('error', (err) => reject(err));
155
+ // Also resolve if the original response ends/closes
156
+ res.on('close', () => resolve());
157
+ });
88
158
  // Stream ended normally — reconnect
89
159
  if (!controller.signal.aborted) {
90
160
  await this.delay(nextDelay);
@@ -101,6 +171,43 @@ export class NtfySubscriber {
101
171
  return this.connectSse(topic, walletName, controller, nextDelay);
102
172
  }
103
173
  }
174
+ /**
175
+ * Download ntfy file attachment and process as normal message.
176
+ * When message payload exceeds ntfy's size limit (~4KB), ntfy auto-converts
177
+ * to a file attachment. The attachment contains the original request JSON body.
178
+ */
179
+ async fetchAttachmentAndProcess(ntfyMsg, walletName, topic) {
180
+ try {
181
+ const res = await fetch(ntfyMsg.attachment.url);
182
+ if (!res.ok) {
183
+ throw new Error(`Attachment download failed: HTTP ${String(res.status)}`);
184
+ }
185
+ const body = await res.json();
186
+ // The attachment contains the original ntfy request JSON body.
187
+ // Extract the encoded message field from it.
188
+ if (typeof body.message === 'string') {
189
+ ntfyMsg.message = body.message;
190
+ }
191
+ if (typeof body.title === 'string' && !ntfyMsg.title) {
192
+ ntfyMsg.title = body.title;
193
+ }
194
+ if (typeof body.priority === 'number' && !ntfyMsg.priority) {
195
+ ntfyMsg.priority = body.priority;
196
+ }
197
+ const effectiveTopic = ntfyMsg.topic ?? topic;
198
+ const type = determineMessageType(effectiveTopic, this.opts.signTopicPrefix, this.opts.notifyTopicPrefix);
199
+ if (!type)
200
+ return;
201
+ let payload = buildPushPayload(ntfyMsg, type);
202
+ if (this.transformer) {
203
+ payload = this.transformer.transform(payload);
204
+ }
205
+ await this.opts.onMessage(walletName, payload, effectiveTopic);
206
+ }
207
+ catch (err) {
208
+ this.opts.onError?.(err instanceof Error ? err : new Error(String(err)));
209
+ }
210
+ }
104
211
  delay(ms) {
105
212
  return new Promise((resolve) => {
106
213
  const timer = setTimeout(resolve, ms);
@@ -1 +1 @@
1
- {"version":3,"file":"ntfy-subscriber.js","sourceRoot":"","sources":["../../src/subscriber/ntfy-subscriber.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ntfy-subscriber.js","sourceRoot":"","sources":["../../src/subscriber/ntfy-subscriber.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waiaas/push-relay",
3
- "version": "2.9.0-rc.8",
3
+ "version": "2.9.0",
4
4
  "description": "WAIaaS Push Relay Server - bridge ntfy topics to push notification services (Pushwoosh, FCM)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,7 +41,7 @@
41
41
  "hono": "^4.5.0",
42
42
  "smol-toml": "^1.3.0",
43
43
  "zod": "^3.24.0",
44
- "@waiaas/core": "2.9.0-rc.8"
44
+ "@waiaas/core": "2.9.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/better-sqlite3": "^7.6.8",