@winstonsayno/mcp-gateway 1.2.0 → 1.4.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +21 -3
  3. package/dist/auth/middleware.d.ts +9 -1
  4. package/dist/auth/middleware.d.ts.map +1 -1
  5. package/dist/auth/middleware.js +6 -1
  6. package/dist/auth/middleware.js.map +1 -1
  7. package/dist/auth/oauth.d.ts +86 -0
  8. package/dist/auth/oauth.d.ts.map +1 -0
  9. package/dist/auth/oauth.js +342 -0
  10. package/dist/auth/oauth.js.map +1 -0
  11. package/dist/auth/ratelimit.d.ts +3 -2
  12. package/dist/auth/ratelimit.d.ts.map +1 -1
  13. package/dist/auth/ratelimit.js +2 -1
  14. package/dist/auth/ratelimit.js.map +1 -1
  15. package/dist/config/loader.d.ts.map +1 -1
  16. package/dist/config/loader.js +58 -1
  17. package/dist/config/loader.js.map +1 -1
  18. package/dist/gateway/api.d.ts +12 -3
  19. package/dist/gateway/api.d.ts.map +1 -1
  20. package/dist/gateway/api.js +23 -9
  21. package/dist/gateway/api.js.map +1 -1
  22. package/dist/gateway/index.d.ts +8 -1
  23. package/dist/gateway/index.d.ts.map +1 -1
  24. package/dist/gateway/index.js +36 -2
  25. package/dist/gateway/index.js.map +1 -1
  26. package/dist/index.d.ts +5 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/mcp/endpoint.d.ts +18 -1
  31. package/dist/mcp/endpoint.d.ts.map +1 -1
  32. package/dist/mcp/endpoint.js +120 -15
  33. package/dist/mcp/endpoint.js.map +1 -1
  34. package/dist/security/lockout.d.ts +14 -2
  35. package/dist/security/lockout.d.ts.map +1 -1
  36. package/dist/security/lockout.js +22 -17
  37. package/dist/security/lockout.js.map +1 -1
  38. package/dist/security/posture.d.ts.map +1 -1
  39. package/dist/security/posture.js +3 -0
  40. package/dist/security/posture.js.map +1 -1
  41. package/dist/state/index.d.ts +14 -0
  42. package/dist/state/index.d.ts.map +1 -0
  43. package/dist/state/index.js +27 -0
  44. package/dist/state/index.js.map +1 -0
  45. package/dist/state/redis.d.ts +56 -0
  46. package/dist/state/redis.d.ts.map +1 -0
  47. package/dist/state/redis.js +263 -0
  48. package/dist/state/redis.js.map +1 -0
  49. package/dist/state/shared.d.ts +45 -0
  50. package/dist/state/shared.d.ts.map +1 -0
  51. package/dist/state/shared.js +130 -0
  52. package/dist/state/shared.js.map +1 -0
  53. package/dist/state/store.d.ts +67 -0
  54. package/dist/state/store.d.ts.map +1 -0
  55. package/dist/state/store.js +113 -0
  56. package/dist/state/store.js.map +1 -0
  57. package/dist/utils/types.d.ts +55 -4
  58. package/dist/utils/types.d.ts.map +1 -1
  59. package/package.json +1 -1
@@ -93,25 +93,30 @@ export function withLockout(auth, lockout) {
93
93
  if (!lo)
94
94
  return auth(req, res, next);
95
95
  const ip = req.ip ?? req.socket.remoteAddress ?? 'unknown';
96
- const wait = lo.lockedFor(ip);
97
- if (wait > 0) {
98
- res.status(429).set('Retry-After', String(wait)).json({
99
- error: 'Too Many Requests',
100
- message: 'Too many failed authentication attempts; try again later',
101
- retryAfter: wait,
96
+ const locked = lo.lockedFor(ip);
97
+ if (typeof locked === 'number')
98
+ return proceed(locked);
99
+ locked.then(proceed, next);
100
+ function proceed(wait) {
101
+ if (wait > 0) {
102
+ res.status(429).set('Retry-After', String(wait)).json({
103
+ error: 'Too Many Requests',
104
+ message: 'Too many failed authentication attempts; try again later',
105
+ retryAfter: wait,
106
+ });
107
+ return;
108
+ }
109
+ let passed = false;
110
+ res.once('finish', () => {
111
+ if (!passed && res.statusCode === 401)
112
+ void lo.fail(ip);
113
+ });
114
+ auth(req, res, (err) => {
115
+ passed = true;
116
+ void lo.success(ip);
117
+ next(err);
102
118
  });
103
- return;
104
119
  }
105
- let passed = false;
106
- res.once('finish', () => {
107
- if (!passed && res.statusCode === 401)
108
- lo.fail(ip);
109
- });
110
- auth(req, res, (err) => {
111
- passed = true;
112
- lo.success(ip);
113
- next(err);
114
- });
115
120
  };
116
121
  }
117
122
  //# sourceMappingURL=lockout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lockout.js","sourceRoot":"","sources":["../../src/security/lockout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lockout.js","sourceRoot":"","sources":["../../src/security/lockout.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"posture.d.ts","sourceRoot":"","sources":["../../src/security/posture.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIpD;AAID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,SAAa,GAAG,eAAe,EAAE,CAiE3F"}
1
+ {"version":3,"file":"posture.d.ts","sourceRoot":"","sources":["../../src/security/posture.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIpD;AAID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,SAAa,GAAG,eAAe,EAAE,CAwE3F"}
@@ -58,6 +58,9 @@ export function securityWarnings(config, now = Date.now()) {
58
58
  if (!jwt.requireExp)
59
59
  add('jwt-no-exp', 'JWTs without an "exp" claim are accepted forever: set auth.jwt.requireExp: true.', 'info');
60
60
  }
61
+ if (strategy === 'oauth2' && !config.auth?.oauth?.resource) {
62
+ add('oauth-no-resource', 'auth.oauth.resource is not set: the resource URI is derived from the Host header. Set it to the public /mcp URL.', 'info');
63
+ }
61
64
  if (strategy !== 'none' && !sec.authLockout) {
62
65
  add('no-auth-lockout', 'No brute-force protection: set security.authLockout: true to lock out IPs after repeated failures.', 'info');
63
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"posture.js","sourceRoot":"","sources":["../../src/security/posture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"posture.js","sourceRoot":"","sources":["../../src/security/posture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * State store factory (`state` config block).
3
+ *
4
+ * @module state
5
+ */
6
+ import type { StateConfig } from '../utils/types.js';
7
+ import { type StateStore } from './store.js';
8
+ export { MemoryStateStore, PrefixedStateStore } from './store.js';
9
+ export type { StateStore } from './store.js';
10
+ export { RedisStateStore, RedisClient, RespParser, encodeCommand } from './redis.js';
11
+ export { createStoreRateLimiter, StoreAuthLockout } from './shared.js';
12
+ /** Build the configured store; `memory` when `state` is absent. */
13
+ export declare function createStateStore(config: StateConfig | undefined): StateStore;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAwC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGnF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEvE,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAY5E"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * State store factory (`state` config block).
3
+ *
4
+ * @module state
5
+ */
6
+ import { MemoryStateStore, PrefixedStateStore } from './store.js';
7
+ import { RedisStateStore } from './redis.js';
8
+ export { MemoryStateStore, PrefixedStateStore } from './store.js';
9
+ export { RedisStateStore, RedisClient, RespParser, encodeCommand } from './redis.js';
10
+ export { createStoreRateLimiter, StoreAuthLockout } from './shared.js';
11
+ /** Build the configured store; `memory` when `state` is absent. */
12
+ export function createStateStore(config) {
13
+ if (!config || (config.store ?? 'memory') === 'memory')
14
+ return new MemoryStateStore();
15
+ if (config.store === 'redis') {
16
+ if (!config.redis?.url)
17
+ throw new Error('state.store is "redis" but state.redis.url is not set');
18
+ const redis = new RedisStateStore({
19
+ url: config.redis.url,
20
+ connectTimeoutMs: config.redis.connectTimeoutMs,
21
+ commandTimeoutMs: config.redis.commandTimeoutMs,
22
+ });
23
+ return new PrefixedStateStore(redis, config.redis.keyPrefix ?? 'mcp-gateway:');
24
+ }
25
+ throw new Error(`Unknown state.store "${String(config.store)}"`);
26
+ }
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAmB,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEvE,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,MAA+B;IAC9D,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,gBAAgB,EAAE,CAAC;IACtF,IAAI,MAAM,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACjG,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC;YAChC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG;YACrB,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,gBAAgB;YAC/C,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,gBAAgB;SAChD,CAAC,CAAC;QACH,OAAO,IAAI,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,cAAc,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Redis-backed `StateStore` with a small built-in RESP2 client (no extra
3
+ * dependency). Supports `redis://` and `rediss://` (TLS) URLs with optional
4
+ * `user:password@` credentials and a `/db` number. Commands are pipelined on
5
+ * one connection; the connection is re-established lazily after an error.
6
+ *
7
+ * @module state/redis
8
+ */
9
+ import type { StateStore } from './store.js';
10
+ export type RespValue = string | number | null | RespValue[] | RespError;
11
+ export declare class RespError extends Error {
12
+ }
13
+ /** Incremental RESP2 parser. Returns parsed values and leaves partial data buffered. */
14
+ export declare class RespParser {
15
+ private buf;
16
+ push(chunk: Buffer): RespValue[];
17
+ private line;
18
+ private parse;
19
+ }
20
+ export declare function encodeCommand(args: Array<string | number>): Buffer;
21
+ export interface RedisOptions {
22
+ url: string;
23
+ connectTimeoutMs?: number;
24
+ commandTimeoutMs?: number;
25
+ }
26
+ /** Minimal pipelining Redis client. */
27
+ export declare class RedisClient {
28
+ private readonly options;
29
+ private socket?;
30
+ private connecting?;
31
+ private queue;
32
+ private parser;
33
+ private closed;
34
+ private readonly url;
35
+ constructor(options: RedisOptions);
36
+ private failAll;
37
+ private open;
38
+ private raw;
39
+ command(...args: Array<string | number>): Promise<RespValue>;
40
+ /** Run commands inside MULTI / EXEC; resolves with the EXEC reply array. */
41
+ transaction(commands: Array<Array<string | number>>): Promise<RespValue[]>;
42
+ close(): Promise<void>;
43
+ }
44
+ export declare class RedisStateStore implements StateStore {
45
+ readonly kind = "redis";
46
+ readonly client: RedisClient;
47
+ constructor(options: RedisOptions);
48
+ incr(key: string, ttlMs: number, by?: number): Promise<number>;
49
+ get(key: string): Promise<string | undefined>;
50
+ set(key: string, value: string, ttlMs?: number): Promise<void>;
51
+ del(key: string): Promise<void>;
52
+ pttl(key: string): Promise<number>;
53
+ ping(): Promise<void>;
54
+ close(): Promise<void>;
55
+ }
56
+ //# sourceMappingURL=redis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/state/redis.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,SAAS,CAAC;AAEzE,qBAAa,SAAU,SAAQ,KAAK;CAAG;AAOvC,wFAAwF;AACxF,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAA2B;IAEtC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE;IAYhC,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,KAAK;CAmCd;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAOlE;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,uCAAuC;AACvC,qBAAa,WAAW;IAQV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPpC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,UAAU,CAAC,CAAkB;IACrC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;gBAEG,OAAO,EAAE,YAAY;IAOlD,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,IAAI;IAyDZ,OAAO,CAAC,GAAG;IAqBL,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAMlE,4EAA4E;IACtE,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAW1E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAa7B;AAED,qBAAa,eAAgB,YAAW,UAAU;IAChD,QAAQ,CAAC,IAAI,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;gBAEjB,OAAO,EAAE,YAAY;IAI3B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,SAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IASzD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAK7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvB"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Redis-backed `StateStore` with a small built-in RESP2 client (no extra
3
+ * dependency). Supports `redis://` and `rediss://` (TLS) URLs with optional
4
+ * `user:password@` credentials and a `/db` number. Commands are pipelined on
5
+ * one connection; the connection is re-established lazily after an error.
6
+ *
7
+ * @module state/redis
8
+ */
9
+ import { connect as netConnect } from 'net';
10
+ import { connect as tlsConnect } from 'tls';
11
+ import { logger } from '../utils/logger.js';
12
+ export class RespError extends Error {
13
+ }
14
+ /** Incremental RESP2 parser. Returns parsed values and leaves partial data buffered. */
15
+ export class RespParser {
16
+ buf = Buffer.alloc(0);
17
+ push(chunk) {
18
+ this.buf = this.buf.length ? Buffer.concat([this.buf, chunk]) : chunk;
19
+ const out = [];
20
+ for (;;) {
21
+ const r = this.parse(0);
22
+ if (!r)
23
+ break;
24
+ out.push(r.value);
25
+ this.buf = this.buf.subarray(r.end);
26
+ }
27
+ return out;
28
+ }
29
+ line(from) {
30
+ const i = this.buf.indexOf('\r\n', from);
31
+ if (i < 0)
32
+ return undefined;
33
+ return { text: this.buf.toString('utf8', from, i), end: i + 2 };
34
+ }
35
+ parse(at) {
36
+ if (at >= this.buf.length)
37
+ return undefined;
38
+ const type = String.fromCharCode(this.buf[at]);
39
+ const l = this.line(at + 1);
40
+ if (!l)
41
+ return undefined;
42
+ switch (type) {
43
+ case '+':
44
+ return { value: l.text, end: l.end };
45
+ case '-':
46
+ return { value: new RespError(l.text), end: l.end };
47
+ case ':':
48
+ return { value: Number(l.text), end: l.end };
49
+ case '$': {
50
+ const len = Number(l.text);
51
+ if (len < 0)
52
+ return { value: null, end: l.end };
53
+ if (this.buf.length < l.end + len + 2)
54
+ return undefined;
55
+ return { value: this.buf.toString('utf8', l.end, l.end + len), end: l.end + len + 2 };
56
+ }
57
+ case '*': {
58
+ const n = Number(l.text);
59
+ if (n < 0)
60
+ return { value: null, end: l.end };
61
+ const items = [];
62
+ let end = l.end;
63
+ for (let i = 0; i < n; i++) {
64
+ const r = this.parse(end);
65
+ if (!r)
66
+ return undefined;
67
+ items.push(r.value);
68
+ end = r.end;
69
+ }
70
+ return { value: items, end };
71
+ }
72
+ default:
73
+ throw new Error(`RESP protocol error: unexpected type byte "${type}"`);
74
+ }
75
+ }
76
+ }
77
+ export function encodeCommand(args) {
78
+ const parts = [`*${args.length}\r\n`];
79
+ for (const a of args) {
80
+ const s = String(a);
81
+ parts.push(`$${Buffer.byteLength(s)}\r\n${s}\r\n`);
82
+ }
83
+ return Buffer.from(parts.join(''));
84
+ }
85
+ /** Minimal pipelining Redis client. */
86
+ export class RedisClient {
87
+ options;
88
+ socket;
89
+ connecting;
90
+ queue = [];
91
+ parser = new RespParser();
92
+ closed = false;
93
+ url;
94
+ constructor(options) {
95
+ this.options = options;
96
+ this.url = new URL(options.url);
97
+ if (this.url.protocol !== 'redis:' && this.url.protocol !== 'rediss:') {
98
+ throw new Error(`state.redis.url must start with redis:// or rediss:// (got ${this.url.protocol})`);
99
+ }
100
+ }
101
+ failAll(err) {
102
+ const q = this.queue;
103
+ this.queue = [];
104
+ for (const p of q)
105
+ p.reject(err);
106
+ }
107
+ open() {
108
+ if (this.socket && !this.socket.destroyed)
109
+ return Promise.resolve(this.socket);
110
+ if (this.connecting)
111
+ return this.connecting;
112
+ this.connecting = new Promise((resolve, reject) => {
113
+ const port = Number(this.url.port || 6379);
114
+ const host = this.url.hostname.replace(/^\[|\]$/g, '');
115
+ const socket = this.url.protocol === 'rediss:' ? tlsConnect({ host, port, servername: host }) : netConnect({ host, port });
116
+ const timer = setTimeout(() => socket.destroy(new Error('Redis connect timeout')), this.options.connectTimeoutMs ?? 5_000);
117
+ timer.unref();
118
+ this.parser = new RespParser();
119
+ socket.on('data', (chunk) => {
120
+ let values;
121
+ try {
122
+ values = this.parser.push(chunk);
123
+ }
124
+ catch (err) {
125
+ socket.destroy(err);
126
+ return;
127
+ }
128
+ for (const v of values) {
129
+ const p = this.queue.shift();
130
+ if (!p)
131
+ continue;
132
+ if (v instanceof RespError)
133
+ p.reject(v);
134
+ else
135
+ p.resolve(v);
136
+ }
137
+ });
138
+ socket.on('error', (err) => {
139
+ logger.debug(`Redis connection error: ${err.message}`);
140
+ });
141
+ socket.on('close', () => {
142
+ if (this.socket === socket)
143
+ this.socket = undefined;
144
+ this.failAll(new Error('Redis connection closed'));
145
+ });
146
+ socket.once(this.url.protocol === 'rediss:' ? 'secureConnect' : 'connect', () => {
147
+ clearTimeout(timer);
148
+ this.socket = socket;
149
+ resolve(socket);
150
+ });
151
+ socket.once('close', () => {
152
+ clearTimeout(timer);
153
+ reject(new Error(`Could not connect to Redis at ${host}:${port}`));
154
+ });
155
+ })
156
+ .then(async (socket) => {
157
+ const user = decodeURIComponent(this.url.username);
158
+ const pass = decodeURIComponent(this.url.password);
159
+ if (pass)
160
+ await this.raw(socket, user ? ['AUTH', user, pass] : ['AUTH', pass]);
161
+ const db = this.url.pathname.replace(/^\//, '');
162
+ if (db && db !== '0')
163
+ await this.raw(socket, ['SELECT', db]);
164
+ return socket;
165
+ })
166
+ .finally(() => {
167
+ this.connecting = undefined;
168
+ });
169
+ return this.connecting;
170
+ }
171
+ raw(socket, args) {
172
+ return new Promise((resolve, reject) => {
173
+ const timer = setTimeout(() => {
174
+ reject(new Error(`Redis command timed out: ${String(args[0])}`));
175
+ socket.destroy();
176
+ }, this.options.commandTimeoutMs ?? 5_000);
177
+ timer.unref();
178
+ this.queue.push({
179
+ resolve: (v) => {
180
+ clearTimeout(timer);
181
+ resolve(v);
182
+ },
183
+ reject: (e) => {
184
+ clearTimeout(timer);
185
+ reject(e);
186
+ },
187
+ });
188
+ socket.write(encodeCommand(args));
189
+ });
190
+ }
191
+ async command(...args) {
192
+ if (this.closed)
193
+ throw new Error('Redis client is closed');
194
+ const socket = await this.open();
195
+ return this.raw(socket, args);
196
+ }
197
+ /** Run commands inside MULTI / EXEC; resolves with the EXEC reply array. */
198
+ async transaction(commands) {
199
+ if (this.closed)
200
+ throw new Error('Redis client is closed');
201
+ const socket = await this.open();
202
+ const replies = [this.raw(socket, ['MULTI']), ...commands.map((c) => this.raw(socket, c)), this.raw(socket, ['EXEC'])];
203
+ const all = await Promise.all(replies);
204
+ const exec = all[all.length - 1];
205
+ if (!Array.isArray(exec))
206
+ throw new Error('Redis transaction aborted');
207
+ for (const v of exec)
208
+ if (v instanceof RespError)
209
+ throw v;
210
+ return exec;
211
+ }
212
+ async close() {
213
+ this.closed = true;
214
+ const s = this.socket;
215
+ this.socket = undefined;
216
+ if (s && !s.destroyed) {
217
+ await new Promise((resolve) => {
218
+ s.once('close', () => resolve());
219
+ s.end(encodeCommand(['QUIT']));
220
+ setTimeout(() => s.destroy(), 500).unref();
221
+ });
222
+ }
223
+ this.failAll(new Error('Redis client is closed'));
224
+ }
225
+ }
226
+ export class RedisStateStore {
227
+ kind = 'redis';
228
+ client;
229
+ constructor(options) {
230
+ this.client = new RedisClient(options);
231
+ }
232
+ async incr(key, ttlMs, by = 1) {
233
+ const ttl = Math.max(1, Math.ceil(ttlMs));
234
+ const replies = await this.client.transaction([
235
+ ['SET', key, '0', 'PX', ttl, 'NX'],
236
+ ['INCRBY', key, by],
237
+ ]);
238
+ return Number(replies[1]);
239
+ }
240
+ async get(key) {
241
+ const v = await this.client.command('GET', key);
242
+ return v === null ? undefined : String(v);
243
+ }
244
+ async set(key, value, ttlMs) {
245
+ if (ttlMs && ttlMs > 0)
246
+ await this.client.command('SET', key, value, 'PX', Math.ceil(ttlMs));
247
+ else
248
+ await this.client.command('SET', key, value);
249
+ }
250
+ async del(key) {
251
+ await this.client.command('DEL', key);
252
+ }
253
+ async pttl(key) {
254
+ return Number(await this.client.command('PTTL', key));
255
+ }
256
+ async ping() {
257
+ await this.client.command('PING');
258
+ }
259
+ close() {
260
+ return this.client.close();
261
+ }
262
+ }
263
+ //# sourceMappingURL=redis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/state/redis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Rate limiting and brute-force lockout on top of a shared `StateStore`
3
+ * (used when `state.store` is not `memory`).
4
+ *
5
+ * Both fail open by default when the store is unreachable (a Redis outage
6
+ * must not take every tool call down); set `state.failureMode: closed` to
7
+ * reject requests instead.
8
+ *
9
+ * @module state/shared
10
+ */
11
+ import type { AuthLockoutConfig, RateLimitConfig } from '../utils/types.js';
12
+ import { type RateLimiter } from '../auth/ratelimit.js';
13
+ import { type LockoutTracker } from '../security/lockout.js';
14
+ import type { StateStore } from './store.js';
15
+ export type FailureMode = 'open' | 'closed';
16
+ /**
17
+ * Sliding-window rate limiter whose counters live in the store, so the limit
18
+ * holds across every gateway instance sharing it.
19
+ */
20
+ export declare function createStoreRateLimiter(config: RateLimitConfig, store: StateStore, options?: {
21
+ failureMode?: FailureMode;
22
+ now?: () => number;
23
+ namespace?: string;
24
+ }): RateLimiter;
25
+ /** Brute-force lockout with failure counters and locks kept in the store. */
26
+ export declare class StoreAuthLockout implements LockoutTracker {
27
+ private readonly store;
28
+ private readonly failureMode;
29
+ readonly config: Required<AuthLockoutConfig>;
30
+ private total;
31
+ private readonly recent;
32
+ constructor(config: AuthLockoutConfig, store: StateStore, failureMode?: FailureMode);
33
+ lockedFor(ip: string): Promise<number>;
34
+ fail(ip: string): Promise<boolean>;
35
+ success(ip: string): Promise<void>;
36
+ /** Lockouts triggered by this instance (the store holds the cluster-wide state). */
37
+ status(): {
38
+ lockedClients: number;
39
+ trackedClients: number;
40
+ lockoutsTotal: number;
41
+ shared: boolean;
42
+ };
43
+ close(): void;
44
+ }
45
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/state/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAW5C;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAClF,WAAW,CAiDb;AAED,6EAA6E;AAC7E,qBAAa,gBAAiB,YAAW,cAAc;IAOnD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAP9B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC7C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;gBAGlD,MAAM,EAAE,iBAAiB,EACR,KAAK,EAAE,UAAU,EACjB,WAAW,GAAE,WAAoB;IAK9C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUtC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBlC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,oFAAoF;IACpF,MAAM;;;;;;IAMN,KAAK,IAAI,IAAI;CAGd"}