paygate-mcp 1.9.0 → 2.0.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 +78 -2
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/redis-client.d.ts +84 -0
- package/dist/redis-client.d.ts.map +1 -0
- package/dist/redis-client.js +341 -0
- package/dist/redis-client.js.map +1 -0
- package/dist/redis-sync.d.ts +65 -0
- package/dist/redis-sync.d.ts.map +1 -0
- package/dist/redis-sync.js +280 -0
- package/dist/redis-sync.js.map +1 -0
- package/dist/server.d.ts +4 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +20 -1
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RedisSync — Write-through cache adapter for distributed PayGate deployments.
|
|
4
|
+
*
|
|
5
|
+
* Keeps the existing in-memory KeyStore as the fast sync read path, while
|
|
6
|
+
* propagating all writes to Redis for cross-process shared state. On startup,
|
|
7
|
+
* loads existing state from Redis. Periodically refreshes local state from Redis
|
|
8
|
+
* to pick up changes made by other PayGate processes.
|
|
9
|
+
*
|
|
10
|
+
* Architecture:
|
|
11
|
+
* Gate.evaluate() → reads from local KeyStore (sync, fast)
|
|
12
|
+
* KeyStore.save() → writes to memory + triggers Redis write (async, fire-and-forget)
|
|
13
|
+
* RedisPersistence.refresh() → pulls latest state from Redis → updates local KeyStore
|
|
14
|
+
*
|
|
15
|
+
* For credit deduction, uses a Redis Lua script to ensure atomicity across
|
|
16
|
+
* multiple PayGate instances (prevents double-spend race conditions).
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.RedisSync = void 0;
|
|
20
|
+
const KEY_PREFIX = 'pg:key:';
|
|
21
|
+
const KEY_SET = 'pg:keys';
|
|
22
|
+
const META_KEY = 'pg:meta';
|
|
23
|
+
/** Lua: atomic credit deduction — check + deduct + increment in one round trip */
|
|
24
|
+
const DEDUCT_LUA = `
|
|
25
|
+
local key = KEYS[1]
|
|
26
|
+
local amount = tonumber(ARGV[1])
|
|
27
|
+
local now = ARGV[2]
|
|
28
|
+
|
|
29
|
+
local credits = tonumber(redis.call('HGET', key, 'credits') or '0')
|
|
30
|
+
local active = redis.call('HGET', key, 'active')
|
|
31
|
+
if active == '0' then return -1 end
|
|
32
|
+
if credits < amount then return 0 end
|
|
33
|
+
|
|
34
|
+
redis.call('HINCRBY', key, 'credits', -amount)
|
|
35
|
+
redis.call('HINCRBY', key, 'totalSpent', amount)
|
|
36
|
+
redis.call('HINCRBY', key, 'totalCalls', 1)
|
|
37
|
+
redis.call('HSET', key, 'lastUsedAt', now)
|
|
38
|
+
return 1
|
|
39
|
+
`;
|
|
40
|
+
/** Lua: atomic credit addition (top-up) */
|
|
41
|
+
const TOPUP_LUA = `
|
|
42
|
+
local key = KEYS[1]
|
|
43
|
+
local amount = tonumber(ARGV[1])
|
|
44
|
+
local active = redis.call('HGET', key, 'active')
|
|
45
|
+
if active == '0' then return 0 end
|
|
46
|
+
redis.call('HINCRBY', key, 'credits', amount)
|
|
47
|
+
return 1
|
|
48
|
+
`;
|
|
49
|
+
class RedisSync {
|
|
50
|
+
redis;
|
|
51
|
+
store;
|
|
52
|
+
syncInterval = null;
|
|
53
|
+
syncMs;
|
|
54
|
+
constructor(redis, store, syncIntervalMs = 5000) {
|
|
55
|
+
this.redis = redis;
|
|
56
|
+
this.store = store;
|
|
57
|
+
this.syncMs = syncIntervalMs;
|
|
58
|
+
}
|
|
59
|
+
// ─── Lifecycle ─────────────────────────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* Initialize: connect to Redis and load existing state into local KeyStore.
|
|
62
|
+
*/
|
|
63
|
+
async init() {
|
|
64
|
+
await this.redis.connect();
|
|
65
|
+
await this.redis.ping();
|
|
66
|
+
console.log('[paygate:redis] Connected to Redis');
|
|
67
|
+
await this.loadFromRedis();
|
|
68
|
+
// Start periodic refresh
|
|
69
|
+
this.syncInterval = setInterval(() => {
|
|
70
|
+
this.loadFromRedis().catch(err => {
|
|
71
|
+
console.error('[paygate:redis] Sync error:', err.message);
|
|
72
|
+
});
|
|
73
|
+
}, this.syncMs);
|
|
74
|
+
}
|
|
75
|
+
async destroy() {
|
|
76
|
+
if (this.syncInterval) {
|
|
77
|
+
clearInterval(this.syncInterval);
|
|
78
|
+
this.syncInterval = null;
|
|
79
|
+
}
|
|
80
|
+
await this.redis.disconnect();
|
|
81
|
+
}
|
|
82
|
+
// ─── Write-through operations ──────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Save a single key record to Redis. Called after local KeyStore mutations.
|
|
85
|
+
* Fire-and-forget (errors logged, not thrown).
|
|
86
|
+
*/
|
|
87
|
+
async saveKey(record) {
|
|
88
|
+
try {
|
|
89
|
+
const redisKey = KEY_PREFIX + record.key;
|
|
90
|
+
await this.redis.hset(redisKey, ...this.recordToHash(record));
|
|
91
|
+
await this.redis.command('SADD', KEY_SET, record.key);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
console.error(`[paygate:redis] Save key error: ${err.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Save ALL keys to Redis. Called when local KeyStore.save() fires.
|
|
99
|
+
*/
|
|
100
|
+
async saveAll() {
|
|
101
|
+
try {
|
|
102
|
+
const keys = this.store.listKeys();
|
|
103
|
+
// Use the internal key map via a dedicated export method
|
|
104
|
+
const data = this.store.keys;
|
|
105
|
+
if (!data)
|
|
106
|
+
return;
|
|
107
|
+
for (const [key, record] of data) {
|
|
108
|
+
const redisKey = KEY_PREFIX + key;
|
|
109
|
+
await this.redis.hset(redisKey, ...this.recordToHash(record));
|
|
110
|
+
await this.redis.command('SADD', KEY_SET, key);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
console.error(`[paygate:redis] SaveAll error: ${err.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Atomic credit deduction via Redis Lua. Returns true if deduction succeeded.
|
|
119
|
+
* Call this INSTEAD of store.deductCredits() in Redis mode.
|
|
120
|
+
*/
|
|
121
|
+
async atomicDeduct(apiKey, amount) {
|
|
122
|
+
try {
|
|
123
|
+
const result = await this.redis.evalLua(DEDUCT_LUA, 1, KEY_PREFIX + apiKey, String(amount), new Date().toISOString());
|
|
124
|
+
if (result === 1) {
|
|
125
|
+
// Update local cache to reflect the deduction
|
|
126
|
+
const record = this.store.keys.get(apiKey);
|
|
127
|
+
if (record) {
|
|
128
|
+
record.credits -= amount;
|
|
129
|
+
record.totalSpent += amount;
|
|
130
|
+
record.totalCalls++;
|
|
131
|
+
record.lastUsedAt = new Date().toISOString();
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
console.error(`[paygate:redis] Atomic deduct error: ${err.message}`);
|
|
139
|
+
// Fallback to local deduction if Redis is temporarily unavailable
|
|
140
|
+
return this.store.deductCredits(apiKey, amount);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Atomic credit top-up via Redis.
|
|
145
|
+
*/
|
|
146
|
+
async atomicTopup(apiKey, amount) {
|
|
147
|
+
try {
|
|
148
|
+
const result = await this.redis.evalLua(TOPUP_LUA, 1, KEY_PREFIX + apiKey, String(amount));
|
|
149
|
+
if (result === 1) {
|
|
150
|
+
// Update local cache
|
|
151
|
+
const record = this.store.keys.get(apiKey);
|
|
152
|
+
if (record) {
|
|
153
|
+
record.credits += amount;
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(`[paygate:redis] Atomic topup error: ${err.message}`);
|
|
161
|
+
return this.store.addCredits(apiKey, amount);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Revoke a key in both local store and Redis.
|
|
166
|
+
*/
|
|
167
|
+
async revokeKey(apiKey) {
|
|
168
|
+
const localResult = this.store.revokeKey(apiKey);
|
|
169
|
+
try {
|
|
170
|
+
await this.redis.hset(KEY_PREFIX + apiKey, 'active', '0');
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
console.error(`[paygate:redis] Revoke error: ${err.message}`);
|
|
174
|
+
}
|
|
175
|
+
return localResult;
|
|
176
|
+
}
|
|
177
|
+
// ─── Load from Redis ───────────────────────────────────────────────────────
|
|
178
|
+
/**
|
|
179
|
+
* Load all keys from Redis into the local in-memory KeyStore.
|
|
180
|
+
* Merges with any locally-created keys (doesn't overwrite local-only keys).
|
|
181
|
+
*/
|
|
182
|
+
async loadFromRedis() {
|
|
183
|
+
try {
|
|
184
|
+
const allKeyIds = await this.redis.command('SMEMBERS', KEY_SET);
|
|
185
|
+
if (!allKeyIds || allKeyIds.length === 0) {
|
|
186
|
+
// No keys in Redis — push local state up if we have any
|
|
187
|
+
await this.pushLocalToRedis();
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
let loaded = 0;
|
|
191
|
+
for (const keyId of allKeyIds) {
|
|
192
|
+
const hash = await this.redis.hgetall(KEY_PREFIX + keyId);
|
|
193
|
+
if (!hash || !hash.key)
|
|
194
|
+
continue;
|
|
195
|
+
const record = this.hashToRecord(hash);
|
|
196
|
+
if (!record)
|
|
197
|
+
continue;
|
|
198
|
+
// Write directly into the local store's map
|
|
199
|
+
const localKeys = this.store.keys;
|
|
200
|
+
localKeys.set(record.key, record);
|
|
201
|
+
loaded++;
|
|
202
|
+
}
|
|
203
|
+
if (loaded > 0) {
|
|
204
|
+
console.log(`[paygate:redis] Synced ${loaded} key(s) from Redis`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
console.error(`[paygate:redis] Load error: ${err.message}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Push local KeyStore state to Redis (used when Redis is empty on first connect).
|
|
213
|
+
*/
|
|
214
|
+
async pushLocalToRedis() {
|
|
215
|
+
const localKeys = this.store.keys;
|
|
216
|
+
if (localKeys.size === 0)
|
|
217
|
+
return;
|
|
218
|
+
for (const [key, record] of localKeys) {
|
|
219
|
+
const redisKey = KEY_PREFIX + key;
|
|
220
|
+
await this.redis.hset(redisKey, ...this.recordToHash(record));
|
|
221
|
+
await this.redis.command('SADD', KEY_SET, key);
|
|
222
|
+
}
|
|
223
|
+
console.log(`[paygate:redis] Pushed ${localKeys.size} local key(s) to Redis`);
|
|
224
|
+
}
|
|
225
|
+
// ─── Serialization ─────────────────────────────────────────────────────────
|
|
226
|
+
recordToHash(record) {
|
|
227
|
+
const fields = [];
|
|
228
|
+
fields.push('key', record.key);
|
|
229
|
+
fields.push('name', record.name);
|
|
230
|
+
fields.push('credits', String(record.credits));
|
|
231
|
+
fields.push('totalSpent', String(record.totalSpent));
|
|
232
|
+
fields.push('totalCalls', String(record.totalCalls));
|
|
233
|
+
fields.push('createdAt', record.createdAt);
|
|
234
|
+
fields.push('lastUsedAt', record.lastUsedAt || '');
|
|
235
|
+
fields.push('active', record.active ? '1' : '0');
|
|
236
|
+
fields.push('spendingLimit', String(record.spendingLimit));
|
|
237
|
+
fields.push('allowedTools', JSON.stringify(record.allowedTools));
|
|
238
|
+
fields.push('deniedTools', JSON.stringify(record.deniedTools));
|
|
239
|
+
fields.push('expiresAt', record.expiresAt || '');
|
|
240
|
+
fields.push('quota', record.quota ? JSON.stringify(record.quota) : '');
|
|
241
|
+
fields.push('tags', JSON.stringify(record.tags));
|
|
242
|
+
fields.push('ipAllowlist', JSON.stringify(record.ipAllowlist));
|
|
243
|
+
fields.push('quotaDailyCalls', String(record.quotaDailyCalls));
|
|
244
|
+
fields.push('quotaMonthlyCalls', String(record.quotaMonthlyCalls));
|
|
245
|
+
fields.push('quotaDailyCredits', String(record.quotaDailyCredits));
|
|
246
|
+
fields.push('quotaMonthlyCredits', String(record.quotaMonthlyCredits));
|
|
247
|
+
fields.push('quotaLastResetDay', record.quotaLastResetDay);
|
|
248
|
+
fields.push('quotaLastResetMonth', record.quotaLastResetMonth);
|
|
249
|
+
return fields;
|
|
250
|
+
}
|
|
251
|
+
hashToRecord(hash) {
|
|
252
|
+
if (!hash.key)
|
|
253
|
+
return null;
|
|
254
|
+
return {
|
|
255
|
+
key: hash.key,
|
|
256
|
+
name: hash.name || '',
|
|
257
|
+
credits: parseInt(hash.credits, 10) || 0,
|
|
258
|
+
totalSpent: parseInt(hash.totalSpent, 10) || 0,
|
|
259
|
+
totalCalls: parseInt(hash.totalCalls, 10) || 0,
|
|
260
|
+
createdAt: hash.createdAt || new Date().toISOString(),
|
|
261
|
+
lastUsedAt: hash.lastUsedAt || null,
|
|
262
|
+
active: hash.active !== '0',
|
|
263
|
+
spendingLimit: parseInt(hash.spendingLimit, 10) || 0,
|
|
264
|
+
allowedTools: hash.allowedTools ? JSON.parse(hash.allowedTools) : [],
|
|
265
|
+
deniedTools: hash.deniedTools ? JSON.parse(hash.deniedTools) : [],
|
|
266
|
+
expiresAt: hash.expiresAt || null,
|
|
267
|
+
quota: hash.quota ? JSON.parse(hash.quota) : undefined,
|
|
268
|
+
tags: hash.tags ? JSON.parse(hash.tags) : {},
|
|
269
|
+
ipAllowlist: hash.ipAllowlist ? JSON.parse(hash.ipAllowlist) : [],
|
|
270
|
+
quotaDailyCalls: parseInt(hash.quotaDailyCalls, 10) || 0,
|
|
271
|
+
quotaMonthlyCalls: parseInt(hash.quotaMonthlyCalls, 10) || 0,
|
|
272
|
+
quotaDailyCredits: parseInt(hash.quotaDailyCredits, 10) || 0,
|
|
273
|
+
quotaMonthlyCredits: parseInt(hash.quotaMonthlyCredits, 10) || 0,
|
|
274
|
+
quotaLastResetDay: hash.quotaLastResetDay || new Date().toISOString().slice(0, 10),
|
|
275
|
+
quotaLastResetMonth: hash.quotaLastResetMonth || new Date().toISOString().slice(0, 7),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
exports.RedisSync = RedisSync;
|
|
280
|
+
//# sourceMappingURL=redis-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-sync.js","sourceRoot":"","sources":["../src/redis-sync.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { MetricsCollector } from './metrics';
|
|
|
24
24
|
import { AnalyticsEngine } from './analytics';
|
|
25
25
|
import { AlertEngine } from './alerts';
|
|
26
26
|
import { TeamManager } from './teams';
|
|
27
|
+
import { RedisSync } from './redis-sync';
|
|
27
28
|
/** Union type for both proxy backends */
|
|
28
29
|
type ProxyBackend = McpProxy | HttpMcpProxy;
|
|
29
30
|
export declare class PayGateServer {
|
|
@@ -52,11 +53,13 @@ export declare class PayGateServer {
|
|
|
52
53
|
readonly alerts: AlertEngine;
|
|
53
54
|
/** Team/organization manager */
|
|
54
55
|
readonly teams: TeamManager;
|
|
56
|
+
/** Redis sync adapter for distributed state (null if not using Redis) */
|
|
57
|
+
readonly redisSync: RedisSync | null;
|
|
55
58
|
/** The active request handler — either proxy or router */
|
|
56
59
|
private get handler();
|
|
57
60
|
constructor(config: Partial<PayGateConfig> & {
|
|
58
61
|
serverCommand: string;
|
|
59
|
-
}, adminKey?: string, statePath?: string, remoteUrl?: string, stripeWebhookSecret?: string, servers?: ServerBackendConfig[]);
|
|
62
|
+
}, adminKey?: string, statePath?: string, remoteUrl?: string, stripeWebhookSecret?: string, servers?: ServerBackendConfig[], redisUrl?: string);
|
|
60
63
|
start(): Promise<{
|
|
61
64
|
port: number;
|
|
62
65
|
adminKey: string;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAE,aAAa,EAAkB,mBAAmB,EAAkB,MAAM,SAAS,CAAC;AAS7F,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,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,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;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -42,6 +42,8 @@ const dashboard_1 = require("./dashboard");
|
|
|
42
42
|
const analytics_1 = require("./analytics");
|
|
43
43
|
const alerts_1 = require("./alerts");
|
|
44
44
|
const teams_1 = require("./teams");
|
|
45
|
+
const redis_client_1 = require("./redis-client");
|
|
46
|
+
const redis_sync_1 = require("./redis-sync");
|
|
45
47
|
/** Max request body size: 1MB */
|
|
46
48
|
const MAX_BODY_SIZE = 1_048_576;
|
|
47
49
|
class PayGateServer {
|
|
@@ -70,11 +72,13 @@ class PayGateServer {
|
|
|
70
72
|
alerts;
|
|
71
73
|
/** Team/organization manager */
|
|
72
74
|
teams;
|
|
75
|
+
/** Redis sync adapter for distributed state (null if not using Redis) */
|
|
76
|
+
redisSync = null;
|
|
73
77
|
/** The active request handler — either proxy or router */
|
|
74
78
|
get handler() {
|
|
75
79
|
return (this.router || this.proxy);
|
|
76
80
|
}
|
|
77
|
-
constructor(config, adminKey, statePath, remoteUrl, stripeWebhookSecret, servers) {
|
|
81
|
+
constructor(config, adminKey, statePath, remoteUrl, stripeWebhookSecret, servers, redisUrl) {
|
|
78
82
|
this.config = { ...types_1.DEFAULT_CONFIG, ...config };
|
|
79
83
|
this.adminKey = adminKey || `admin_${require('crypto').randomBytes(16).toString('hex')}`;
|
|
80
84
|
this.gate = new gate_1.Gate(this.config, statePath);
|
|
@@ -147,8 +151,19 @@ class PayGateServer {
|
|
|
147
151
|
this.gate.teamRecorder = (apiKey, credits) => {
|
|
148
152
|
this.teams.recordUsage(apiKey, credits);
|
|
149
153
|
};
|
|
154
|
+
// Redis distributed state (if configured)
|
|
155
|
+
if (redisUrl) {
|
|
156
|
+
const redisOpts = (0, redis_client_1.parseRedisUrl)(redisUrl);
|
|
157
|
+
const redisClient = new redis_client_1.RedisClient(redisOpts);
|
|
158
|
+
this.redisSync = new redis_sync_1.RedisSync(redisClient, this.gate.store);
|
|
159
|
+
}
|
|
150
160
|
}
|
|
151
161
|
async start() {
|
|
162
|
+
// Initialize Redis sync before starting (loads state from Redis)
|
|
163
|
+
if (this.redisSync) {
|
|
164
|
+
await this.redisSync.init();
|
|
165
|
+
console.log('[paygate] Redis distributed state enabled');
|
|
166
|
+
}
|
|
152
167
|
await this.handler.start();
|
|
153
168
|
return new Promise((resolve, reject) => {
|
|
154
169
|
this.server = (0, http_1.createServer)(async (req, res) => {
|
|
@@ -567,6 +582,7 @@ class PayGateServer {
|
|
|
567
582
|
},
|
|
568
583
|
shadowMode: this.config.shadowMode,
|
|
569
584
|
oauth: !!this.oauth,
|
|
585
|
+
redis: !!this.redisSync,
|
|
570
586
|
}));
|
|
571
587
|
}
|
|
572
588
|
// ─── /status — Dashboard ────────────────────────────────────────────────────
|
|
@@ -1937,6 +1953,9 @@ class PayGateServer {
|
|
|
1937
1953
|
this.oauth?.destroy();
|
|
1938
1954
|
this.sessions.destroy();
|
|
1939
1955
|
this.audit.destroy();
|
|
1956
|
+
if (this.redisSync) {
|
|
1957
|
+
await this.redisSync.destroy();
|
|
1958
|
+
}
|
|
1940
1959
|
if (this.server) {
|
|
1941
1960
|
return new Promise((resolve) => {
|
|
1942
1961
|
this.server.close(() => resolve());
|