paygate-mcp 8.79.0 → 8.81.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/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +75 -44
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/server.d.ts
CHANGED
|
@@ -163,7 +163,7 @@ export declare class PayGateServer {
|
|
|
163
163
|
private logStartupSummary;
|
|
164
164
|
/** Send a JSON response with the given status code. */
|
|
165
165
|
private sendJson;
|
|
166
|
-
/** Send a JSON error response: { error
|
|
166
|
+
/** Send a JSON error response: { error, requestId }. */
|
|
167
167
|
private sendError;
|
|
168
168
|
private handleRequest;
|
|
169
169
|
private handleMcp;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAgB,eAAe,EAA0B,MAAM,MAAM,CAAC;AAI7E,OAAO,EAAE,aAAa,EAAkB,mBAAmB,EAAkB,MAAM,SAAS,CAAC;AAE7F,OAAO,EAAE,MAAM,EAAiC,MAAM,UAAU,CAAC;AASjE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAqD,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAmB,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAS,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAA6B,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAqB,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -94,6 +94,20 @@ const expiry_scanner_1 = require("./expiry-scanner");
|
|
|
94
94
|
const key_templates_1 = require("./key-templates");
|
|
95
95
|
/** Max request body size: 1MB */
|
|
96
96
|
const MAX_BODY_SIZE = 1_048_576;
|
|
97
|
+
/** Max length for user-supplied string fields (names, reasons, messages, memos) */
|
|
98
|
+
const MAX_STRING_FIELD = 500;
|
|
99
|
+
/** Truncate user-supplied strings to MAX_STRING_FIELD to prevent log injection and memory abuse. */
|
|
100
|
+
function sanitizeString(value, maxLen = MAX_STRING_FIELD) {
|
|
101
|
+
if (!value)
|
|
102
|
+
return '';
|
|
103
|
+
return String(value).slice(0, maxLen);
|
|
104
|
+
}
|
|
105
|
+
/** Clamp a numeric value to [min, max], returning defaultVal for NaN/undefined. */
|
|
106
|
+
function clampInt(value, min, max, defaultVal) {
|
|
107
|
+
if (value === undefined || !Number.isFinite(value))
|
|
108
|
+
return defaultVal ?? min;
|
|
109
|
+
return Math.min(max, Math.max(min, Math.floor(value)));
|
|
110
|
+
}
|
|
97
111
|
/** Generate a unique request ID (16 hex chars = 8 bytes of randomness) */
|
|
98
112
|
function generateRequestId() {
|
|
99
113
|
return `req_${(0, crypto_1.randomBytes)(8).toString('hex')}`;
|
|
@@ -578,10 +592,11 @@ class PayGateServer {
|
|
|
578
592
|
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
579
593
|
res.end(JSON.stringify(data));
|
|
580
594
|
}
|
|
581
|
-
/** Send a JSON error response: { error
|
|
595
|
+
/** Send a JSON error response: { error, requestId }. */
|
|
582
596
|
sendError(res, status, message) {
|
|
597
|
+
const requestId = res.getHeader('X-Request-Id');
|
|
583
598
|
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
584
|
-
res.end(JSON.stringify({ error: message }));
|
|
599
|
+
res.end(JSON.stringify(requestId ? { error: message, requestId } : { error: message }));
|
|
585
600
|
}
|
|
586
601
|
// ─── Request Handling ──────────────────────────────────────────────────────
|
|
587
602
|
async handleRequest(req, res) {
|
|
@@ -2122,6 +2137,19 @@ class PayGateServer {
|
|
|
2122
2137
|
params.has('expired') || params.has('namePrefix') ||
|
|
2123
2138
|
params.has('minCredits') || params.has('maxCredits');
|
|
2124
2139
|
if (hasPagination) {
|
|
2140
|
+
// Validate sortBy against allowlist
|
|
2141
|
+
const VALID_SORT_FIELDS = ['name', 'credits', 'totalSpent', 'totalCalls', 'lastUsedAt', 'createdAt'];
|
|
2142
|
+
const rawSortBy = params.get('sortBy');
|
|
2143
|
+
if (rawSortBy && !VALID_SORT_FIELDS.includes(rawSortBy)) {
|
|
2144
|
+
this.sendError(res, 400, `Invalid sortBy field "${sanitizeString(rawSortBy, 50)}". Must be one of: ${VALID_SORT_FIELDS.join(', ')}`);
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
// Validate order
|
|
2148
|
+
const rawOrder = params.get('order');
|
|
2149
|
+
if (rawOrder && rawOrder !== 'asc' && rawOrder !== 'desc') {
|
|
2150
|
+
this.sendError(res, 400, 'Invalid order. Must be "asc" or "desc".');
|
|
2151
|
+
return;
|
|
2152
|
+
}
|
|
2125
2153
|
const query = {
|
|
2126
2154
|
namespace: params.get('namespace') || undefined,
|
|
2127
2155
|
group: params.has('group') ? (params.get('group') || '') : undefined,
|
|
@@ -2131,10 +2159,10 @@ class PayGateServer {
|
|
|
2131
2159
|
namePrefix: params.get('namePrefix') || undefined,
|
|
2132
2160
|
minCredits: params.has('minCredits') ? Number(params.get('minCredits')) : undefined,
|
|
2133
2161
|
maxCredits: params.has('maxCredits') ? Number(params.get('maxCredits')) : undefined,
|
|
2134
|
-
sortBy:
|
|
2135
|
-
order:
|
|
2136
|
-
limit: params.has('limit') ? Number(params.get('limit')) : undefined,
|
|
2137
|
-
offset: params.has('offset') ? Number(params.get('offset')) : undefined,
|
|
2162
|
+
sortBy: rawSortBy || undefined,
|
|
2163
|
+
order: rawOrder || undefined,
|
|
2164
|
+
limit: params.has('limit') && Number.isFinite(Number(params.get('limit'))) ? clampInt(Number(params.get('limit')), 1, 500) : undefined,
|
|
2165
|
+
offset: params.has('offset') && Number.isFinite(Number(params.get('offset'))) ? clampInt(Number(params.get('offset')), 0, 100_000) : undefined,
|
|
2138
2166
|
};
|
|
2139
2167
|
const result = this.gate.store.listKeysFiltered(query);
|
|
2140
2168
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
@@ -2271,7 +2299,7 @@ class PayGateServer {
|
|
|
2271
2299
|
}
|
|
2272
2300
|
const fromBalance = sourceRecord.credits;
|
|
2273
2301
|
const toBalance = destRecord.credits;
|
|
2274
|
-
const memo = params.memo
|
|
2302
|
+
const memo = sanitizeString(params.memo);
|
|
2275
2303
|
this.creditLedger.record(sourceRecord.key, {
|
|
2276
2304
|
type: 'transfer_out', amount: credits, balanceBefore: sourceBalanceBefore, balanceAfter: fromBalance, memo: memo || undefined,
|
|
2277
2305
|
});
|
|
@@ -2620,13 +2648,14 @@ class PayGateServer {
|
|
|
2620
2648
|
return;
|
|
2621
2649
|
}
|
|
2622
2650
|
this.syncKeyMutation(record.key);
|
|
2623
|
-
|
|
2651
|
+
const reason = sanitizeString(params.reason) || null;
|
|
2652
|
+
this.audit.log('key.suspended', 'admin', `Key suspended${reason ? ': ' + reason : ''}`, {
|
|
2624
2653
|
keyMasked: (0, audit_1.maskKeyForAudit)(record.key),
|
|
2625
|
-
reason
|
|
2654
|
+
reason,
|
|
2626
2655
|
});
|
|
2627
2656
|
this.emitWebhookAdmin('key.suspended', 'admin', {
|
|
2628
2657
|
keyMasked: (0, audit_1.maskKeyForAudit)(record.key),
|
|
2629
|
-
reason
|
|
2658
|
+
reason,
|
|
2630
2659
|
});
|
|
2631
2660
|
this.sendJson(res, 200, { message: 'Key suspended', suspended: true });
|
|
2632
2661
|
}
|
|
@@ -2710,7 +2739,7 @@ class PayGateServer {
|
|
|
2710
2739
|
return;
|
|
2711
2740
|
}
|
|
2712
2741
|
const cloned = this.gate.store.cloneKey(source.key, {
|
|
2713
|
-
name: params.name,
|
|
2742
|
+
name: params.name ? sanitizeString(String(params.name)) : undefined,
|
|
2714
2743
|
credits: params.credits,
|
|
2715
2744
|
tags: params.tags,
|
|
2716
2745
|
namespace: params.namespace,
|
|
@@ -2771,7 +2800,7 @@ class PayGateServer {
|
|
|
2771
2800
|
this.sendError(res, 404, 'Key not found');
|
|
2772
2801
|
return;
|
|
2773
2802
|
}
|
|
2774
|
-
const alias = params.alias !== undefined ? (params.alias === null || params.alias === '' ? null : String(params.alias)) : undefined;
|
|
2803
|
+
const alias = params.alias !== undefined ? (params.alias === null || params.alias === '' ? null : sanitizeString(String(params.alias))) : undefined;
|
|
2775
2804
|
if (alias === undefined) {
|
|
2776
2805
|
this.sendError(res, 400, 'Missing "alias" parameter (string to set, null to clear)');
|
|
2777
2806
|
return;
|
|
@@ -3352,7 +3381,8 @@ class PayGateServer {
|
|
|
3352
3381
|
return;
|
|
3353
3382
|
}
|
|
3354
3383
|
const type = params.get('type') || undefined;
|
|
3355
|
-
const
|
|
3384
|
+
const limitRaw = params.get('limit');
|
|
3385
|
+
const limit = limitRaw ? clampInt(parseInt(limitRaw, 10), 1, 200, 50) : 50;
|
|
3356
3386
|
const since = params.get('since') || undefined;
|
|
3357
3387
|
const entries = this.creditLedger.getHistory(actualKey, { type, limit, since });
|
|
3358
3388
|
this.sendJson(res, 200, {
|
|
@@ -4519,7 +4549,7 @@ class PayGateServer {
|
|
|
4519
4549
|
const wasEnabled = this.maintenanceMode;
|
|
4520
4550
|
this.maintenanceMode = params.enabled;
|
|
4521
4551
|
if (params.enabled) {
|
|
4522
|
-
this.maintenanceMessage = params.message || 'Server is under maintenance';
|
|
4552
|
+
this.maintenanceMessage = sanitizeString(params.message) || 'Server is under maintenance';
|
|
4523
4553
|
this.maintenanceSince = new Date().toISOString();
|
|
4524
4554
|
if (!wasEnabled) {
|
|
4525
4555
|
this.audit.log('maintenance.enabled', 'admin', `Maintenance mode enabled: ${this.maintenanceMessage}`, {
|
|
@@ -9207,7 +9237,7 @@ class PayGateServer {
|
|
|
9207
9237
|
return;
|
|
9208
9238
|
}
|
|
9209
9239
|
const since = params.get('since') || undefined;
|
|
9210
|
-
const limit =
|
|
9240
|
+
const limit = clampInt(parseInt(params.get('limit') || '50', 10), 1, 200, 50);
|
|
9211
9241
|
const maskedKey = (0, audit_1.maskKeyForAudit)(record.key);
|
|
9212
9242
|
// 1. Collect audit events for this key
|
|
9213
9243
|
// Audit events store masked keys in metadata.key or metadata.keyMasked
|
|
@@ -9360,7 +9390,7 @@ class PayGateServer {
|
|
|
9360
9390
|
credits: params.credits,
|
|
9361
9391
|
createdAt: new Date().toISOString(),
|
|
9362
9392
|
expiresAt: new Date(Date.now() + ttl * 1000).toISOString(),
|
|
9363
|
-
memo: params.memo
|
|
9393
|
+
memo: sanitizeString(params.memo),
|
|
9364
9394
|
};
|
|
9365
9395
|
this.creditReservations.set(reservation.id, reservation);
|
|
9366
9396
|
this.audit.log('credits.reserved', 'admin', `Reserved ${params.credits} credits`, {
|
|
@@ -9664,9 +9694,7 @@ class PayGateServer {
|
|
|
9664
9694
|
const successParam = url.searchParams.get('success');
|
|
9665
9695
|
const options = {};
|
|
9666
9696
|
if (limitParam) {
|
|
9667
|
-
|
|
9668
|
-
if (!isNaN(n) && n > 0)
|
|
9669
|
-
options.limit = n;
|
|
9697
|
+
options.limit = clampInt(parseInt(limitParam, 10), 1, 500);
|
|
9670
9698
|
}
|
|
9671
9699
|
if (sinceParam)
|
|
9672
9700
|
options.since = sinceParam;
|
|
@@ -9865,7 +9893,7 @@ class PayGateServer {
|
|
|
9865
9893
|
try {
|
|
9866
9894
|
const rule = this.gate.webhookRouter.addRule({
|
|
9867
9895
|
id: '', // auto-generated
|
|
9868
|
-
name:
|
|
9896
|
+
name: sanitizeString(params.name) || '',
|
|
9869
9897
|
events: Array.isArray(params.events) ? params.events.map(String) : [],
|
|
9870
9898
|
url: String(params.url || ''),
|
|
9871
9899
|
secret: params.secret ? String(params.secret) : undefined,
|
|
@@ -9908,7 +9936,7 @@ class PayGateServer {
|
|
|
9908
9936
|
}
|
|
9909
9937
|
try {
|
|
9910
9938
|
const rule = this.gate.webhookRouter.updateRule(filterId, {
|
|
9911
|
-
name: params.name !== undefined ? String(params.name) : undefined,
|
|
9939
|
+
name: params.name !== undefined ? sanitizeString(String(params.name)) : undefined,
|
|
9912
9940
|
events: Array.isArray(params.events) ? params.events.map(String) : undefined,
|
|
9913
9941
|
url: params.url !== undefined ? String(params.url) : undefined,
|
|
9914
9942
|
secret: params.secret !== undefined ? String(params.secret) : undefined,
|
|
@@ -9971,8 +9999,8 @@ class PayGateServer {
|
|
|
9971
9999
|
const actor = params.get('actor') || undefined;
|
|
9972
10000
|
const since = params.get('since') || undefined;
|
|
9973
10001
|
const until = params.get('until') || undefined;
|
|
9974
|
-
const limit = params.get('limit') ? parseInt(params.get('limit'), 10) : undefined;
|
|
9975
|
-
const offset = params.get('offset') ? parseInt(params.get('offset'), 10) : undefined;
|
|
10002
|
+
const limit = params.get('limit') ? clampInt(parseInt(params.get('limit'), 10), 1, 1000) : undefined;
|
|
10003
|
+
const offset = params.get('offset') ? clampInt(parseInt(params.get('offset'), 10), 0, 100_000) : undefined;
|
|
9976
10004
|
const result = this.audit.query({ types, actor, since, until, limit, offset });
|
|
9977
10005
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
9978
10006
|
res.end(JSON.stringify(result, null, 2));
|
|
@@ -10091,8 +10119,8 @@ class PayGateServer {
|
|
|
10091
10119
|
return;
|
|
10092
10120
|
}
|
|
10093
10121
|
const team = this.teams.createTeam({
|
|
10094
|
-
name: params.name,
|
|
10095
|
-
description: params.description,
|
|
10122
|
+
name: sanitizeString(params.name) || 'unnamed',
|
|
10123
|
+
description: sanitizeString(params.description) || undefined,
|
|
10096
10124
|
budget: params.budget,
|
|
10097
10125
|
quota: params.quota,
|
|
10098
10126
|
tags: params.tags,
|
|
@@ -10126,8 +10154,8 @@ class PayGateServer {
|
|
|
10126
10154
|
return;
|
|
10127
10155
|
}
|
|
10128
10156
|
const success = this.teams.updateTeam(params.teamId, {
|
|
10129
|
-
name: params.name,
|
|
10130
|
-
description: params.description,
|
|
10157
|
+
name: params.name ? sanitizeString(params.name) : undefined,
|
|
10158
|
+
description: params.description !== undefined ? (sanitizeString(params.description) || undefined) : undefined,
|
|
10131
10159
|
budget: params.budget,
|
|
10132
10160
|
quota: params.quota,
|
|
10133
10161
|
tags: params.tags,
|
|
@@ -10353,7 +10381,7 @@ class PayGateServer {
|
|
|
10353
10381
|
this.sendError(res, 400, 'Not a scoped token (must start with pgt_)');
|
|
10354
10382
|
return;
|
|
10355
10383
|
}
|
|
10356
|
-
const entry = this.tokens.revokeToken(params.token, params.reason);
|
|
10384
|
+
const entry = this.tokens.revokeToken(params.token, sanitizeString(params.reason) || undefined);
|
|
10357
10385
|
if (!entry) {
|
|
10358
10386
|
// Already revoked or invalid signature
|
|
10359
10387
|
this.sendError(res, 409, 'Token already revoked or invalid signature');
|
|
@@ -10431,8 +10459,8 @@ class PayGateServer {
|
|
|
10431
10459
|
}
|
|
10432
10460
|
try {
|
|
10433
10461
|
const group = this.groups.createGroup({
|
|
10434
|
-
name:
|
|
10435
|
-
description: params.description,
|
|
10462
|
+
name: sanitizeString(params.name) || '',
|
|
10463
|
+
description: sanitizeString(params.description) || undefined,
|
|
10436
10464
|
allowedTools: params.allowedTools,
|
|
10437
10465
|
deniedTools: params.deniedTools,
|
|
10438
10466
|
rateLimitPerMin: params.rateLimitPerMin,
|
|
@@ -10483,8 +10511,8 @@ class PayGateServer {
|
|
|
10483
10511
|
}
|
|
10484
10512
|
try {
|
|
10485
10513
|
const group = this.groups.updateGroup(groupId, {
|
|
10486
|
-
name: params.name,
|
|
10487
|
-
description: params.description,
|
|
10514
|
+
name: params.name ? sanitizeString(params.name) : undefined,
|
|
10515
|
+
description: params.description !== undefined ? (sanitizeString(params.description) || undefined) : undefined,
|
|
10488
10516
|
allowedTools: params.allowedTools,
|
|
10489
10517
|
deniedTools: params.deniedTools,
|
|
10490
10518
|
rateLimitPerMin: params.rateLimitPerMin,
|
|
@@ -10679,14 +10707,15 @@ class PayGateServer {
|
|
|
10679
10707
|
// Mask the requesting admin key for audit
|
|
10680
10708
|
const callerKey = req.headers['x-admin-key'];
|
|
10681
10709
|
const callerMasked = callerKey.slice(0, 7) + '...' + callerKey.slice(-4);
|
|
10682
|
-
const
|
|
10683
|
-
this.
|
|
10710
|
+
const safeName = sanitizeString(params.name) || 'unnamed';
|
|
10711
|
+
const record = this.adminKeys.create(safeName, role, callerMasked);
|
|
10712
|
+
this.audit.log('admin_key.created', callerMasked, `Created admin key "${safeName}" with role ${role}`, {
|
|
10684
10713
|
newKeyMasked: record.key.slice(0, 7) + '...' + record.key.slice(-4),
|
|
10685
10714
|
role,
|
|
10686
10715
|
});
|
|
10687
10716
|
this.emitWebhookAdmin('admin_key.created', callerMasked, {
|
|
10688
10717
|
newKeyMasked: record.key.slice(0, 7) + '...' + record.key.slice(-4),
|
|
10689
|
-
name:
|
|
10718
|
+
name: safeName,
|
|
10690
10719
|
role,
|
|
10691
10720
|
});
|
|
10692
10721
|
this.sendJson(res, 201, {
|
|
@@ -10786,11 +10815,12 @@ class PayGateServer {
|
|
|
10786
10815
|
this.sendError(res, 400, 'Invalid JSON');
|
|
10787
10816
|
return;
|
|
10788
10817
|
}
|
|
10789
|
-
const
|
|
10790
|
-
if (!
|
|
10818
|
+
const rawName = params.name;
|
|
10819
|
+
if (!rawName || typeof rawName !== 'string') {
|
|
10791
10820
|
this.sendError(res, 400, 'Missing required field: name');
|
|
10792
10821
|
return;
|
|
10793
10822
|
}
|
|
10823
|
+
const name = sanitizeString(rawName);
|
|
10794
10824
|
const existing = this.templates.get(name);
|
|
10795
10825
|
const result = this.templates.set(name, params);
|
|
10796
10826
|
if (!result.success) {
|
|
@@ -10825,16 +10855,17 @@ class PayGateServer {
|
|
|
10825
10855
|
this.sendError(res, 400, 'Missing required field: name');
|
|
10826
10856
|
return;
|
|
10827
10857
|
}
|
|
10828
|
-
const
|
|
10858
|
+
const templateName = sanitizeString(params.name);
|
|
10859
|
+
const deleted = this.templates.delete(templateName);
|
|
10829
10860
|
if (!deleted) {
|
|
10830
10861
|
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
10831
|
-
res.end(JSON.stringify({ error: `Template "${
|
|
10862
|
+
res.end(JSON.stringify({ error: `Template "${templateName}" not found` }));
|
|
10832
10863
|
return;
|
|
10833
10864
|
}
|
|
10834
|
-
this.audit.log('template.deleted', 'admin', `Deleted template: ${
|
|
10835
|
-
templateName
|
|
10865
|
+
this.audit.log('template.deleted', 'admin', `Deleted template: ${templateName}`, {
|
|
10866
|
+
templateName,
|
|
10836
10867
|
});
|
|
10837
|
-
this.sendJson(res, 200, { deleted: true, name:
|
|
10868
|
+
this.sendJson(res, 200, { deleted: true, name: templateName });
|
|
10838
10869
|
}
|
|
10839
10870
|
/**
|
|
10840
10871
|
* Route admin webhook events through the WebhookRouter (for filter rules) or direct emitter.
|
|
@@ -11042,8 +11073,8 @@ class PayGateServer {
|
|
|
11042
11073
|
const toolFilter = params.get('tool');
|
|
11043
11074
|
const statusFilter = params.get('status'); // 'allowed' | 'denied'
|
|
11044
11075
|
const sinceFilter = params.get('since');
|
|
11045
|
-
const limit =
|
|
11046
|
-
const offset =
|
|
11076
|
+
const limit = clampInt(parseInt(params.get('limit') || '100', 10), 1, 1000, 100);
|
|
11077
|
+
const offset = clampInt(parseInt(params.get('offset') || '0', 10), 0, 100_000, 0);
|
|
11047
11078
|
let filtered = this.requestLog;
|
|
11048
11079
|
// Filter by key (partial match on masked key)
|
|
11049
11080
|
if (keyFilter) {
|