ttyd-mux 0.4.2 → 0.4.3
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/commands/share.d.ts +25 -0
- package/dist/commands/share.d.ts.map +1 -0
- package/dist/commands/share.js +108 -0
- package/dist/commands/share.js.map +1 -0
- package/dist/config/state-store.d.ts +9 -1
- package/dist/config/state-store.d.ts.map +1 -1
- package/dist/config/state-store.js +30 -2
- package/dist/config/state-store.js.map +1 -1
- package/dist/config/state.d.ts +9 -1
- package/dist/config/state.d.ts.map +1 -1
- package/dist/config/state.js +67 -1
- package/dist/config/state.js.map +1 -1
- package/dist/config/types.d.ts +52 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +23 -1
- package/dist/config/types.js.map +1 -1
- package/dist/daemon/api-handler.d.ts.map +1 -1
- package/dist/daemon/api-handler.js +180 -2
- package/dist/daemon/api-handler.js.map +1 -1
- package/dist/daemon/http-proxy.d.ts +3 -2
- package/dist/daemon/http-proxy.d.ts.map +1 -1
- package/dist/daemon/http-proxy.js +7 -4
- package/dist/daemon/http-proxy.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +22 -2
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/notification/index.d.ts +42 -0
- package/dist/daemon/notification/index.d.ts.map +1 -0
- package/dist/daemon/notification/index.js +83 -0
- package/dist/daemon/notification/index.js.map +1 -0
- package/dist/daemon/notification/matcher.d.ts +30 -0
- package/dist/daemon/notification/matcher.d.ts.map +1 -0
- package/dist/daemon/notification/matcher.js +72 -0
- package/dist/daemon/notification/matcher.js.map +1 -0
- package/dist/daemon/notification/sender.d.ts +38 -0
- package/dist/daemon/notification/sender.d.ts.map +1 -0
- package/dist/daemon/notification/sender.js +74 -0
- package/dist/daemon/notification/sender.js.map +1 -0
- package/dist/daemon/notification/subscription.d.ts +35 -0
- package/dist/daemon/notification/subscription.d.ts.map +1 -0
- package/dist/daemon/notification/subscription.js +52 -0
- package/dist/daemon/notification/subscription.js.map +1 -0
- package/dist/daemon/notification/types.d.ts +70 -0
- package/dist/daemon/notification/types.d.ts.map +1 -0
- package/dist/daemon/notification/types.js +5 -0
- package/dist/daemon/notification/types.js.map +1 -0
- package/dist/daemon/notification/vapid.d.ts +25 -0
- package/dist/daemon/notification/vapid.d.ts.map +1 -0
- package/dist/daemon/notification/vapid.js +56 -0
- package/dist/daemon/notification/vapid.js.map +1 -0
- package/dist/daemon/pwa.d.ts +2 -1
- package/dist/daemon/pwa.d.ts.map +1 -1
- package/dist/daemon/pwa.js +51 -0
- package/dist/daemon/pwa.js.map +1 -1
- package/dist/daemon/router.d.ts +10 -0
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +122 -10
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/share-manager.d.ts +55 -0
- package/dist/daemon/share-manager.d.ts.map +1 -0
- package/dist/daemon/share-manager.js +115 -0
- package/dist/daemon/share-manager.js.map +1 -0
- package/dist/daemon/toolbar/index.d.ts +4 -12
- package/dist/daemon/toolbar/index.d.ts.map +1 -1
- package/dist/daemon/toolbar/index.js +6 -794
- package/dist/daemon/toolbar/index.js.map +1 -1
- package/dist/daemon/toolbar/styles.d.ts +1 -1
- package/dist/daemon/toolbar/styles.d.ts.map +1 -1
- package/dist/daemon/toolbar/styles.js +106 -0
- package/dist/daemon/toolbar/styles.js.map +1 -1
- package/dist/daemon/toolbar/template.d.ts +1 -1
- package/dist/daemon/toolbar/template.d.ts.map +1 -1
- package/dist/daemon/toolbar/template.js +11 -0
- package/dist/daemon/toolbar/template.js.map +1 -1
- package/dist/daemon/ws-proxy.d.ts +21 -1
- package/dist/daemon/ws-proxy.d.ts.map +1 -1
- package/dist/daemon/ws-proxy.js +107 -5
- package/dist/daemon/ws-proxy.js.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/toolbar.js +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern matcher for notification triggers
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Create a cooldown key for tracking
|
|
6
|
+
*/
|
|
7
|
+
function getCooldownKey(sessionName, regex) {
|
|
8
|
+
return `${sessionName}:${regex}`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create a notification matcher
|
|
12
|
+
*/
|
|
13
|
+
export function createNotificationMatcher(config) {
|
|
14
|
+
const { patterns, defaultCooldown } = config;
|
|
15
|
+
// Map of cooldown key -> timestamp when cooldown expires
|
|
16
|
+
const cooldowns = new Map();
|
|
17
|
+
// Pre-compile regexes
|
|
18
|
+
const compiledPatterns = [];
|
|
19
|
+
for (const pattern of patterns) {
|
|
20
|
+
try {
|
|
21
|
+
compiledPatterns.push({
|
|
22
|
+
config: pattern,
|
|
23
|
+
regex: new RegExp(pattern.regex)
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Skip invalid regex
|
|
28
|
+
console.error(`[Notification] Invalid regex: ${pattern.regex}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
match(sessionName, text) {
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
for (const { config: pattern, regex } of compiledPatterns) {
|
|
35
|
+
if (regex.test(text)) {
|
|
36
|
+
const key = getCooldownKey(sessionName, pattern.regex);
|
|
37
|
+
const cooldownExpires = cooldowns.get(key);
|
|
38
|
+
// Check if in cooldown period
|
|
39
|
+
if (cooldownExpires && now < cooldownExpires) {
|
|
40
|
+
continue; // Still in cooldown, try next pattern
|
|
41
|
+
}
|
|
42
|
+
// Set cooldown
|
|
43
|
+
const cooldownSeconds = pattern.cooldown ?? defaultCooldown;
|
|
44
|
+
cooldowns.set(key, now + cooldownSeconds * 1000);
|
|
45
|
+
return {
|
|
46
|
+
pattern,
|
|
47
|
+
matchedText: text,
|
|
48
|
+
sessionName,
|
|
49
|
+
timestamp: new Date().toISOString()
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
},
|
|
55
|
+
matchesPattern(regex, text) {
|
|
56
|
+
try {
|
|
57
|
+
return new RegExp(regex).test(text);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
clearCooldown(sessionName, regex) {
|
|
64
|
+
const key = getCooldownKey(sessionName, regex);
|
|
65
|
+
cooldowns.delete(key);
|
|
66
|
+
},
|
|
67
|
+
reset() {
|
|
68
|
+
cooldowns.clear();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../../src/daemon/notification/matcher.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6BH;;GAEG;AACH,SAAS,cAAc,CAAC,WAAmB,EAAE,KAAa;IACxD,OAAO,GAAG,WAAW,IAAI,KAAK,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAqB;IAC7D,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC;IAE7C,yDAAyD;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,sBAAsB;IACtB,MAAM,gBAAgB,GAAoD,EAAE,CAAC;IAC7E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,gBAAgB,CAAC,IAAI,CAAC;gBACpB,MAAM,EAAE,OAAO;gBACf,KAAK,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aACjC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;YACrB,OAAO,CAAC,KAAK,CAAC,iCAAiC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,WAAmB,EAAE,IAAY;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAEvB,KAAK,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,gBAAgB,EAAE,CAAC;gBAC1D,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,MAAM,GAAG,GAAG,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;oBACvD,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAE3C,8BAA8B;oBAC9B,IAAI,eAAe,IAAI,GAAG,GAAG,eAAe,EAAE,CAAC;wBAC7C,SAAS,CAAC,sCAAsC;oBAClD,CAAC;oBAED,eAAe;oBACf,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC;oBAC5D,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,eAAe,GAAG,IAAI,CAAC,CAAC;oBAEjD,OAAO;wBACL,OAAO;wBACP,WAAW,EAAE,IAAI;wBACjB,WAAW;wBACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACpC,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAED,cAAc,CAAC,KAAa,EAAE,IAAY;YACxC,IAAI,CAAC;gBACH,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,aAAa,CAAC,WAAmB,EAAE,KAAa;YAC9C,MAAM,GAAG,GAAG,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAC/C,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAED,KAAK;YACH,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push notification sender
|
|
3
|
+
*/
|
|
4
|
+
import type { MatchResult, PushSubscription, VapidKeys } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Notification payload sent to client
|
|
7
|
+
*/
|
|
8
|
+
export interface NotificationPayload {
|
|
9
|
+
title: string;
|
|
10
|
+
body: string;
|
|
11
|
+
sessionName: string;
|
|
12
|
+
matchedText: string;
|
|
13
|
+
timestamp: string;
|
|
14
|
+
icon?: string;
|
|
15
|
+
tag?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Subscription store interface
|
|
19
|
+
*/
|
|
20
|
+
export interface SubscriptionStore {
|
|
21
|
+
getSubscriptions(): PushSubscription[];
|
|
22
|
+
getSubscriptionsForSession(sessionName: string): PushSubscription[];
|
|
23
|
+
removeSubscription(id: string): void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* NotificationSender interface
|
|
27
|
+
*/
|
|
28
|
+
export interface NotificationSender {
|
|
29
|
+
/** Send notification to all relevant subscribers */
|
|
30
|
+
sendNotification(match: MatchResult): Promise<number>;
|
|
31
|
+
/** Send notification to a specific subscription */
|
|
32
|
+
sendToSubscription(subscription: PushSubscription, payload: NotificationPayload): Promise<boolean>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a notification sender
|
|
36
|
+
*/
|
|
37
|
+
export declare function createNotificationSender(vapidKeys: VapidKeys, contactEmail: string, store: SubscriptionStore): NotificationSender;
|
|
38
|
+
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../src/daemon/notification/sender.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAI3E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,IAAI,gBAAgB,EAAE,CAAC;IACvC,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAAC;IACpE,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,mDAAmD;IACnD,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpG;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,iBAAiB,GACvB,kBAAkB,CA0EpB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push notification sender
|
|
3
|
+
*/
|
|
4
|
+
import webpush from 'web-push';
|
|
5
|
+
import { createLogger } from '../../utils/logger.js';
|
|
6
|
+
const log = createLogger('notification');
|
|
7
|
+
/**
|
|
8
|
+
* Create a notification sender
|
|
9
|
+
*/
|
|
10
|
+
export function createNotificationSender(vapidKeys, contactEmail, store) {
|
|
11
|
+
// Configure web-push with VAPID details
|
|
12
|
+
webpush.setVapidDetails(`mailto:${contactEmail}`, vapidKeys.publicKey, vapidKeys.privateKey);
|
|
13
|
+
return {
|
|
14
|
+
async sendNotification(match) {
|
|
15
|
+
const payload = {
|
|
16
|
+
title: match.pattern.message,
|
|
17
|
+
body: match.matchedText.slice(0, 200), // Truncate long text
|
|
18
|
+
sessionName: match.sessionName,
|
|
19
|
+
matchedText: match.matchedText,
|
|
20
|
+
timestamp: match.timestamp,
|
|
21
|
+
tag: `ttyd-mux-${match.sessionName}`
|
|
22
|
+
};
|
|
23
|
+
// Get subscriptions for this session (or all if no session filter)
|
|
24
|
+
const subscriptions = store.getSubscriptionsForSession(match.sessionName);
|
|
25
|
+
if (subscriptions.length === 0) {
|
|
26
|
+
log.debug(`No subscriptions for session: ${match.sessionName}`);
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
let sent = 0;
|
|
30
|
+
const invalidSubscriptions = [];
|
|
31
|
+
for (const subscription of subscriptions) {
|
|
32
|
+
try {
|
|
33
|
+
await webpush.sendNotification({
|
|
34
|
+
endpoint: subscription.endpoint,
|
|
35
|
+
keys: subscription.keys
|
|
36
|
+
}, JSON.stringify(payload));
|
|
37
|
+
sent++;
|
|
38
|
+
log.debug(`Sent notification to subscription: ${subscription.id}`);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const err = error;
|
|
42
|
+
if (err.statusCode === 410 || err.statusCode === 404) {
|
|
43
|
+
// Subscription no longer valid
|
|
44
|
+
invalidSubscriptions.push(subscription.id);
|
|
45
|
+
log.debug(`Subscription expired: ${subscription.id}`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
log.error(`Failed to send notification: ${String(error)}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Remove invalid subscriptions
|
|
53
|
+
for (const id of invalidSubscriptions) {
|
|
54
|
+
store.removeSubscription(id);
|
|
55
|
+
}
|
|
56
|
+
log.info(`Sent ${sent}/${subscriptions.length} notifications for pattern: ${match.pattern.message}`);
|
|
57
|
+
return sent;
|
|
58
|
+
},
|
|
59
|
+
async sendToSubscription(subscription, payload) {
|
|
60
|
+
try {
|
|
61
|
+
await webpush.sendNotification({
|
|
62
|
+
endpoint: subscription.endpoint,
|
|
63
|
+
keys: subscription.keys
|
|
64
|
+
}, JSON.stringify(payload));
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
log.error(`Failed to send notification: ${String(error)}`);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../../../src/daemon/notification/sender.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,OAAO,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,GAAG,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;AAkCzC;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAAoB,EACpB,YAAoB,EACpB,KAAwB;IAExB,wCAAwC;IACxC,OAAO,CAAC,eAAe,CAAC,UAAU,YAAY,EAAE,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IAE7F,OAAO;QACL,KAAK,CAAC,gBAAgB,CAAC,KAAkB;YACvC,MAAM,OAAO,GAAwB;gBACnC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO;gBAC5B,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,qBAAqB;gBAC5D,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,GAAG,EAAE,YAAY,KAAK,CAAC,WAAW,EAAE;aACrC,CAAC;YAEF,mEAAmE;YACnE,MAAM,aAAa,GAAG,KAAK,CAAC,0BAA0B,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAE1E,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,GAAG,CAAC,KAAK,CAAC,iCAAiC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBAChE,OAAO,CAAC,CAAC;YACX,CAAC;YAED,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,MAAM,oBAAoB,GAAa,EAAE,CAAC;YAE1C,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACzC,IAAI,CAAC;oBACH,MAAM,OAAO,CAAC,gBAAgB,CAC5B;wBACE,QAAQ,EAAE,YAAY,CAAC,QAAQ;wBAC/B,IAAI,EAAE,YAAY,CAAC,IAAI;qBACxB,EACD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CACxB,CAAC;oBACF,IAAI,EAAE,CAAC;oBACP,GAAG,CAAC,KAAK,CAAC,sCAAsC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrE,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,GAAG,GAAG,KAAgC,CAAC;oBAC7C,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;wBACrD,+BAA+B;wBAC/B,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;wBAC3C,GAAG,CAAC,KAAK,CAAC,yBAAyB,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;oBACxD,CAAC;yBAAM,CAAC;wBACN,GAAG,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;YACH,CAAC;YAED,+BAA+B;YAC/B,KAAK,MAAM,EAAE,IAAI,oBAAoB,EAAE,CAAC;gBACtC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;YAED,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,aAAa,CAAC,MAAM,+BAA+B,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACrG,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,YAA8B,EAAE,OAA4B;YACnF,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,gBAAgB,CAC5B;oBACE,QAAQ,EAAE,YAAY,CAAC,QAAQ;oBAC/B,IAAI,EAAE,YAAY,CAAC,IAAI;iBACxB,EACD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CACxB,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC3D,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push subscription management
|
|
3
|
+
*/
|
|
4
|
+
import type { PushSubscription } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Subscription store with persistence
|
|
7
|
+
*/
|
|
8
|
+
export interface SubscriptionStoreConfig {
|
|
9
|
+
getSubscriptions(): PushSubscription[];
|
|
10
|
+
addSubscription(subscription: PushSubscription): void;
|
|
11
|
+
removeSubscription(id: string): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Subscription manager interface
|
|
15
|
+
*/
|
|
16
|
+
export interface SubscriptionManager {
|
|
17
|
+
/** Add a new subscription */
|
|
18
|
+
subscribe(endpoint: string, keys: {
|
|
19
|
+
p256dh: string;
|
|
20
|
+
auth: string;
|
|
21
|
+
}, sessionName?: string): PushSubscription;
|
|
22
|
+
/** Remove a subscription by ID */
|
|
23
|
+
unsubscribe(id: string): boolean;
|
|
24
|
+
/** Get all subscriptions */
|
|
25
|
+
getAll(): PushSubscription[];
|
|
26
|
+
/** Get subscriptions for a specific session (includes global subscriptions) */
|
|
27
|
+
getForSession(sessionName: string): PushSubscription[];
|
|
28
|
+
/** Check if a subscription exists by endpoint */
|
|
29
|
+
hasSubscription(endpoint: string): boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a subscription manager
|
|
33
|
+
*/
|
|
34
|
+
export declare function createSubscriptionManager(store: SubscriptionStoreConfig): SubscriptionManager;
|
|
35
|
+
//# sourceMappingURL=subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../../src/daemon/notification/subscription.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,IAAI,gBAAgB,EAAE,CAAC;IACvC,eAAe,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACtD,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6BAA6B;IAC7B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5G,kCAAkC;IAClC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,4BAA4B;IAC5B,MAAM,IAAI,gBAAgB,EAAE,CAAC;IAC7B,+EAA+E;IAC/E,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAAC;IACvD,iDAAiD;IACjD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5C;AASD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,uBAAuB,GAAG,mBAAmB,CAiD7F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push subscription management
|
|
3
|
+
*/
|
|
4
|
+
import { randomBytes } from 'node:crypto';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a subscription ID
|
|
7
|
+
*/
|
|
8
|
+
function generateSubscriptionId() {
|
|
9
|
+
return randomBytes(8).toString('hex');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create a subscription manager
|
|
13
|
+
*/
|
|
14
|
+
export function createSubscriptionManager(store) {
|
|
15
|
+
return {
|
|
16
|
+
subscribe(endpoint, keys, sessionName) {
|
|
17
|
+
// Check if already subscribed
|
|
18
|
+
const existing = store.getSubscriptions().find((s) => s.endpoint === endpoint);
|
|
19
|
+
if (existing) {
|
|
20
|
+
return existing;
|
|
21
|
+
}
|
|
22
|
+
const subscription = {
|
|
23
|
+
id: generateSubscriptionId(),
|
|
24
|
+
endpoint,
|
|
25
|
+
keys,
|
|
26
|
+
sessionName,
|
|
27
|
+
createdAt: new Date().toISOString()
|
|
28
|
+
};
|
|
29
|
+
store.addSubscription(subscription);
|
|
30
|
+
return subscription;
|
|
31
|
+
},
|
|
32
|
+
unsubscribe(id) {
|
|
33
|
+
const subscriptions = store.getSubscriptions();
|
|
34
|
+
const exists = subscriptions.some((s) => s.id === id);
|
|
35
|
+
if (exists) {
|
|
36
|
+
store.removeSubscription(id);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
},
|
|
41
|
+
getAll() {
|
|
42
|
+
return store.getSubscriptions();
|
|
43
|
+
},
|
|
44
|
+
getForSession(sessionName) {
|
|
45
|
+
return store.getSubscriptions().filter((s) => !s.sessionName || s.sessionName === sessionName);
|
|
46
|
+
},
|
|
47
|
+
hasSubscription(endpoint) {
|
|
48
|
+
return store.getSubscriptions().some((s) => s.endpoint === endpoint);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../src/daemon/notification/subscription.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA4B1C;;GAEG;AACH,SAAS,sBAAsB;IAC7B,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAA8B;IACtE,OAAO;QACL,SAAS,CACP,QAAgB,EAChB,IAAsC,EACtC,WAAoB;YAEpB,8BAA8B;YAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;YAC/E,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,MAAM,YAAY,GAAqB;gBACrC,EAAE,EAAE,sBAAsB,EAAE;gBAC5B,QAAQ;gBACR,IAAI;gBACJ,WAAW;gBACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC;YAEF,KAAK,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;YACpC,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,WAAW,CAAC,EAAU;YACpB,MAAM,aAAa,GAAG,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACtD,IAAI,MAAM,EAAE,CAAC;gBACX,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;gBAC7B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM;YACJ,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAClC,CAAC;QAED,aAAa,CAAC,WAAmB;YAC/B,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,KAAK,WAAW,CACvD,CAAC;QACJ,CAAC;QAED,eAAe,CAAC,QAAgB;YAC9B,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification system types
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Pattern configuration for notification triggers
|
|
6
|
+
*/
|
|
7
|
+
export interface PatternConfig {
|
|
8
|
+
/** Regular expression pattern to match */
|
|
9
|
+
regex: string;
|
|
10
|
+
/** Message to include in notification */
|
|
11
|
+
message: string;
|
|
12
|
+
/** Cooldown in seconds (optional, uses default if not set) */
|
|
13
|
+
cooldown?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Push subscription from browser
|
|
17
|
+
*/
|
|
18
|
+
export interface PushSubscription {
|
|
19
|
+
/** Unique subscription ID */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Browser push endpoint URL */
|
|
22
|
+
endpoint: string;
|
|
23
|
+
/** Subscription keys */
|
|
24
|
+
keys: {
|
|
25
|
+
p256dh: string;
|
|
26
|
+
auth: string;
|
|
27
|
+
};
|
|
28
|
+
/** Session name this subscription is for (optional, null = all sessions) */
|
|
29
|
+
sessionName?: string;
|
|
30
|
+
/** Created timestamp */
|
|
31
|
+
createdAt: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* VAPID keys for Web Push
|
|
35
|
+
*/
|
|
36
|
+
export interface VapidKeys {
|
|
37
|
+
publicKey: string;
|
|
38
|
+
privateKey: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Notification configuration in config.yaml
|
|
42
|
+
*/
|
|
43
|
+
export interface NotificationConfig {
|
|
44
|
+
/** Enable/disable notifications */
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
/** VAPID contact email */
|
|
47
|
+
contact_email?: string;
|
|
48
|
+
/** Enable bell notification (default: true) */
|
|
49
|
+
bell_notification?: boolean;
|
|
50
|
+
/** Bell notification cooldown in seconds (default: 10) */
|
|
51
|
+
bell_cooldown?: number;
|
|
52
|
+
/** Patterns to match */
|
|
53
|
+
patterns?: PatternConfig[];
|
|
54
|
+
/** Default cooldown in seconds */
|
|
55
|
+
default_cooldown?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Match result when a pattern matches
|
|
59
|
+
*/
|
|
60
|
+
export interface MatchResult {
|
|
61
|
+
/** The matched pattern configuration */
|
|
62
|
+
pattern: PatternConfig;
|
|
63
|
+
/** The text that matched */
|
|
64
|
+
matchedText: string;
|
|
65
|
+
/** Session name where match occurred */
|
|
66
|
+
sessionName: string;
|
|
67
|
+
/** Timestamp of match */
|
|
68
|
+
timestamp: string;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/daemon/notification/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,OAAO,EAAE,aAAa,CAAC;IACvB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/daemon/notification/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VAPID key management for Web Push
|
|
3
|
+
*/
|
|
4
|
+
import type { VapidKeys } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Get VAPID keys file path
|
|
7
|
+
*/
|
|
8
|
+
export declare function getVapidKeysPath(stateDir: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate new VAPID keys
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateVapidKeys(): VapidKeys;
|
|
13
|
+
/**
|
|
14
|
+
* Load VAPID keys from file, or generate if not exists
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadOrGenerateVapidKeys(stateDir: string): VapidKeys;
|
|
17
|
+
/**
|
|
18
|
+
* Save VAPID keys to file
|
|
19
|
+
*/
|
|
20
|
+
export declare function saveVapidKeys(stateDir: string, keys: VapidKeys): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get public VAPID key (safe to share with clients)
|
|
23
|
+
*/
|
|
24
|
+
export declare function getPublicVapidKey(stateDir: string): string;
|
|
25
|
+
//# sourceMappingURL=vapid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vapid.d.ts","sourceRoot":"","sources":["../../../src/daemon/notification/vapid.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,SAAS,CAM7C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAgBnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAGrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG1D"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VAPID key management for Web Push
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import webpush from 'web-push';
|
|
7
|
+
/**
|
|
8
|
+
* Get VAPID keys file path
|
|
9
|
+
*/
|
|
10
|
+
export function getVapidKeysPath(stateDir) {
|
|
11
|
+
return join(stateDir, 'vapid-keys.json');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate new VAPID keys
|
|
15
|
+
*/
|
|
16
|
+
export function generateVapidKeys() {
|
|
17
|
+
const keys = webpush.generateVAPIDKeys();
|
|
18
|
+
return {
|
|
19
|
+
publicKey: keys.publicKey,
|
|
20
|
+
privateKey: keys.privateKey
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load VAPID keys from file, or generate if not exists
|
|
25
|
+
*/
|
|
26
|
+
export function loadOrGenerateVapidKeys(stateDir) {
|
|
27
|
+
const keysPath = getVapidKeysPath(stateDir);
|
|
28
|
+
if (existsSync(keysPath)) {
|
|
29
|
+
try {
|
|
30
|
+
const content = readFileSync(keysPath, 'utf-8');
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Fall through to generate new keys
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Generate new keys
|
|
38
|
+
const keys = generateVapidKeys();
|
|
39
|
+
saveVapidKeys(stateDir, keys);
|
|
40
|
+
return keys;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Save VAPID keys to file
|
|
44
|
+
*/
|
|
45
|
+
export function saveVapidKeys(stateDir, keys) {
|
|
46
|
+
const keysPath = getVapidKeysPath(stateDir);
|
|
47
|
+
writeFileSync(keysPath, JSON.stringify(keys, null, 2), { mode: 0o600 });
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get public VAPID key (safe to share with clients)
|
|
51
|
+
*/
|
|
52
|
+
export function getPublicVapidKey(stateDir) {
|
|
53
|
+
const keys = loadOrGenerateVapidKeys(stateDir);
|
|
54
|
+
return keys.publicKey;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=vapid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vapid.js","sourceRoot":"","sources":["../../../src/daemon/notification/vapid.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,OAAO,MAAM,UAAU,CAAC;AAG/B;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IACzC,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,IAAe;IAC7D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC5C,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,IAAI,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC;AACxB,CAAC"}
|
package/dist/daemon/pwa.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ export declare function generateManifest(basePath: string): object;
|
|
|
15
15
|
*
|
|
16
16
|
* Minimal implementation for PWA installability.
|
|
17
17
|
* Uses network-first strategy since terminal requires online connectivity.
|
|
18
|
+
* Also handles push notifications.
|
|
18
19
|
*/
|
|
19
|
-
export declare const serviceWorkerScript = "// ttyd-mux Service Worker\nself.addEventListener('install', (event) => {\n // Skip waiting to activate immediately\n self.skipWaiting();\n});\n\nself.addEventListener('activate', (event) => {\n // Claim all clients immediately\n event.waitUntil(clients.claim());\n});\n\nself.addEventListener('fetch', (event) => {\n // Network-first strategy - terminal requires online connectivity\n event.respondWith(fetch(event.request));\n});\n";
|
|
20
|
+
export declare const serviceWorkerScript = "// ttyd-mux Service Worker\nself.addEventListener('install', (event) => {\n // Skip waiting to activate immediately\n self.skipWaiting();\n});\n\nself.addEventListener('activate', (event) => {\n // Claim all clients immediately\n event.waitUntil(clients.claim());\n});\n\nself.addEventListener('fetch', (event) => {\n // Network-first strategy - terminal requires online connectivity\n event.respondWith(fetch(event.request));\n});\n\n// Push notification handler\nself.addEventListener('push', (event) => {\n if (!event.data) return;\n\n try {\n const data = event.data.json();\n const options = {\n body: data.body || 'Terminal notification',\n icon: '/ttyd-mux/icon-192.png',\n badge: '/ttyd-mux/icon-192.png',\n tag: data.tag || 'ttyd-mux-notification',\n requireInteraction: true,\n data: {\n sessionName: data.sessionName,\n timestamp: data.timestamp,\n url: data.sessionName ? '/ttyd-mux/' + data.sessionName : '/ttyd-mux/'\n }\n };\n\n event.waitUntil(\n self.registration.showNotification(data.title || 'ttyd-mux', options)\n );\n } catch (e) {\n console.error('[SW] Push notification error:', e);\n }\n});\n\n// Notification click handler\nself.addEventListener('notificationclick', (event) => {\n event.notification.close();\n\n const url = event.notification.data?.url || '/ttyd-mux/';\n\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true })\n .then((clientList) => {\n // Try to focus existing window\n for (const client of clientList) {\n if (client.url.includes('/ttyd-mux/') && 'focus' in client) {\n return client.focus();\n }\n }\n // Open new window if none exists\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n});\n";
|
|
20
21
|
/**
|
|
21
22
|
* SVG icon for ttyd-mux
|
|
22
23
|
*
|
package/dist/daemon/pwa.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwa.d.ts","sourceRoot":"","sources":["../../src/daemon/pwa.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA6BzD;AAED
|
|
1
|
+
{"version":3,"file":"pwa.d.ts","sourceRoot":"","sources":["../../src/daemon/pwa.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA6BzD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,g2DAiE/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,OAAO,qSAGb,CAAC;AAER;;;;;;;GAOG;AAIH,eAAO,MAAM,aAAa,QAA6B,CAAC;AAGxD,eAAO,MAAM,aAAa,QAA6B,CAAC;AAsJxD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD"}
|
package/dist/daemon/pwa.js
CHANGED
|
@@ -45,6 +45,7 @@ export function generateManifest(basePath) {
|
|
|
45
45
|
*
|
|
46
46
|
* Minimal implementation for PWA installability.
|
|
47
47
|
* Uses network-first strategy since terminal requires online connectivity.
|
|
48
|
+
* Also handles push notifications.
|
|
48
49
|
*/
|
|
49
50
|
export const serviceWorkerScript = `// ttyd-mux Service Worker
|
|
50
51
|
self.addEventListener('install', (event) => {
|
|
@@ -61,6 +62,56 @@ self.addEventListener('fetch', (event) => {
|
|
|
61
62
|
// Network-first strategy - terminal requires online connectivity
|
|
62
63
|
event.respondWith(fetch(event.request));
|
|
63
64
|
});
|
|
65
|
+
|
|
66
|
+
// Push notification handler
|
|
67
|
+
self.addEventListener('push', (event) => {
|
|
68
|
+
if (!event.data) return;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const data = event.data.json();
|
|
72
|
+
const options = {
|
|
73
|
+
body: data.body || 'Terminal notification',
|
|
74
|
+
icon: '/ttyd-mux/icon-192.png',
|
|
75
|
+
badge: '/ttyd-mux/icon-192.png',
|
|
76
|
+
tag: data.tag || 'ttyd-mux-notification',
|
|
77
|
+
requireInteraction: true,
|
|
78
|
+
data: {
|
|
79
|
+
sessionName: data.sessionName,
|
|
80
|
+
timestamp: data.timestamp,
|
|
81
|
+
url: data.sessionName ? '/ttyd-mux/' + data.sessionName : '/ttyd-mux/'
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
event.waitUntil(
|
|
86
|
+
self.registration.showNotification(data.title || 'ttyd-mux', options)
|
|
87
|
+
);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.error('[SW] Push notification error:', e);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Notification click handler
|
|
94
|
+
self.addEventListener('notificationclick', (event) => {
|
|
95
|
+
event.notification.close();
|
|
96
|
+
|
|
97
|
+
const url = event.notification.data?.url || '/ttyd-mux/';
|
|
98
|
+
|
|
99
|
+
event.waitUntil(
|
|
100
|
+
clients.matchAll({ type: 'window', includeUncontrolled: true })
|
|
101
|
+
.then((clientList) => {
|
|
102
|
+
// Try to focus existing window
|
|
103
|
+
for (const client of clientList) {
|
|
104
|
+
if (client.url.includes('/ttyd-mux/') && 'focus' in client) {
|
|
105
|
+
return client.focus();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Open new window if none exists
|
|
109
|
+
if (clients.openWindow) {
|
|
110
|
+
return clients.openWindow(url);
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
});
|
|
64
115
|
`;
|
|
65
116
|
/**
|
|
66
117
|
* SVG icon for ttyd-mux
|
package/dist/daemon/pwa.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pwa.js","sourceRoot":"","sources":["../../src/daemon/pwa.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,WAAW,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,UAAU;QACtB,WAAW,EAAE,0BAA0B;QACvC,SAAS,EAAE,GAAG,QAAQ,GAAG;QACzB,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,KAAK;QAClB,gBAAgB,EAAE,SAAS;QAC3B,WAAW,EAAE,SAAS;QACtB,KAAK,EAAE;YACL;gBACE,GAAG,EAAE,GAAG,QAAQ,WAAW;gBAC3B,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,KAAK;aACf;YACD;gBACE,GAAG,EAAE,GAAG,QAAQ,eAAe;gBAC/B,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,WAAW;aAClB;YACD;gBACE,GAAG,EAAE,GAAG,QAAQ,eAAe;gBAC/B,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,WAAW;aAClB;SACF;KACF,CAAC;AACJ,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"pwa.js","sourceRoot":"","sources":["../../src/daemon/pwa.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon/router.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
2
|
import type { Config, SessionState } from '../config/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate ETag from content using MD5 hash
|
|
5
|
+
* @param content - Content to hash
|
|
6
|
+
* @returns ETag string with quotes (e.g., '"abc123..."')
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateEtag(content: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Reset toolbar.js cache (for testing)
|
|
11
|
+
*/
|
|
12
|
+
export declare function resetToolbarCache(): void;
|
|
3
13
|
/**
|
|
4
14
|
* Set security headers on response
|
|
5
15
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/daemon/router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/daemon/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKjE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAiB9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAeD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAK5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAYpF;AAyHD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CA4G7F"}
|