paygate-mcp 6.7.0 → 6.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/README.md +64 -0
- package/dist/audit.d.ts +3 -1
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +9 -0
- package/dist/audit.js.map +1 -1
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +178 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,6 +94,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
94
94
|
- **Spending Velocity** — `GET /keys/spending-velocity?key=...` returns credit burn rate and depletion forecast — credits/calls per hour/day, estimated depletion date, top tools by spend, configurable analysis window (1h–30d)
|
|
95
95
|
- **Key Comparison** — `GET /keys/compare?keys=pg_a,pg_b` returns side-by-side comparison of 2–10 keys — credits, usage, velocity, rate limits, status, metadata (namespace/group/tags) — with not-found key reporting
|
|
96
96
|
- **Key Health Score** — `GET /keys/health?key=...` returns composite health score (0–100) with weighted component breakdown: balance health (30%), quota utilization (25%), rate limit pressure (20%), error rate (25%) — status levels (healthy/good/caution/warning/critical), key issue detection (revoked/suspended/expired/expiring/zero credits), alias support
|
|
97
|
+
- **Maintenance Mode** — `POST /maintenance` enables/disables maintenance mode with custom message — `/mcp` returns 503 to clients while admin endpoints stay operational, `GET /maintenance` checks status, `GET /health` reflects maintenance state, full audit trail
|
|
98
|
+
- **Admin Event Stream** — `GET /admin/events` SSE endpoint streams real-time audit events to admin clients — tool calls, denials, key operations, maintenance changes, all with optional `?types=` filter for event type filtering, keepalive pings, multi-client support
|
|
97
99
|
- **Config Hot Reload** — `POST /config/reload` reloads pricing, rate limits, webhooks, quotas, and behavior flags from config file without server restart
|
|
98
100
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
99
101
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -1866,6 +1868,68 @@ curl "http://localhost:3402/keys/health?key=pg_abc" -H "X-Admin-Key: YOUR_ADMIN_
|
|
|
1866
1868
|
|
|
1867
1869
|
Components: **balance** (30%, hours until credit depletion), **quota** (25%, max utilization across daily/monthly limits), **rateLimit** (20%, current window usage), **errorRate** (25%, denied/total ratio). Status: healthy (≥90), good (≥75), caution (≥50), warning (≥25), critical (<25). Issues detect: revoked, suspended, expired, expiring soon, zero credits, rapid depletion. Supports aliases.
|
|
1868
1870
|
|
|
1871
|
+
### Maintenance Mode
|
|
1872
|
+
|
|
1873
|
+
Put your server into maintenance mode to gracefully reject client traffic while keeping admin endpoints operational:
|
|
1874
|
+
|
|
1875
|
+
```bash
|
|
1876
|
+
# Enable maintenance mode
|
|
1877
|
+
curl -X POST http://localhost:3402/maintenance \
|
|
1878
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
|
|
1879
|
+
-d '{"enabled": true, "message": "Upgrading to v7 — back in 10 minutes"}'
|
|
1880
|
+
|
|
1881
|
+
# Check maintenance status
|
|
1882
|
+
curl http://localhost:3402/maintenance -H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
1883
|
+
|
|
1884
|
+
# Disable maintenance mode
|
|
1885
|
+
curl -X POST http://localhost:3402/maintenance \
|
|
1886
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
|
|
1887
|
+
-d '{"enabled": false}'
|
|
1888
|
+
```
|
|
1889
|
+
|
|
1890
|
+
**Response (enabled):**
|
|
1891
|
+
|
|
1892
|
+
```json
|
|
1893
|
+
{
|
|
1894
|
+
"enabled": true,
|
|
1895
|
+
"message": "Upgrading to v7 — back in 10 minutes",
|
|
1896
|
+
"since": "2025-03-15T14:30:00.000Z"
|
|
1897
|
+
}
|
|
1898
|
+
```
|
|
1899
|
+
|
|
1900
|
+
When enabled, all `/mcp` requests return **503** with the custom message. Admin endpoints (`/keys`, `/maintenance`, `/audit`, etc.) remain fully operational. `GET /health` returns `{"status": "maintenance"}`. Both enable and disable actions are recorded in the audit trail (`maintenance.enabled` / `maintenance.disabled`).
|
|
1901
|
+
|
|
1902
|
+
### Admin Event Stream
|
|
1903
|
+
|
|
1904
|
+
Stream real-time server events to admin clients via Server-Sent Events (SSE):
|
|
1905
|
+
|
|
1906
|
+
```bash
|
|
1907
|
+
# Stream all events
|
|
1908
|
+
curl -N http://localhost:3402/admin/events \
|
|
1909
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
|
|
1910
|
+
-H "Accept: text/event-stream"
|
|
1911
|
+
|
|
1912
|
+
# Stream only key operations
|
|
1913
|
+
curl -N http://localhost:3402/admin/events?types=key.created,key.revoked,key.topup \
|
|
1914
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
|
|
1915
|
+
-H "Accept: text/event-stream"
|
|
1916
|
+
```
|
|
1917
|
+
|
|
1918
|
+
**Events:**
|
|
1919
|
+
|
|
1920
|
+
```
|
|
1921
|
+
event: connected
|
|
1922
|
+
data: {"message":"Admin event stream connected","filters":"all"}
|
|
1923
|
+
|
|
1924
|
+
event: audit
|
|
1925
|
+
data: {"id":42,"timestamp":"2025-03-15T14:30:00.000Z","type":"key.created","actor":"admin","message":"Key created: prod-agent","metadata":{...}}
|
|
1926
|
+
|
|
1927
|
+
event: audit
|
|
1928
|
+
data: {"id":43,"timestamp":"2025-03-15T14:30:01.000Z","type":"gate.allow","actor":"pg_abc12...","message":"Allowed: get_weather","metadata":{...}}
|
|
1929
|
+
```
|
|
1930
|
+
|
|
1931
|
+
Every audit event (tool calls, denials, key operations, maintenance, alerts) is broadcast in real-time. Use `?types=` to filter by comma-separated event types. Supports multiple concurrent admin clients. Keepalive pings every 15s prevent connection timeouts. Connections are cleaned up automatically on disconnect.
|
|
1932
|
+
|
|
1869
1933
|
### IP Allowlisting
|
|
1870
1934
|
|
|
1871
1935
|
Restrict API keys to specific IP addresses or CIDR ranges:
|
package/dist/audit.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* session lifecycle, and admin operations. Ring buffer with configurable
|
|
6
6
|
* max size and age-based retention. Zero external dependencies.
|
|
7
7
|
*/
|
|
8
|
-
export type AuditEventType = 'key.created' | 'key.revoked' | 'key.suspended' | 'key.resumed' | 'key.cloned' | 'key.rotated' | 'key.topup' | 'key.acl_updated' | 'key.expiry_updated' | 'key.quota_updated' | 'key.tags_updated' | 'key.ip_updated' | 'key.limit_updated' | 'gate.allow' | 'gate.deny' | 'session.created' | 'session.destroyed' | 'oauth.client_registered' | 'oauth.token_issued' | 'oauth.token_revoked' | 'team.created' | 'team.updated' | 'team.deleted' | 'team.key_assigned' | 'team.key_removed' | 'admin.auth_failed' | 'admin.alerts_configured' | 'webhook.dead_letter_cleared' | 'webhook.replayed' | 'webhook.test' | 'webhook.pause' | 'webhook.resume' | 'key.alias_set' | 'key.expiry_warning' | 'template.created' | 'template.updated' | 'template.deleted' | 'token.created' | 'token.revoked' | 'billing.refund' | 'key.auto_topup_configured' | 'key.auto_topped_up' | 'admin_key.created' | 'admin_key.revoked' | 'group.created' | 'group.updated' | 'group.deleted' | 'group.key_assigned' | 'group.key_removed' | 'key.credits_transferred' | 'keys.exported' | 'keys.imported' | 'webhook_filter.created' | 'webhook_filter.updated' | 'webhook_filter.deleted' | 'config.reloaded' | 'config.export';
|
|
8
|
+
export type AuditEventType = 'key.created' | 'key.revoked' | 'key.suspended' | 'key.resumed' | 'key.cloned' | 'key.rotated' | 'key.topup' | 'key.acl_updated' | 'key.expiry_updated' | 'key.quota_updated' | 'key.tags_updated' | 'key.ip_updated' | 'key.limit_updated' | 'gate.allow' | 'gate.deny' | 'session.created' | 'session.destroyed' | 'oauth.client_registered' | 'oauth.token_issued' | 'oauth.token_revoked' | 'team.created' | 'team.updated' | 'team.deleted' | 'team.key_assigned' | 'team.key_removed' | 'admin.auth_failed' | 'admin.alerts_configured' | 'webhook.dead_letter_cleared' | 'webhook.replayed' | 'webhook.test' | 'webhook.pause' | 'webhook.resume' | 'key.alias_set' | 'key.expiry_warning' | 'template.created' | 'template.updated' | 'template.deleted' | 'token.created' | 'token.revoked' | 'billing.refund' | 'key.auto_topup_configured' | 'key.auto_topped_up' | 'admin_key.created' | 'admin_key.revoked' | 'group.created' | 'group.updated' | 'group.deleted' | 'group.key_assigned' | 'group.key_removed' | 'key.credits_transferred' | 'keys.exported' | 'keys.imported' | 'webhook_filter.created' | 'webhook_filter.updated' | 'webhook_filter.deleted' | 'config.reloaded' | 'config.export' | 'maintenance.enabled' | 'maintenance.disabled';
|
|
9
9
|
export interface AuditEvent {
|
|
10
10
|
/** Monotonically increasing ID */
|
|
11
11
|
id: number;
|
|
@@ -53,6 +53,8 @@ export declare class AuditLogger {
|
|
|
53
53
|
private nextId;
|
|
54
54
|
private readonly config;
|
|
55
55
|
private cleanupTimer;
|
|
56
|
+
/** Optional callback fired for every logged event (used by admin event stream). */
|
|
57
|
+
onEvent: ((event: AuditEvent) => void) | null;
|
|
56
58
|
constructor(config?: Partial<AuditLogConfig>);
|
|
57
59
|
/**
|
|
58
60
|
* Log an audit event.
|
package/dist/audit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,cAAc,GAEtB,aAAa,GACb,aAAa,GACb,eAAe,GACf,aAAa,GACb,YAAY,GACZ,aAAa,GACb,WAAW,GACX,iBAAiB,GACjB,oBAAoB,GACpB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,GAChB,mBAAmB,GAEnB,YAAY,GACZ,WAAW,GAEX,iBAAiB,GACjB,mBAAmB,GAEnB,yBAAyB,GACzB,oBAAoB,GACpB,qBAAqB,GAErB,cAAc,GACd,cAAc,GACd,cAAc,GACd,mBAAmB,GACnB,kBAAkB,GAElB,mBAAmB,GACnB,yBAAyB,GAEzB,6BAA6B,GAC7B,kBAAkB,GAClB,cAAc,GACd,eAAe,GACf,gBAAgB,GAEhB,eAAe,GAEf,oBAAoB,GAEpB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAElB,eAAe,GACf,eAAe,GAEf,gBAAgB,GAEhB,2BAA2B,GAC3B,oBAAoB,GAEpB,mBAAmB,GACnB,mBAAmB,GAEnB,eAAe,GACf,eAAe,GACf,eAAe,GACf,oBAAoB,GACpB,mBAAmB,GAEnB,yBAAyB,GAEzB,eAAe,GACf,eAAe,GAEf,wBAAwB,GACxB,wBAAwB,GACxB,wBAAwB,GAExB,iBAAiB,GACjB,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/audit.js
CHANGED
|
@@ -20,6 +20,8 @@ class AuditLogger {
|
|
|
20
20
|
nextId = 1;
|
|
21
21
|
config;
|
|
22
22
|
cleanupTimer = null;
|
|
23
|
+
/** Optional callback fired for every logged event (used by admin event stream). */
|
|
24
|
+
onEvent = null;
|
|
23
25
|
constructor(config) {
|
|
24
26
|
this.config = { ...DEFAULT_AUDIT_CONFIG, ...config };
|
|
25
27
|
// Start retention cleanup timer
|
|
@@ -45,6 +47,13 @@ class AuditLogger {
|
|
|
45
47
|
if (this.events.length > this.config.maxEvents) {
|
|
46
48
|
this.events = this.events.slice(-this.config.maxEvents);
|
|
47
49
|
}
|
|
50
|
+
// Notify listeners (e.g., admin event stream)
|
|
51
|
+
if (this.onEvent) {
|
|
52
|
+
try {
|
|
53
|
+
this.onEvent(event);
|
|
54
|
+
}
|
|
55
|
+
catch { /* ignore listener errors */ }
|
|
56
|
+
}
|
|
48
57
|
return event;
|
|
49
58
|
}
|
|
50
59
|
/**
|
package/dist/audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -97,6 +97,16 @@ export declare class PayGateServer {
|
|
|
97
97
|
private readonly startedAt;
|
|
98
98
|
/** Whether the server is draining (shutting down gracefully) */
|
|
99
99
|
private draining;
|
|
100
|
+
/** Whether the server is in maintenance mode (rejects /mcp with 503) */
|
|
101
|
+
private maintenanceMode;
|
|
102
|
+
/** Custom message shown during maintenance mode */
|
|
103
|
+
private maintenanceMessage;
|
|
104
|
+
/** Timestamp when maintenance mode was enabled */
|
|
105
|
+
private maintenanceSince;
|
|
106
|
+
/** Active admin SSE event stream connections */
|
|
107
|
+
private adminEventStreams;
|
|
108
|
+
/** Keepalive timer for admin event streams */
|
|
109
|
+
private adminEventKeepAliveTimer;
|
|
100
110
|
/** Number of in-flight /mcp requests */
|
|
101
111
|
private inflight;
|
|
102
112
|
/** Config file path for hot reload (null if not using config file) */
|
|
@@ -212,6 +222,9 @@ export declare class PayGateServer {
|
|
|
212
222
|
private handleGetDeadLetters;
|
|
213
223
|
private handleClearDeadLetters;
|
|
214
224
|
private handleWebhookReplay;
|
|
225
|
+
private handleGetMaintenance;
|
|
226
|
+
private handleSetMaintenance;
|
|
227
|
+
private handleAdminEventStream;
|
|
215
228
|
private handleConfigReload;
|
|
216
229
|
private handleWebhookStats;
|
|
217
230
|
private handleWebhookLog;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -215,6 +215,16 @@ class PayGateServer {
|
|
|
215
215
|
startedAt = Date.now();
|
|
216
216
|
/** Whether the server is draining (shutting down gracefully) */
|
|
217
217
|
draining = false;
|
|
218
|
+
/** Whether the server is in maintenance mode (rejects /mcp with 503) */
|
|
219
|
+
maintenanceMode = false;
|
|
220
|
+
/** Custom message shown during maintenance mode */
|
|
221
|
+
maintenanceMessage = 'Server is under maintenance';
|
|
222
|
+
/** Timestamp when maintenance mode was enabled */
|
|
223
|
+
maintenanceSince = null;
|
|
224
|
+
/** Active admin SSE event stream connections */
|
|
225
|
+
adminEventStreams = new Set();
|
|
226
|
+
/** Keepalive timer for admin event streams */
|
|
227
|
+
adminEventKeepAliveTimer = null;
|
|
218
228
|
/** Number of in-flight /mcp requests */
|
|
219
229
|
inflight = 0;
|
|
220
230
|
/** Config file path for hot reload (null if not using config file) */
|
|
@@ -261,6 +271,20 @@ class PayGateServer {
|
|
|
261
271
|
this.sessions = new session_1.SessionManager();
|
|
262
272
|
// Audit logger
|
|
263
273
|
this.audit = new audit_1.AuditLogger();
|
|
274
|
+
// Wire up admin event stream — broadcast every audit event to connected admin SSE clients
|
|
275
|
+
this.audit.onEvent = (event) => {
|
|
276
|
+
for (const client of this.adminEventStreams) {
|
|
277
|
+
try {
|
|
278
|
+
// Apply type filter if client specified one
|
|
279
|
+
if (client.types && !client.types.has(event.type))
|
|
280
|
+
continue;
|
|
281
|
+
client.res.write(`event: audit\ndata: ${JSON.stringify(event)}\n\n`);
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// Connection died — will be cleaned up by 'close' handler
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
264
288
|
// Tool registry for pricing discovery
|
|
265
289
|
this.registry = new registry_1.ToolRegistry(this.config, !!this.oauth);
|
|
266
290
|
// Prometheus-compatible metrics
|
|
@@ -487,6 +511,11 @@ class PayGateServer {
|
|
|
487
511
|
res.end(JSON.stringify({ error: 'Server is shutting down' }));
|
|
488
512
|
return;
|
|
489
513
|
}
|
|
514
|
+
if (this.maintenanceMode) {
|
|
515
|
+
res.writeHead(503, { 'Content-Type': 'application/json' });
|
|
516
|
+
res.end(JSON.stringify({ error: this.maintenanceMessage }));
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
490
519
|
return this.handleMcp(req, res);
|
|
491
520
|
case '/health':
|
|
492
521
|
return this.handleHealth(req, res);
|
|
@@ -660,6 +689,8 @@ class PayGateServer {
|
|
|
660
689
|
break;
|
|
661
690
|
case '/admin/keys/revoke':
|
|
662
691
|
return this.handleRevokeAdminKey(req, res);
|
|
692
|
+
case '/admin/events':
|
|
693
|
+
return this.handleAdminEventStream(req, res);
|
|
663
694
|
// ─── Plugin endpoints ──────────────────────────────────────────────
|
|
664
695
|
case '/plugins':
|
|
665
696
|
return this.handleListPlugins(req, res);
|
|
@@ -677,6 +708,15 @@ class PayGateServer {
|
|
|
677
708
|
return this.handleAssignKeyToGroup(req, res);
|
|
678
709
|
case '/groups/remove':
|
|
679
710
|
return this.handleRemoveKeyFromGroup(req, res);
|
|
711
|
+
// ─── Maintenance mode ──────────────────────────────────────────
|
|
712
|
+
case '/maintenance':
|
|
713
|
+
if (req.method === 'GET')
|
|
714
|
+
return this.handleGetMaintenance(req, res);
|
|
715
|
+
if (req.method === 'POST')
|
|
716
|
+
return this.handleSetMaintenance(req, res);
|
|
717
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
718
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
719
|
+
return;
|
|
680
720
|
// ─── Config endpoints ──────────────────────────────────────────
|
|
681
721
|
case '/config/reload':
|
|
682
722
|
return this.handleConfigReload(req, res);
|
|
@@ -1134,6 +1174,8 @@ class PayGateServer {
|
|
|
1134
1174
|
removeKeyFromGroup: 'POST /groups/remove — Remove a key from a group (requires X-Admin-Key)',
|
|
1135
1175
|
configReload: 'POST /config/reload — Hot reload config from file (requires X-Admin-Key)',
|
|
1136
1176
|
configExport: 'GET /config — Export running config with sensitive values masked (requires X-Admin-Key)',
|
|
1177
|
+
maintenance: 'GET /maintenance — Check status + POST to enable/disable maintenance mode (requires X-Admin-Key)',
|
|
1178
|
+
adminEvents: 'GET /admin/events — Real-time SSE stream of server events (requires X-Admin-Key, Accept: text/event-stream)',
|
|
1137
1179
|
...(this.oauth ? {
|
|
1138
1180
|
oauthMetadata: 'GET /.well-known/oauth-authorization-server — OAuth 2.1 server metadata',
|
|
1139
1181
|
oauthRegister: 'POST /oauth/register — Register OAuth client',
|
|
@@ -1167,7 +1209,7 @@ class PayGateServer {
|
|
|
1167
1209
|
return;
|
|
1168
1210
|
}
|
|
1169
1211
|
const uptimeMs = Date.now() - this.startedAt;
|
|
1170
|
-
const status = this.draining ? 'draining' : 'healthy';
|
|
1212
|
+
const status = this.draining ? 'draining' : this.maintenanceMode ? 'maintenance' : 'healthy';
|
|
1171
1213
|
const httpStatus = this.draining ? 503 : 200;
|
|
1172
1214
|
const health = {
|
|
1173
1215
|
status,
|
|
@@ -3787,6 +3829,129 @@ class PayGateServer {
|
|
|
3787
3829
|
message: `Replayed ${replayed} dead letter entries`,
|
|
3788
3830
|
}));
|
|
3789
3831
|
}
|
|
3832
|
+
// ─── /maintenance — Maintenance mode (503 on /mcp while admin stays up) ──
|
|
3833
|
+
handleGetMaintenance(req, res) {
|
|
3834
|
+
if (req.method !== 'GET') {
|
|
3835
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
3836
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
3837
|
+
return;
|
|
3838
|
+
}
|
|
3839
|
+
if (!this.checkAdmin(req, res))
|
|
3840
|
+
return;
|
|
3841
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3842
|
+
res.end(JSON.stringify({
|
|
3843
|
+
enabled: this.maintenanceMode,
|
|
3844
|
+
message: this.maintenanceMode ? this.maintenanceMessage : undefined,
|
|
3845
|
+
since: this.maintenanceSince,
|
|
3846
|
+
}));
|
|
3847
|
+
}
|
|
3848
|
+
handleSetMaintenance(req, res) {
|
|
3849
|
+
if (req.method !== 'POST') {
|
|
3850
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
3851
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
3852
|
+
return;
|
|
3853
|
+
}
|
|
3854
|
+
if (!this.checkAdmin(req, res))
|
|
3855
|
+
return;
|
|
3856
|
+
let body = '';
|
|
3857
|
+
req.on('data', (chunk) => { body += chunk; });
|
|
3858
|
+
req.on('end', () => {
|
|
3859
|
+
let params;
|
|
3860
|
+
try {
|
|
3861
|
+
params = JSON.parse(body);
|
|
3862
|
+
}
|
|
3863
|
+
catch {
|
|
3864
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3865
|
+
res.end(JSON.stringify({ error: 'Invalid JSON body' }));
|
|
3866
|
+
return;
|
|
3867
|
+
}
|
|
3868
|
+
if (typeof params.enabled !== 'boolean') {
|
|
3869
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3870
|
+
res.end(JSON.stringify({ error: 'Missing required field: enabled (boolean)' }));
|
|
3871
|
+
return;
|
|
3872
|
+
}
|
|
3873
|
+
const wasEnabled = this.maintenanceMode;
|
|
3874
|
+
this.maintenanceMode = params.enabled;
|
|
3875
|
+
if (params.enabled) {
|
|
3876
|
+
this.maintenanceMessage = params.message || 'Server is under maintenance';
|
|
3877
|
+
this.maintenanceSince = new Date().toISOString();
|
|
3878
|
+
if (!wasEnabled) {
|
|
3879
|
+
this.audit.log('maintenance.enabled', 'admin', `Maintenance mode enabled: ${this.maintenanceMessage}`, {
|
|
3880
|
+
message: this.maintenanceMessage,
|
|
3881
|
+
});
|
|
3882
|
+
}
|
|
3883
|
+
}
|
|
3884
|
+
else {
|
|
3885
|
+
if (wasEnabled) {
|
|
3886
|
+
this.audit.log('maintenance.disabled', 'admin', 'Maintenance mode disabled', {
|
|
3887
|
+
since: this.maintenanceSince,
|
|
3888
|
+
});
|
|
3889
|
+
}
|
|
3890
|
+
this.maintenanceMessage = 'Server is under maintenance';
|
|
3891
|
+
this.maintenanceSince = null;
|
|
3892
|
+
}
|
|
3893
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3894
|
+
res.end(JSON.stringify({
|
|
3895
|
+
enabled: this.maintenanceMode,
|
|
3896
|
+
message: this.maintenanceMode ? this.maintenanceMessage : undefined,
|
|
3897
|
+
since: this.maintenanceSince,
|
|
3898
|
+
}));
|
|
3899
|
+
});
|
|
3900
|
+
}
|
|
3901
|
+
// ─── /admin/events — Real-time SSE stream of server events ────────────────
|
|
3902
|
+
handleAdminEventStream(req, res) {
|
|
3903
|
+
if (req.method !== 'GET') {
|
|
3904
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
3905
|
+
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
3906
|
+
return;
|
|
3907
|
+
}
|
|
3908
|
+
if (!this.checkAdmin(req, res))
|
|
3909
|
+
return;
|
|
3910
|
+
const accept = req.headers['accept'] || '';
|
|
3911
|
+
if (!accept.includes('text/event-stream')) {
|
|
3912
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
3913
|
+
res.end(JSON.stringify({ error: 'Requires Accept: text/event-stream header' }));
|
|
3914
|
+
return;
|
|
3915
|
+
}
|
|
3916
|
+
// Parse optional type filter from query string
|
|
3917
|
+
const urlParts = req.url?.split('?') || [];
|
|
3918
|
+
const params = new URLSearchParams(urlParts[1] || '');
|
|
3919
|
+
const typesParam = params.get('types');
|
|
3920
|
+
const typeFilter = typesParam ? new Set(typesParam.split(',').filter(Boolean)) : null;
|
|
3921
|
+
// Start SSE stream
|
|
3922
|
+
res.writeHead(200, {
|
|
3923
|
+
'Content-Type': 'text/event-stream',
|
|
3924
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
3925
|
+
'Connection': 'keep-alive',
|
|
3926
|
+
'X-Accel-Buffering': 'no',
|
|
3927
|
+
});
|
|
3928
|
+
// Send connected event
|
|
3929
|
+
res.write(`event: connected\ndata: ${JSON.stringify({ message: 'Admin event stream connected', filters: typesParam || 'all' })}\n\n`);
|
|
3930
|
+
// Register this connection
|
|
3931
|
+
const client = { res, types: typeFilter };
|
|
3932
|
+
this.adminEventStreams.add(client);
|
|
3933
|
+
// Start keepalive if this is the first connection
|
|
3934
|
+
if (!this.adminEventKeepAliveTimer && this.adminEventStreams.size === 1) {
|
|
3935
|
+
this.adminEventKeepAliveTimer = setInterval(() => {
|
|
3936
|
+
for (const c of this.adminEventStreams) {
|
|
3937
|
+
try {
|
|
3938
|
+
c.res.write(':keepalive\n\n');
|
|
3939
|
+
}
|
|
3940
|
+
catch { /* handled by close */ }
|
|
3941
|
+
}
|
|
3942
|
+
}, 15_000);
|
|
3943
|
+
this.adminEventKeepAliveTimer.unref();
|
|
3944
|
+
}
|
|
3945
|
+
// Cleanup on disconnect
|
|
3946
|
+
req.on('close', () => {
|
|
3947
|
+
this.adminEventStreams.delete(client);
|
|
3948
|
+
// Stop keepalive if no more connections
|
|
3949
|
+
if (this.adminEventStreams.size === 0 && this.adminEventKeepAliveTimer) {
|
|
3950
|
+
clearInterval(this.adminEventKeepAliveTimer);
|
|
3951
|
+
this.adminEventKeepAliveTimer = null;
|
|
3952
|
+
}
|
|
3953
|
+
});
|
|
3954
|
+
}
|
|
3790
3955
|
// ─── /config/reload — Hot reload configuration from file ─────────────────
|
|
3791
3956
|
async handleConfigReload(req, res) {
|
|
3792
3957
|
if (req.method !== 'POST') {
|
|
@@ -5278,6 +5443,18 @@ class PayGateServer {
|
|
|
5278
5443
|
});
|
|
5279
5444
|
}
|
|
5280
5445
|
async stop() {
|
|
5446
|
+
// Close admin event stream connections
|
|
5447
|
+
if (this.adminEventKeepAliveTimer) {
|
|
5448
|
+
clearInterval(this.adminEventKeepAliveTimer);
|
|
5449
|
+
this.adminEventKeepAliveTimer = null;
|
|
5450
|
+
}
|
|
5451
|
+
for (const client of this.adminEventStreams) {
|
|
5452
|
+
try {
|
|
5453
|
+
client.res.end();
|
|
5454
|
+
}
|
|
5455
|
+
catch { /* ignore */ }
|
|
5456
|
+
}
|
|
5457
|
+
this.adminEventStreams.clear();
|
|
5281
5458
|
// Plugin lifecycle: onStop (reverse order)
|
|
5282
5459
|
if (this.plugins.count > 0) {
|
|
5283
5460
|
await this.plugins.executeStop();
|