@codemem/mcp 0.33.0-alpha.3 → 0.34.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/http.d.ts +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +609 -345
- package/dist/http.js.map +1 -1
- package/dist/oauth.d.ts +43 -0
- package/dist/oauth.d.ts.map +1 -1
- package/dist/stdio.js +10 -10
- package/package.json +2 -2
package/dist/http.js
CHANGED
|
@@ -10,8 +10,12 @@ import { StreamableHTTPServerTransport as d } from "@modelcontextprotocol/sdk/se
|
|
|
10
10
|
import f from "express";
|
|
11
11
|
import { Buffer as p } from "node:buffer";
|
|
12
12
|
import { createHash as m, createHmac as h, createPublicKey as g, randomBytes as _, randomUUID as v, timingSafeEqual as y, verify as b } from "node:crypto";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { existsSync as ee, mkdirSync as x, readFileSync as S, renameSync as te, writeFileSync as C } from "node:fs";
|
|
14
|
+
import { chmod as w } from "node:fs/promises";
|
|
15
|
+
import { homedir as T } from "node:os";
|
|
16
|
+
import { dirname as E, join as D } from "node:path";
|
|
17
|
+
import { AccessDeniedError as ne, InvalidClientError as re, InvalidClientMetadataError as O, InvalidGrantError as k, InvalidRequestError as ie, InvalidTokenError as ae, ServerError as oe, TemporarilyUnavailableError as A, UnsupportedResponseTypeError as se } from "@modelcontextprotocol/sdk/server/auth/errors.js";
|
|
18
|
+
import { OAuthProtectedResourceMetadataSchema as ce, OAuthTokensSchema as le } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
15
19
|
//#region \0rolldown/runtime.js
|
|
16
20
|
var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t.exports), M = /* @__PURE__ */ j(((e) => {
|
|
17
21
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.isInSubnet = t, e.isCorrect = n, e.numberToPaddedHex = r, e.stringToPaddedHex = i, e.testBit = a;
|
|
@@ -35,7 +39,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
35
39
|
let r = n - t;
|
|
36
40
|
return e.substring(r, r + 1) === "1";
|
|
37
41
|
}
|
|
38
|
-
})),
|
|
42
|
+
})), ue = /* @__PURE__ */ j(((e) => {
|
|
39
43
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.RE_SUBNET_STRING = e.RE_ADDRESS = e.GROUPS = e.BITS = void 0, e.BITS = 32, e.GROUPS = 4, e.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g, e.RE_SUBNET_STRING = /\/\d{1,2}$/;
|
|
40
44
|
})), N = /* @__PURE__ */ j(((e) => {
|
|
41
45
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.AddressError = void 0, e.AddressError = class extends Error {
|
|
@@ -43,7 +47,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
43
47
|
super(e), this.name = "AddressError", this.parseMessage = t;
|
|
44
48
|
}
|
|
45
49
|
};
|
|
46
|
-
})),
|
|
50
|
+
})), de = /* @__PURE__ */ j(((e) => {
|
|
47
51
|
var t = e && e.__createBinding || (Object.create ? (function(e, t, n, r) {
|
|
48
52
|
r === void 0 && (r = n);
|
|
49
53
|
var i = Object.getOwnPropertyDescriptor(t, n);
|
|
@@ -69,7 +73,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
69
73
|
return n(r, e), r;
|
|
70
74
|
};
|
|
71
75
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.Address4 = void 0;
|
|
72
|
-
var i = r(M()), a = r(
|
|
76
|
+
var i = r(M()), a = r(ue()), o = N();
|
|
73
77
|
e.Address4 = class e {
|
|
74
78
|
constructor(e) {
|
|
75
79
|
this.groups = a.GROUPS, this.parsedAddress = [], this.parsedSubnet = "", this.subnet = "/32", this.subnetMask = 32, this.v4 = !0, this.isCorrect = i.isCorrect(a.BITS), this.isInSubnet = i.isInSubnet, this.address = e;
|
|
@@ -177,7 +181,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
177
181
|
return this.address.replace(a.RE_ADDRESS, `<span class="hover-group group-v4 group-6">${e.slice(0, 2).join(".")}</span>.<span class="hover-group group-v4 group-7">${e.slice(2, 4).join(".")}</span>`);
|
|
178
182
|
}
|
|
179
183
|
};
|
|
180
|
-
})),
|
|
184
|
+
})), fe = /* @__PURE__ */ j(((e) => {
|
|
181
185
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.RE_URL_WITH_PORT = e.RE_URL = e.RE_ZONE_STRING = e.RE_SUBNET_STRING = e.RE_BAD_ADDRESS = e.RE_BAD_CHARACTERS = e.TYPES = e.SCOPES = e.GROUPS = e.BITS = void 0, e.BITS = 128, e.GROUPS = 8, e.SCOPES = {
|
|
182
186
|
0: "Reserved",
|
|
183
187
|
1: "Interface local",
|
|
@@ -211,7 +215,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
211
215
|
"ff00::/8": "Multicast",
|
|
212
216
|
"fe80::/10": "Link-local unicast"
|
|
213
217
|
}, e.RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi, e.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi, e.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/, e.RE_ZONE_STRING = /%.*$/, e.RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/, e.RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/;
|
|
214
|
-
})),
|
|
218
|
+
})), pe = /* @__PURE__ */ j(((e) => {
|
|
215
219
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.escapeHtml = t, e.spanAllZeroes = n, e.spanAll = r, e.spanLeadingZeroes = a, e.simpleGroup = o;
|
|
216
220
|
function t(e) {
|
|
217
221
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -231,7 +235,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
231
235
|
function o(e, t = 0) {
|
|
232
236
|
return e.split(":").map((e, n) => /group-v4/.test(e) ? e : `<span class="hover-group group-${n + t}">${i(e)}</span>`);
|
|
233
237
|
}
|
|
234
|
-
})),
|
|
238
|
+
})), me = /* @__PURE__ */ j(((e) => {
|
|
235
239
|
var t = e && e.__createBinding || (Object.create ? (function(e, t, n, r) {
|
|
236
240
|
r === void 0 && (r = n);
|
|
237
241
|
var i = Object.getOwnPropertyDescriptor(t, n);
|
|
@@ -257,7 +261,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
257
261
|
return n(r, e), r;
|
|
258
262
|
};
|
|
259
263
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.ADDRESS_BOUNDARY = void 0, e.groupPossibilities = a, e.padGroup = o, e.simpleRegularExpression = s, e.possibleElisions = c;
|
|
260
|
-
var i = r(
|
|
264
|
+
var i = r(fe());
|
|
261
265
|
function a(e) {
|
|
262
266
|
return `(${e.join("|")})`;
|
|
263
267
|
}
|
|
@@ -285,7 +289,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
285
289
|
for (let t = 1; t < e - 1; t++) for (let n = 1; n < e - t; n++) o.push(`(0{1,4}:){${n}}:(0{1,4}:){${e - n - t - 1}}0{1,4}`);
|
|
286
290
|
return a(o);
|
|
287
291
|
}
|
|
288
|
-
})),
|
|
292
|
+
})), he = /* @__PURE__ */ j(((e) => {
|
|
289
293
|
var t = e && e.__createBinding || (Object.create ? (function(e, t, n, r) {
|
|
290
294
|
r === void 0 && (r = n);
|
|
291
295
|
var i = Object.getOwnPropertyDescriptor(t, n);
|
|
@@ -311,7 +315,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
311
315
|
return n(r, e), r;
|
|
312
316
|
};
|
|
313
317
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.Address6 = void 0;
|
|
314
|
-
var i = r(M()), a = r(
|
|
318
|
+
var i = r(M()), a = r(ue()), o = r(fe()), s = r(pe()), c = de(), l = me(), u = N(), d = M();
|
|
315
319
|
function f(e) {
|
|
316
320
|
if (!e) throw Error("Assertion failed.");
|
|
317
321
|
}
|
|
@@ -629,7 +633,7 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
629
633
|
return new RegExp(this.regularExpressionString(e), "i");
|
|
630
634
|
}
|
|
631
635
|
};
|
|
632
|
-
})),
|
|
636
|
+
})), ge = (/* @__PURE__ */ j(((e) => {
|
|
633
637
|
var t = e && e.__createBinding || (Object.create ? (function(e, t, n, r) {
|
|
634
638
|
r === void 0 && (r = n);
|
|
635
639
|
var i = Object.getOwnPropertyDescriptor(t, n);
|
|
@@ -655,14 +659,14 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
655
659
|
return n(r, e), r;
|
|
656
660
|
};
|
|
657
661
|
Object.defineProperty(e, "__esModule", { value: !0 }), e.v6 = e.AddressError = e.Address6 = e.Address4 = void 0;
|
|
658
|
-
var i =
|
|
662
|
+
var i = de();
|
|
659
663
|
Object.defineProperty(e, "Address4", {
|
|
660
664
|
enumerable: !0,
|
|
661
665
|
get: function() {
|
|
662
666
|
return i.Address4;
|
|
663
667
|
}
|
|
664
668
|
});
|
|
665
|
-
var a =
|
|
669
|
+
var a = he();
|
|
666
670
|
Object.defineProperty(e, "Address6", {
|
|
667
671
|
enumerable: !0,
|
|
668
672
|
get: function() {
|
|
@@ -675,17 +679,17 @@ var j = (e, t) => () => (t || (e((t = { exports: {} }).exports, t), e = null), t
|
|
|
675
679
|
get: function() {
|
|
676
680
|
return o.AddressError;
|
|
677
681
|
}
|
|
678
|
-
}), e.v6 = { helpers: r(
|
|
682
|
+
}), e.v6 = { helpers: r(pe()) };
|
|
679
683
|
})))();
|
|
680
|
-
function
|
|
684
|
+
function _e(e, t = 56) {
|
|
681
685
|
if (r(e)) {
|
|
682
|
-
let n = new
|
|
686
|
+
let n = new ge.Address6(e);
|
|
683
687
|
if (n.is4()) return n.to4().correctForm();
|
|
684
|
-
if (t) return new
|
|
688
|
+
if (t) return new ge.Address6(`${e}/${t}`).networkForm();
|
|
685
689
|
}
|
|
686
690
|
return e;
|
|
687
691
|
}
|
|
688
|
-
var
|
|
692
|
+
var ve = class {
|
|
689
693
|
constructor(e) {
|
|
690
694
|
this.validations = e, this.previous = /* @__PURE__ */ new Map(), this.current = /* @__PURE__ */ new Map(), this.localKeys = !0;
|
|
691
695
|
}
|
|
@@ -728,14 +732,14 @@ var le = class {
|
|
|
728
732
|
clearExpired() {
|
|
729
733
|
this.previous = this.current, this.current = /* @__PURE__ */ new Map();
|
|
730
734
|
}
|
|
731
|
-
},
|
|
735
|
+
}, ye = {
|
|
732
736
|
warn(...e) {
|
|
733
737
|
console.warn(...e.reverse());
|
|
734
738
|
},
|
|
735
739
|
error(...e) {
|
|
736
740
|
console.error(...e.reverse());
|
|
737
741
|
}
|
|
738
|
-
},
|
|
742
|
+
}, be = [
|
|
739
743
|
"draft-6",
|
|
740
744
|
"draft-7",
|
|
741
745
|
"draft-8"
|
|
@@ -746,30 +750,30 @@ var le = class {
|
|
|
746
750
|
n = Math.max(0, e);
|
|
747
751
|
} else n = Math.ceil(e / 1e3);
|
|
748
752
|
return n;
|
|
749
|
-
},
|
|
753
|
+
}, xe = (e) => {
|
|
750
754
|
let t = m("sha256");
|
|
751
755
|
t.update(e);
|
|
752
756
|
let n = t.digest("hex").slice(0, 12);
|
|
753
757
|
return p.from(n).toString("base64");
|
|
754
|
-
},
|
|
758
|
+
}, Se = (e, t) => {
|
|
755
759
|
e.headersSent || (e.setHeader("X-RateLimit-Limit", t.limit.toString()), e.setHeader("X-RateLimit-Remaining", t.remaining.toString()), t.resetTime instanceof Date && (e.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString()), e.setHeader("X-RateLimit-Reset", Math.ceil(t.resetTime.getTime() / 1e3).toString())));
|
|
756
|
-
},
|
|
760
|
+
}, Ce = (e, t, n) => {
|
|
757
761
|
if (e.headersSent) return;
|
|
758
762
|
let r = Math.ceil(n / 1e3), i = P(n, t.resetTime);
|
|
759
763
|
e.setHeader("RateLimit-Policy", `${t.limit};w=${r}`), e.setHeader("RateLimit-Limit", t.limit.toString()), e.setHeader("RateLimit-Remaining", t.remaining.toString()), typeof i == "number" && e.setHeader("RateLimit-Reset", i.toString());
|
|
760
|
-
},
|
|
764
|
+
}, we = (e, t, n) => {
|
|
761
765
|
if (e.headersSent) return;
|
|
762
766
|
let r = Math.ceil(n / 1e3), i = P(n, t.resetTime);
|
|
763
767
|
e.setHeader("RateLimit-Policy", `${t.limit};w=${r}`), e.setHeader("RateLimit", `limit=${t.limit}, remaining=${t.remaining}, reset=${i}`);
|
|
764
|
-
},
|
|
768
|
+
}, Te = (e, t, n, r, i) => {
|
|
765
769
|
if (e.headersSent) return;
|
|
766
|
-
let a = Math.ceil(n / 1e3), o = P(n, t.resetTime), s =
|
|
770
|
+
let a = Math.ceil(n / 1e3), o = P(n, t.resetTime), s = xe(i), c = `r=${t.remaining}; t=${o}`, l = `q=${t.limit}; w=${a}; pk=:${s}:`;
|
|
767
771
|
e.append("RateLimit", `"${r}"; ${c}`), e.append("RateLimit-Policy", `"${r}"; ${l}`);
|
|
768
|
-
},
|
|
772
|
+
}, Ee = (e, t, n) => {
|
|
769
773
|
if (e.headersSent) return;
|
|
770
774
|
let r = P(n, t.resetTime);
|
|
771
775
|
e.setHeader("Retry-After", r.toString());
|
|
772
|
-
},
|
|
776
|
+
}, De = (e) => {
|
|
773
777
|
let t = {};
|
|
774
778
|
for (let n of Object.keys(e)) {
|
|
775
779
|
let r = n;
|
|
@@ -781,7 +785,7 @@ var le = class {
|
|
|
781
785
|
let n = `https://express-rate-limit.github.io/${e}/`;
|
|
782
786
|
super(`${t} See ${n} for more information.`), this.name = this.constructor.name, this.code = e, this.help = n;
|
|
783
787
|
}
|
|
784
|
-
}, I = class extends F {},
|
|
788
|
+
}, I = class extends F {}, Oe = /* @__PURE__ */ new Set(), ke = /* @__PURE__ */ new WeakMap(), Ae = {
|
|
785
789
|
enabled: { default: !0 },
|
|
786
790
|
disable() {
|
|
787
791
|
for (let e of Object.keys(this.enabled)) this.enabled[e] = !1;
|
|
@@ -803,15 +807,15 @@ var le = class {
|
|
|
803
807
|
if (typeof e != "number" || e < 1 || e !== Math.round(e)) throw new F("ERR_ERL_INVALID_HITS", `The totalHits value returned from the store must be a positive integer, got ${e}`);
|
|
804
808
|
},
|
|
805
809
|
unsharedStore(e) {
|
|
806
|
-
if (
|
|
810
|
+
if (Oe.has(e)) {
|
|
807
811
|
let t = e?.localKeys ? "" : " (with a unique prefix)";
|
|
808
812
|
throw new F("ERR_ERL_STORE_REUSE", `A Store instance must not be shared across multiple rate limiters. Create a new instance of ${e.constructor.name}${t} for each limiter instead.`);
|
|
809
813
|
}
|
|
810
|
-
|
|
814
|
+
Oe.add(e);
|
|
811
815
|
},
|
|
812
816
|
singleCount(e, t, n) {
|
|
813
|
-
let r =
|
|
814
|
-
r || (r = /* @__PURE__ */ new Map(),
|
|
817
|
+
let r = ke.get(e);
|
|
818
|
+
r || (r = /* @__PURE__ */ new Map(), ke.set(e, r));
|
|
815
819
|
let i = t.localKeys ? t : t.constructor.name, a = r.get(i);
|
|
816
820
|
a || (a = [], r.set(i, a));
|
|
817
821
|
let o = `${t.prefix ?? ""}${n}`;
|
|
@@ -828,7 +832,7 @@ var le = class {
|
|
|
828
832
|
if (e) throw new I("WRN_ERL_DEPRECATED_ON_LIMIT_REACHED", "The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.");
|
|
829
833
|
},
|
|
830
834
|
headersDraftVersion(e) {
|
|
831
|
-
if (typeof e != "string" || !
|
|
835
|
+
if (typeof e != "string" || !be.includes(e)) throw new F("ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION", `standardHeaders: only the following versions of the IETF draft specification are supported: ${be.join(", ")}.`);
|
|
832
836
|
},
|
|
833
837
|
headersResetTime(e) {
|
|
834
838
|
if (!e) throw new F("ERR_ERL_HEADERS_NO_RESET", "standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.");
|
|
@@ -885,18 +889,18 @@ var le = class {
|
|
|
885
889
|
if (typeof e != "number" || Number.isNaN(e) || e < 1 || e > t) throw new F("ERR_ERL_WINDOW_MS", `Invalid windowMs value: ${e}${typeof e == "number" ? "" : ` (${typeof e})`}, must be a number between 1 and ${t} when using the default MemoryStore`);
|
|
886
890
|
}
|
|
887
891
|
};
|
|
888
|
-
function
|
|
892
|
+
function je(e) {
|
|
889
893
|
if (typeof e != "object" || typeof e.error != "function" || typeof e.warn != "function") throw TypeError("Provided logger does not implement the Logger interface");
|
|
890
894
|
}
|
|
891
|
-
var
|
|
892
|
-
|
|
895
|
+
var Me = (e, t) => {
|
|
896
|
+
je(t);
|
|
893
897
|
let n;
|
|
894
898
|
n = typeof e == "boolean" ? { default: e } : {
|
|
895
899
|
default: !0,
|
|
896
900
|
...e
|
|
897
901
|
};
|
|
898
902
|
let r = { enabled: n };
|
|
899
|
-
for (let [e, i] of Object.entries(
|
|
903
|
+
for (let [e, i] of Object.entries(Ae)) typeof i == "function" && (r[e] = (...a) => {
|
|
900
904
|
if (n[e] ?? n.default) try {
|
|
901
905
|
i.apply(r, a);
|
|
902
906
|
} catch (e) {
|
|
@@ -904,8 +908,8 @@ var Ce = (e, t) => {
|
|
|
904
908
|
}
|
|
905
909
|
});
|
|
906
910
|
return r;
|
|
907
|
-
},
|
|
908
|
-
if (!
|
|
911
|
+
}, Ne = (e) => typeof e.incr == "function" && typeof e.increment != "function", Pe = (e) => {
|
|
912
|
+
if (!Ne(e)) return e;
|
|
909
913
|
let t = e;
|
|
910
914
|
class n {
|
|
911
915
|
async increment(e) {
|
|
@@ -930,14 +934,14 @@ var Ce = (e, t) => {
|
|
|
930
934
|
}
|
|
931
935
|
}
|
|
932
936
|
return new n();
|
|
933
|
-
},
|
|
937
|
+
}, Fe = (e) => {
|
|
934
938
|
let { validations: t, ...n } = e;
|
|
935
939
|
return {
|
|
936
940
|
...n,
|
|
937
941
|
validate: t.enabled
|
|
938
942
|
};
|
|
939
|
-
},
|
|
940
|
-
let t =
|
|
943
|
+
}, Ie = (e) => {
|
|
944
|
+
let t = De(e), n = e.logger ?? ye, i = Me(t?.validate ?? !0, n);
|
|
941
945
|
i.validationsConfig(), i.knownOptions(e), i.draftPolliHeaders(t.draft_polli_ratelimit_headers), i.onLimitReached(t.onLimitReached), t.ipv6Subnet !== void 0 && typeof t.ipv6Subnet != "function" && i.ipv6Subnet(t.ipv6Subnet), i.keyGeneratorIpFallback(t.keyGenerator), i.ipv6SubnetOrKeyGenerator(t);
|
|
942
946
|
let a = t.standardHeaders ?? !1;
|
|
943
947
|
a === !0 && (a = "draft-6");
|
|
@@ -959,7 +963,7 @@ var Ce = (e, t) => {
|
|
|
959
963
|
async keyGenerator(e, t) {
|
|
960
964
|
i.ip(e.ip), i.trustProxy(e), i.xForwardedForHeader(e), i.forwardedHeader(e);
|
|
961
965
|
let n = e.ip, a = 56;
|
|
962
|
-
return r(n) && (a = typeof o.ipv6Subnet == "function" ? await o.ipv6Subnet(e, t) : o.ipv6Subnet, typeof o.ipv6Subnet == "function" && i.ipv6Subnet(a)),
|
|
966
|
+
return r(n) && (a = typeof o.ipv6Subnet == "function" ? await o.ipv6Subnet(e, t) : o.ipv6Subnet, typeof o.ipv6Subnet == "function" && i.ipv6Subnet(a)), _e(n, a);
|
|
963
967
|
},
|
|
964
968
|
ipv6Subnet: 56,
|
|
965
969
|
async handler(e, t, n, r) {
|
|
@@ -970,27 +974,27 @@ var Ce = (e, t) => {
|
|
|
970
974
|
passOnStoreError: !1,
|
|
971
975
|
...t,
|
|
972
976
|
standardHeaders: a,
|
|
973
|
-
store:
|
|
977
|
+
store: Pe(t.store ?? new ve(i)),
|
|
974
978
|
validations: i,
|
|
975
979
|
logger: n
|
|
976
980
|
};
|
|
977
981
|
if (typeof o.store.increment != "function" || typeof o.store.decrement != "function" || typeof o.store.resetKey != "function" || o.store.resetAll !== void 0 && typeof o.store.resetAll != "function" || o.store.init !== void 0 && typeof o.store.init != "function") throw TypeError("An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.");
|
|
978
982
|
return o;
|
|
979
|
-
},
|
|
983
|
+
}, Le = (e) => async (t, n, r) => {
|
|
980
984
|
try {
|
|
981
985
|
await Promise.resolve(e(t, n, r)).catch(r);
|
|
982
986
|
} catch (e) {
|
|
983
987
|
r(e);
|
|
984
988
|
}
|
|
985
|
-
},
|
|
986
|
-
let t =
|
|
989
|
+
}, Re = (e) => {
|
|
990
|
+
let t = Ie(e ?? {}), n = Fe(t);
|
|
987
991
|
if (t.validations.creationStack(t.store), t.validations.unsharedStore(t.store), typeof t.store.init == "function") try {
|
|
988
992
|
let e = t.store.init(n);
|
|
989
993
|
e instanceof Promise && e.catch((e) => t.logger.error(e, "express-rate-limit: async error during store initialization."));
|
|
990
994
|
} catch (e) {
|
|
991
995
|
t.logger.error(e, "express-rate-limit: error during store initialization.");
|
|
992
996
|
}
|
|
993
|
-
let r =
|
|
997
|
+
let r = Le(async (e, r, i) => {
|
|
994
998
|
let a = t.skipFailedRequests && new Promise((e) => r.once("close", e)), o = (t.skipFailedRequests || t.skipSuccessfulRequests) && new Promise((e) => r.once("finish", e)), s = t.skipFailedRequests && new Promise((e) => r.once("error", e));
|
|
995
999
|
if (await t.skip(e, r)) {
|
|
996
1000
|
i();
|
|
@@ -1021,16 +1025,16 @@ var Ce = (e, t) => {
|
|
|
1021
1025
|
configurable: !1,
|
|
1022
1026
|
enumerable: !1,
|
|
1023
1027
|
value: u
|
|
1024
|
-
}), c[t.requestPropertyName] = p, t.legacyHeaders && !r.headersSent &&
|
|
1028
|
+
}), c[t.requestPropertyName] = p, t.legacyHeaders && !r.headersSent && Se(r, p), t.standardHeaders && !r.headersSent) switch (t.standardHeaders) {
|
|
1025
1029
|
case "draft-6":
|
|
1026
|
-
|
|
1030
|
+
Ce(r, p, t.windowMs);
|
|
1027
1031
|
break;
|
|
1028
1032
|
case "draft-7":
|
|
1029
|
-
t.validations.headersResetTime(p.resetTime),
|
|
1033
|
+
t.validations.headersResetTime(p.resetTime), we(r, p, t.windowMs);
|
|
1030
1034
|
break;
|
|
1031
1035
|
case "draft-8": {
|
|
1032
1036
|
let n = await (typeof t.identifier == "function" ? t.identifier(e, r) : t.identifier);
|
|
1033
|
-
t.validations.headersResetTime(p.resetTime),
|
|
1037
|
+
t.validations.headersResetTime(p.resetTime), Te(r, p, t.windowMs, n, l);
|
|
1034
1038
|
break;
|
|
1035
1039
|
}
|
|
1036
1040
|
default:
|
|
@@ -1052,7 +1056,7 @@ var Ce = (e, t) => {
|
|
|
1052
1056
|
});
|
|
1053
1057
|
}
|
|
1054
1058
|
if (t.validations.disable(), u > f) {
|
|
1055
|
-
(t.legacyHeaders || t.standardHeaders) &&
|
|
1059
|
+
(t.legacyHeaders || t.standardHeaders) && Ee(r, p, t.windowMs), t.handler(e, r, i, n);
|
|
1056
1060
|
return;
|
|
1057
1061
|
}
|
|
1058
1062
|
i();
|
|
@@ -1060,7 +1064,7 @@ var Ce = (e, t) => {
|
|
|
1060
1064
|
return r.resetKey = t.store.resetKey.bind(t.store), r.getKey = typeof t.store.get == "function" ? t.store.get.bind(t.store) : () => {
|
|
1061
1065
|
throw Error("The current store does not support the get/getKey method");
|
|
1062
1066
|
}, r;
|
|
1063
|
-
},
|
|
1067
|
+
}, ze = new Set([
|
|
1064
1068
|
"token",
|
|
1065
1069
|
"accesstoken",
|
|
1066
1070
|
"refreshtoken",
|
|
@@ -1073,11 +1077,11 @@ var Ce = (e, t) => {
|
|
|
1073
1077
|
"password",
|
|
1074
1078
|
"secret"
|
|
1075
1079
|
]);
|
|
1076
|
-
function
|
|
1080
|
+
function Be(e) {
|
|
1077
1081
|
return e.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1078
1082
|
}
|
|
1079
1083
|
function L(e, t) {
|
|
1080
|
-
for (let e of Object.keys(t)) if (
|
|
1084
|
+
for (let e of Object.keys(t)) if (ze.has(Be(e))) throw Error(`OAuth audit event must not carry forbidden field: ${e}`);
|
|
1081
1085
|
let { now: n, ...r } = t;
|
|
1082
1086
|
return {
|
|
1083
1087
|
kind: e,
|
|
@@ -1085,7 +1089,7 @@ function L(e, t) {
|
|
|
1085
1089
|
...r
|
|
1086
1090
|
};
|
|
1087
1091
|
}
|
|
1088
|
-
function
|
|
1092
|
+
function Ve(e) {
|
|
1089
1093
|
let t = !1;
|
|
1090
1094
|
return (n) => {
|
|
1091
1095
|
try {
|
|
@@ -1095,7 +1099,7 @@ function Me(e) {
|
|
|
1095
1099
|
}
|
|
1096
1100
|
};
|
|
1097
1101
|
}
|
|
1098
|
-
function
|
|
1102
|
+
function He(e = process.stderr) {
|
|
1099
1103
|
return (t) => {
|
|
1100
1104
|
e.write(`${JSON.stringify({
|
|
1101
1105
|
source: "codemem-mcp-oauth-audit",
|
|
@@ -1103,28 +1107,28 @@ function Ne(e = process.stderr) {
|
|
|
1103
1107
|
})}\n`);
|
|
1104
1108
|
};
|
|
1105
1109
|
}
|
|
1106
|
-
function
|
|
1110
|
+
function Ue() {
|
|
1107
1111
|
return () => {};
|
|
1108
1112
|
}
|
|
1109
|
-
function
|
|
1113
|
+
function We(e = process.env.CODEMEM_MCP_AUDIT) {
|
|
1110
1114
|
let t = e?.trim().toLowerCase();
|
|
1111
|
-
return t === "0" || t === "false" || t === "no" ?
|
|
1115
|
+
return t === "0" || t === "false" || t === "no" ? Ue() : He();
|
|
1112
1116
|
}
|
|
1113
|
-
var
|
|
1117
|
+
var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github.com/kunickiaj/codemem#readme", Ke = "https://claude.ai/api/mcp/auth_callback", qe = new Set([
|
|
1114
1118
|
"localhost",
|
|
1115
1119
|
"127.0.0.1",
|
|
1116
1120
|
"::1"
|
|
1117
|
-
]),
|
|
1121
|
+
]), Je = new Set(["authorization_code", "refresh_token"]), Ye = new Set(["code"]), B = 3600, V = 720 * 60 * 60, Xe = 100, Ze = 100, Qe = 100, $e = 32, et = 43, tt = /^[A-Za-z0-9_-]{43}$/, nt = /^[A-Za-z0-9_-]{43}$/, rt = class {
|
|
1118
1122
|
#e = /* @__PURE__ */ new Map();
|
|
1119
1123
|
getClient(e) {
|
|
1120
1124
|
return this.#e.get(e);
|
|
1121
1125
|
}
|
|
1122
1126
|
registerClient(e) {
|
|
1123
|
-
let t =
|
|
1124
|
-
if (t) throw new
|
|
1125
|
-
if (e.client_secret || e.token_endpoint_auth_method !== "none") throw new
|
|
1126
|
-
if (e.grant_types && !
|
|
1127
|
-
if (e.response_types && !
|
|
1127
|
+
let t = yt(e.redirect_uris);
|
|
1128
|
+
if (t) throw new O(t);
|
|
1129
|
+
if (e.client_secret || e.token_endpoint_auth_method !== "none") throw new O("Only public clients with token_endpoint_auth_method=none are supported");
|
|
1130
|
+
if (e.grant_types && !H(e.grant_types, Je)) throw new O("Only authorization_code and refresh_token grant_types are supported");
|
|
1131
|
+
if (e.response_types && !H(e.response_types, Ye)) throw new O("Only code response_type is supported");
|
|
1128
1132
|
if (this.#e.size >= 100) {
|
|
1129
1133
|
let e = this.#e.keys().next().value;
|
|
1130
1134
|
e && this.#e.delete(e);
|
|
@@ -1139,10 +1143,10 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1139
1143
|
};
|
|
1140
1144
|
return this.#e.set(n.client_id, n), n;
|
|
1141
1145
|
}
|
|
1142
|
-
},
|
|
1146
|
+
}, it = class {
|
|
1143
1147
|
#e = /* @__PURE__ */ new Map();
|
|
1144
1148
|
issueCode(e, t = Date.now()) {
|
|
1145
|
-
if (this.#t(t), this.#e.size >=
|
|
1149
|
+
if (this.#t(t), this.#e.size >= Xe) return;
|
|
1146
1150
|
let n = v();
|
|
1147
1151
|
return this.#e.set(n, {
|
|
1148
1152
|
...e,
|
|
@@ -1160,12 +1164,12 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1160
1164
|
#t(e) {
|
|
1161
1165
|
for (let [t, n] of this.#e) n.expiresAt <= e && this.#e.delete(t);
|
|
1162
1166
|
}
|
|
1163
|
-
},
|
|
1167
|
+
}, at = class {
|
|
1164
1168
|
#e = /* @__PURE__ */ new Map();
|
|
1165
1169
|
#t = _(32);
|
|
1166
1170
|
issueToken(e, t = Date.now(), n, r, i = []) {
|
|
1167
|
-
if (this.#n(t), this.#e.size >=
|
|
1168
|
-
let a = _(
|
|
1171
|
+
if (this.#n(t), this.#e.size >= Ze) return;
|
|
1172
|
+
let a = _($e), o = Tt(a, this.#t);
|
|
1169
1173
|
return this.#e.set(o, {
|
|
1170
1174
|
clientId: e,
|
|
1171
1175
|
grantId: r,
|
|
@@ -1173,22 +1177,22 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1173
1177
|
resource: n,
|
|
1174
1178
|
tokenHash: o,
|
|
1175
1179
|
issuedAt: t,
|
|
1176
|
-
expiresAt: t +
|
|
1180
|
+
expiresAt: t + B * 1e3,
|
|
1177
1181
|
lastUsedAt: null,
|
|
1178
1182
|
revokedAt: null
|
|
1179
1183
|
}), {
|
|
1180
1184
|
token: a.toString("base64url"),
|
|
1181
|
-
expiresIn:
|
|
1185
|
+
expiresIn: B
|
|
1182
1186
|
};
|
|
1183
1187
|
}
|
|
1184
1188
|
verifyToken(e, t = Date.now()) {
|
|
1185
|
-
let n =
|
|
1189
|
+
let n = W(e);
|
|
1186
1190
|
if (!n) return {
|
|
1187
1191
|
ok: !1,
|
|
1188
1192
|
reason: "unknown_token"
|
|
1189
1193
|
};
|
|
1190
|
-
let r =
|
|
1191
|
-
return !i || !
|
|
1194
|
+
let r = Tt(n, this.#t), i = this.#e.get(r);
|
|
1195
|
+
return !i || !J(i.tokenHash, r) ? {
|
|
1192
1196
|
ok: !1,
|
|
1193
1197
|
reason: "unknown_token"
|
|
1194
1198
|
} : i.revokedAt === null ? i.expiresAt <= t ? {
|
|
@@ -1203,10 +1207,10 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1203
1207
|
};
|
|
1204
1208
|
}
|
|
1205
1209
|
revokeToken(e, t = Date.now()) {
|
|
1206
|
-
let n =
|
|
1210
|
+
let n = W(e);
|
|
1207
1211
|
if (!n) return !1;
|
|
1208
|
-
let r =
|
|
1209
|
-
return !i || !
|
|
1212
|
+
let r = Tt(n, this.#t), i = this.#e.get(r);
|
|
1213
|
+
return !i || !J(i.tokenHash, r) ? !1 : (i.revokedAt === null && (i.revokedAt = t), !0);
|
|
1210
1214
|
}
|
|
1211
1215
|
revokeTokensForGrant(e, t = Date.now()) {
|
|
1212
1216
|
let n = 0;
|
|
@@ -1216,14 +1220,14 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1216
1220
|
#n(e) {
|
|
1217
1221
|
for (let [t, n] of this.#e) (n.expiresAt <= e || n.revokedAt !== null) && this.#e.delete(t);
|
|
1218
1222
|
}
|
|
1219
|
-
},
|
|
1223
|
+
}, ot = class {
|
|
1220
1224
|
#e = /* @__PURE__ */ new Map();
|
|
1221
1225
|
#t = /* @__PURE__ */ new Map();
|
|
1222
1226
|
#n = /* @__PURE__ */ new Map();
|
|
1223
1227
|
#r = _(32);
|
|
1224
1228
|
issueGrant(e, t = Date.now()) {
|
|
1225
|
-
if (this.#i(t), this.#e.size >=
|
|
1226
|
-
let n =
|
|
1229
|
+
if (this.#i(t), this.#e.size >= Qe) return;
|
|
1230
|
+
let n = G(), r = K(n, this.#r);
|
|
1227
1231
|
if (!r) return;
|
|
1228
1232
|
let i = {
|
|
1229
1233
|
grantId: v(),
|
|
@@ -1233,7 +1237,7 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1233
1237
|
currentRefreshTokenHash: r,
|
|
1234
1238
|
previousRefreshTokenHash: null,
|
|
1235
1239
|
issuedAt: t,
|
|
1236
|
-
expiresAt: t +
|
|
1240
|
+
expiresAt: t + V * 1e3,
|
|
1237
1241
|
rotatedAt: null,
|
|
1238
1242
|
revokedAt: null
|
|
1239
1243
|
};
|
|
@@ -1243,11 +1247,11 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1243
1247
|
scopes: [...i.scopes]
|
|
1244
1248
|
},
|
|
1245
1249
|
refreshToken: n,
|
|
1246
|
-
expiresIn:
|
|
1250
|
+
expiresIn: V
|
|
1247
1251
|
};
|
|
1248
1252
|
}
|
|
1249
1253
|
rotateRefreshToken(e, t, n = {}, r = Date.now()) {
|
|
1250
|
-
let i =
|
|
1254
|
+
let i = K(t, this.#r);
|
|
1251
1255
|
if (!i) return {
|
|
1252
1256
|
ok: !1,
|
|
1253
1257
|
reason: "unknown_refresh_token"
|
|
@@ -1277,7 +1281,7 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1277
1281
|
reason: "client_mismatch",
|
|
1278
1282
|
grantId: a
|
|
1279
1283
|
};
|
|
1280
|
-
if (!
|
|
1284
|
+
if (!Dt(n.scopes ?? o.scopes, o.scopes)) return {
|
|
1281
1285
|
ok: !1,
|
|
1282
1286
|
reason: "scope_mismatch",
|
|
1283
1287
|
grantId: a
|
|
@@ -1287,13 +1291,13 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1287
1291
|
reason: "resource_mismatch",
|
|
1288
1292
|
grantId: a
|
|
1289
1293
|
};
|
|
1290
|
-
let s =
|
|
1294
|
+
let s = J(o.currentRefreshTokenHash, i), c = o.previousRefreshTokenHash !== null && J(o.previousRefreshTokenHash, i);
|
|
1291
1295
|
if (!s && !c) return this.revokeGrant(a, r), {
|
|
1292
1296
|
ok: !1,
|
|
1293
1297
|
reason: "refresh_token_replay",
|
|
1294
1298
|
grantId: a
|
|
1295
1299
|
};
|
|
1296
|
-
let l =
|
|
1300
|
+
let l = G(), u = K(l, this.#r);
|
|
1297
1301
|
return u ? (o.scopes = [...n.scopes ?? o.scopes], o.previousRefreshTokenHash = s ? o.currentRefreshTokenHash : null, o.currentRefreshTokenHash = u, o.rotatedAt = r, this.#t.set(u, a), this.#n.get(a)?.add(u), {
|
|
1298
1302
|
ok: !0,
|
|
1299
1303
|
grant: {
|
|
@@ -1308,7 +1312,7 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1308
1312
|
};
|
|
1309
1313
|
}
|
|
1310
1314
|
revokeRefreshToken(e, t = Date.now()) {
|
|
1311
|
-
let n =
|
|
1315
|
+
let n = K(e, this.#r);
|
|
1312
1316
|
if (!n) return;
|
|
1313
1317
|
let r = this.#t.get(n);
|
|
1314
1318
|
if (r) return this.revokeGrant(r, t), r;
|
|
@@ -1329,24 +1333,279 @@ var Ie = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
|
|
|
1329
1333
|
}
|
|
1330
1334
|
this.#t.delete(e.currentRefreshTokenHash), e.previousRefreshTokenHash && this.#t.delete(e.previousRefreshTokenHash);
|
|
1331
1335
|
}
|
|
1336
|
+
}, st = class {
|
|
1337
|
+
#e;
|
|
1338
|
+
#t = /* @__PURE__ */ new Map();
|
|
1339
|
+
#n = /* @__PURE__ */ new Map();
|
|
1340
|
+
#r = /* @__PURE__ */ new Map();
|
|
1341
|
+
#i = /* @__PURE__ */ new Map();
|
|
1342
|
+
#a = /* @__PURE__ */ new Map();
|
|
1343
|
+
#o = /* @__PURE__ */ new Map();
|
|
1344
|
+
constructor(e = pt()) {
|
|
1345
|
+
this.#e = e, this.#s();
|
|
1346
|
+
}
|
|
1347
|
+
getClient(e) {
|
|
1348
|
+
return this.#n.get(e);
|
|
1349
|
+
}
|
|
1350
|
+
registerClient(e) {
|
|
1351
|
+
let t = yt(e.redirect_uris);
|
|
1352
|
+
if (t) throw new O(t);
|
|
1353
|
+
if (e.client_secret || e.token_endpoint_auth_method !== "none") throw new O("Only public clients with token_endpoint_auth_method=none are supported");
|
|
1354
|
+
if (e.grant_types && !H(e.grant_types, Je)) throw new O("Only authorization_code and refresh_token grant_types are supported");
|
|
1355
|
+
if (e.response_types && !H(e.response_types, Ye)) throw new O("Only code response_type is supported");
|
|
1356
|
+
if (this.#u(Date.now()), this.#n.size >= 100) {
|
|
1357
|
+
let e = this.#n.keys().next().value;
|
|
1358
|
+
e && this.#n.delete(e);
|
|
1359
|
+
}
|
|
1360
|
+
let n = {
|
|
1361
|
+
...e,
|
|
1362
|
+
token_endpoint_auth_method: "none",
|
|
1363
|
+
grant_types: e.grant_types ?? ["authorization_code", "refresh_token"],
|
|
1364
|
+
response_types: e.response_types ?? ["code"],
|
|
1365
|
+
client_id: v(),
|
|
1366
|
+
client_id_issued_at: Math.floor(Date.now() / 1e3)
|
|
1367
|
+
};
|
|
1368
|
+
return this.#n.set(n.client_id, n), this.#c(), n;
|
|
1369
|
+
}
|
|
1370
|
+
issueCode(e, t = Date.now()) {
|
|
1371
|
+
if (this.#l(t), this.#t.size >= Xe) return;
|
|
1372
|
+
let n = v();
|
|
1373
|
+
return this.#t.set(n, {
|
|
1374
|
+
...e,
|
|
1375
|
+
used: !1
|
|
1376
|
+
}), n;
|
|
1377
|
+
}
|
|
1378
|
+
peekCode(e) {
|
|
1379
|
+
let t = this.#t.get(e);
|
|
1380
|
+
if (!(!t || t.used)) return t;
|
|
1381
|
+
}
|
|
1382
|
+
consumeCode(e) {
|
|
1383
|
+
let t = this.#t.get(e);
|
|
1384
|
+
if (!(!t || t.used)) return t.used = !0, t;
|
|
1385
|
+
}
|
|
1386
|
+
issueToken(e, t = Date.now(), n, r, i = []) {
|
|
1387
|
+
if (this.#u(t), this.#r.size >= Ze) return;
|
|
1388
|
+
let a = G(), o = q(a);
|
|
1389
|
+
if (o) return this.#r.set(o, {
|
|
1390
|
+
clientId: e,
|
|
1391
|
+
grantId: r,
|
|
1392
|
+
scopes: [...i],
|
|
1393
|
+
resource: n,
|
|
1394
|
+
tokenHash: o,
|
|
1395
|
+
issuedAt: t,
|
|
1396
|
+
expiresAt: t + B * 1e3,
|
|
1397
|
+
lastUsedAt: null,
|
|
1398
|
+
revokedAt: null
|
|
1399
|
+
}), this.#c(), {
|
|
1400
|
+
token: a,
|
|
1401
|
+
expiresIn: B
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
verifyToken(e, t = Date.now()) {
|
|
1405
|
+
let n = q(e);
|
|
1406
|
+
if (!n) return {
|
|
1407
|
+
ok: !1,
|
|
1408
|
+
reason: "unknown_token"
|
|
1409
|
+
};
|
|
1410
|
+
let r = this.#r.get(n);
|
|
1411
|
+
return !r || !J(r.tokenHash, n) ? {
|
|
1412
|
+
ok: !1,
|
|
1413
|
+
reason: "unknown_token"
|
|
1414
|
+
} : r.revokedAt === null ? r.expiresAt <= t ? {
|
|
1415
|
+
ok: !1,
|
|
1416
|
+
reason: "expired_token"
|
|
1417
|
+
} : (r.lastUsedAt = t, {
|
|
1418
|
+
ok: !0,
|
|
1419
|
+
record: {
|
|
1420
|
+
...r,
|
|
1421
|
+
scopes: [...r.scopes]
|
|
1422
|
+
}
|
|
1423
|
+
}) : {
|
|
1424
|
+
ok: !1,
|
|
1425
|
+
reason: "revoked_token"
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
revokeToken(e, t = Date.now()) {
|
|
1429
|
+
let n = q(e);
|
|
1430
|
+
if (!n) return !1;
|
|
1431
|
+
let r = this.#r.get(n);
|
|
1432
|
+
return !r || !J(r.tokenHash, n) ? !1 : r.revokedAt === null ? (r.revokedAt = t, this.#c(), !0) : !0;
|
|
1433
|
+
}
|
|
1434
|
+
revokeTokensForGrant(e, t = Date.now()) {
|
|
1435
|
+
let n = 0;
|
|
1436
|
+
for (let r of this.#r.values()) r.grantId !== e || r.revokedAt !== null || (r.revokedAt = t, n += 1);
|
|
1437
|
+
return n > 0 && this.#c(), n;
|
|
1438
|
+
}
|
|
1439
|
+
issueGrant(e, t = Date.now()) {
|
|
1440
|
+
if (this.#u(t), this.#i.size >= Qe) return;
|
|
1441
|
+
let n = G(), r = q(n);
|
|
1442
|
+
if (!r) return;
|
|
1443
|
+
let i = {
|
|
1444
|
+
grantId: v(),
|
|
1445
|
+
clientId: e.clientId,
|
|
1446
|
+
scopes: [...e.scopes ?? []],
|
|
1447
|
+
resource: e.resource,
|
|
1448
|
+
currentRefreshTokenHash: r,
|
|
1449
|
+
previousRefreshTokenHash: null,
|
|
1450
|
+
issuedAt: t,
|
|
1451
|
+
expiresAt: t + V * 1e3,
|
|
1452
|
+
rotatedAt: null,
|
|
1453
|
+
revokedAt: null
|
|
1454
|
+
};
|
|
1455
|
+
return this.#i.set(i.grantId, i), this.#a.set(r, i.grantId), this.#o.set(i.grantId, new Set([r])), this.#c(), {
|
|
1456
|
+
grant: {
|
|
1457
|
+
...i,
|
|
1458
|
+
scopes: [...i.scopes]
|
|
1459
|
+
},
|
|
1460
|
+
refreshToken: n,
|
|
1461
|
+
expiresIn: V
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
rotateRefreshToken(e, t, n = {}, r = Date.now()) {
|
|
1465
|
+
let i = q(t);
|
|
1466
|
+
if (!i) return {
|
|
1467
|
+
ok: !1,
|
|
1468
|
+
reason: "unknown_refresh_token"
|
|
1469
|
+
};
|
|
1470
|
+
let a = this.#a.get(i);
|
|
1471
|
+
if (!a) return {
|
|
1472
|
+
ok: !1,
|
|
1473
|
+
reason: "unknown_refresh_token"
|
|
1474
|
+
};
|
|
1475
|
+
let o = this.#i.get(a);
|
|
1476
|
+
if (!o) return {
|
|
1477
|
+
ok: !1,
|
|
1478
|
+
reason: "unknown_refresh_token"
|
|
1479
|
+
};
|
|
1480
|
+
if (o.revokedAt !== null) return {
|
|
1481
|
+
ok: !1,
|
|
1482
|
+
reason: "revoked_refresh_token",
|
|
1483
|
+
grantId: a
|
|
1484
|
+
};
|
|
1485
|
+
if (o.expiresAt <= r) return this.revokeGrant(a, r), {
|
|
1486
|
+
ok: !1,
|
|
1487
|
+
reason: "expired_refresh_token",
|
|
1488
|
+
grantId: a
|
|
1489
|
+
};
|
|
1490
|
+
if (o.clientId !== e) return {
|
|
1491
|
+
ok: !1,
|
|
1492
|
+
reason: "client_mismatch",
|
|
1493
|
+
grantId: a
|
|
1494
|
+
};
|
|
1495
|
+
if (!Dt(n.scopes ?? o.scopes, o.scopes)) return {
|
|
1496
|
+
ok: !1,
|
|
1497
|
+
reason: "scope_mismatch",
|
|
1498
|
+
grantId: a
|
|
1499
|
+
};
|
|
1500
|
+
if ((o.resource ?? null) !== (n.resource ?? o.resource ?? null)) return {
|
|
1501
|
+
ok: !1,
|
|
1502
|
+
reason: "resource_mismatch",
|
|
1503
|
+
grantId: a
|
|
1504
|
+
};
|
|
1505
|
+
let s = J(o.currentRefreshTokenHash, i), c = o.previousRefreshTokenHash !== null && J(o.previousRefreshTokenHash, i);
|
|
1506
|
+
if (!s && !c) return this.revokeGrant(a, r), {
|
|
1507
|
+
ok: !1,
|
|
1508
|
+
reason: "refresh_token_replay",
|
|
1509
|
+
grantId: a
|
|
1510
|
+
};
|
|
1511
|
+
let l = G(), u = q(l);
|
|
1512
|
+
return u ? (o.scopes = [...n.scopes ?? o.scopes], o.previousRefreshTokenHash = s ? o.currentRefreshTokenHash : null, o.currentRefreshTokenHash = u, o.rotatedAt = r, this.#a.set(u, a), this.#o.get(a)?.add(u), this.#c(), {
|
|
1513
|
+
ok: !0,
|
|
1514
|
+
grant: {
|
|
1515
|
+
...o,
|
|
1516
|
+
scopes: [...o.scopes]
|
|
1517
|
+
},
|
|
1518
|
+
refreshToken: l,
|
|
1519
|
+
expiresIn: Math.max(0, Math.floor((o.expiresAt - r) / 1e3))
|
|
1520
|
+
}) : {
|
|
1521
|
+
ok: !1,
|
|
1522
|
+
reason: "unknown_refresh_token"
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
revokeRefreshToken(e, t = Date.now()) {
|
|
1526
|
+
let n = q(e);
|
|
1527
|
+
if (!n) return;
|
|
1528
|
+
let r = this.#a.get(n);
|
|
1529
|
+
if (r) return this.revokeGrant(r, t), r;
|
|
1530
|
+
}
|
|
1531
|
+
revokeGrant(e, t = Date.now()) {
|
|
1532
|
+
let n = this.#i.get(e);
|
|
1533
|
+
return n ? n.revokedAt === null ? (n.revokedAt = t, this.#d(n), this.#c(), !0) : !0 : !1;
|
|
1534
|
+
}
|
|
1535
|
+
#s() {
|
|
1536
|
+
if (!ee(this.#e)) return;
|
|
1537
|
+
let e;
|
|
1538
|
+
try {
|
|
1539
|
+
e = JSON.parse(S(this.#e, "utf8"));
|
|
1540
|
+
} catch {
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
if (e.version === 1) {
|
|
1544
|
+
this.#n = new Map(e.clients.map((e) => [e.client_id, e])), this.#r = new Map(e.accessTokens.map((e) => [e.tokenHash, e])), this.#i = new Map(e.refreshGrants.map((e) => [e.grantId, e])), this.#a = /* @__PURE__ */ new Map(), this.#o = /* @__PURE__ */ new Map();
|
|
1545
|
+
for (let t of this.#i.values()) {
|
|
1546
|
+
let n = new Set(e.refreshHashesByGrantId[t.grantId] ?? []);
|
|
1547
|
+
n.add(t.currentRefreshTokenHash), t.previousRefreshTokenHash && n.add(t.previousRefreshTokenHash), this.#o.set(t.grantId, n);
|
|
1548
|
+
for (let e of n) this.#a.set(e, t.grantId);
|
|
1549
|
+
}
|
|
1550
|
+
this.#u(Date.now());
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
#c() {
|
|
1554
|
+
x(E(this.#e), {
|
|
1555
|
+
recursive: !0,
|
|
1556
|
+
mode: 448
|
|
1557
|
+
});
|
|
1558
|
+
let e = {
|
|
1559
|
+
version: 1,
|
|
1560
|
+
clients: [...this.#n.values()],
|
|
1561
|
+
accessTokens: [...this.#r.values()],
|
|
1562
|
+
refreshGrants: [...this.#i.values()],
|
|
1563
|
+
refreshHashesByGrantId: Object.fromEntries([...this.#o.entries()].map(([e, t]) => [e, [...t]]))
|
|
1564
|
+
}, t = `${this.#e}.${process.pid}.${Date.now()}.tmp`;
|
|
1565
|
+
C(t, `${JSON.stringify(e, null, 2)}\n`, { mode: 384 }), te(t, this.#e), w(this.#e, 384).catch(() => void 0);
|
|
1566
|
+
}
|
|
1567
|
+
#l(e) {
|
|
1568
|
+
for (let [t, n] of this.#t) n.expiresAt <= e && this.#t.delete(t);
|
|
1569
|
+
}
|
|
1570
|
+
#u(e) {
|
|
1571
|
+
let t = !1;
|
|
1572
|
+
for (let [n, r] of this.#r) r.expiresAt > e && r.revokedAt === null || (this.#r.delete(n), t = !0);
|
|
1573
|
+
for (let [n, r] of this.#i) r.expiresAt > e && r.revokedAt === null || (this.#i.delete(n), this.#d(r), t = !0);
|
|
1574
|
+
t && this.#c();
|
|
1575
|
+
}
|
|
1576
|
+
#d(e) {
|
|
1577
|
+
let t = this.#o.get(e.grantId);
|
|
1578
|
+
if (t) {
|
|
1579
|
+
for (let e of t) this.#a.delete(e);
|
|
1580
|
+
this.#o.delete(e.grantId);
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
this.#a.delete(e.currentRefreshTokenHash), e.previousRefreshTokenHash && this.#a.delete(e.previousRefreshTokenHash);
|
|
1584
|
+
}
|
|
1332
1585
|
};
|
|
1333
|
-
function
|
|
1334
|
-
return new
|
|
1586
|
+
function ct() {
|
|
1587
|
+
return new rt();
|
|
1335
1588
|
}
|
|
1336
|
-
function
|
|
1337
|
-
return new
|
|
1589
|
+
function lt() {
|
|
1590
|
+
return new it();
|
|
1338
1591
|
}
|
|
1339
|
-
function
|
|
1340
|
-
return new
|
|
1592
|
+
function ut() {
|
|
1593
|
+
return new at();
|
|
1594
|
+
}
|
|
1595
|
+
function dt() {
|
|
1596
|
+
return new ot();
|
|
1597
|
+
}
|
|
1598
|
+
function ft(e) {
|
|
1599
|
+
return new st(e);
|
|
1341
1600
|
}
|
|
1342
|
-
function
|
|
1343
|
-
return
|
|
1601
|
+
function pt() {
|
|
1602
|
+
return D(process.env.HOME?.trim() || T(), ".codemem", "mcp-oauth-state.json");
|
|
1344
1603
|
}
|
|
1345
|
-
function
|
|
1346
|
-
let t =
|
|
1604
|
+
function mt(e) {
|
|
1605
|
+
let t = vt(_t(e.mcpUrl));
|
|
1347
1606
|
return {
|
|
1348
1607
|
...c({
|
|
1349
|
-
provider:
|
|
1608
|
+
provider: Ot(e.clientsStore),
|
|
1350
1609
|
issuerUrl: t,
|
|
1351
1610
|
baseUrl: t
|
|
1352
1611
|
}),
|
|
@@ -1359,23 +1618,23 @@ function rt(e) {
|
|
|
1359
1618
|
client_id_metadata_document_supported: !1
|
|
1360
1619
|
};
|
|
1361
1620
|
}
|
|
1362
|
-
function
|
|
1363
|
-
let t =
|
|
1621
|
+
function ht(e) {
|
|
1622
|
+
let t = _t(e), n = {
|
|
1364
1623
|
resource: t.href,
|
|
1365
|
-
authorization_servers: [
|
|
1624
|
+
authorization_servers: [vt(t).href],
|
|
1366
1625
|
scopes_supported: R,
|
|
1367
1626
|
bearer_methods_supported: ["header"],
|
|
1368
|
-
resource_name:
|
|
1627
|
+
resource_name: Ge,
|
|
1369
1628
|
resource_documentation: z
|
|
1370
1629
|
};
|
|
1371
|
-
return
|
|
1372
|
-
}
|
|
1373
|
-
function
|
|
1374
|
-
let n = e.get("client_id") ?? "", r = e.get("redirect_uri") ?? "", i = e.get("response_type") ?? "", a = e.get("code_challenge") ?? "", o = e.get("code_challenge_method") ?? "", s = e.get("resource"), c =
|
|
1375
|
-
if (i !== "code") return
|
|
1376
|
-
if (o !== "S256") return
|
|
1377
|
-
if (!
|
|
1378
|
-
let u =
|
|
1630
|
+
return ce.parse(n);
|
|
1631
|
+
}
|
|
1632
|
+
function gt(e, t) {
|
|
1633
|
+
let n = e.get("client_id") ?? "", r = e.get("redirect_uri") ?? "", i = e.get("response_type") ?? "", a = e.get("code_challenge") ?? "", o = e.get("code_challenge_method") ?? "", s = e.get("resource"), c = Ct(e.get("scope")), l = e.get("state");
|
|
1634
|
+
if (i !== "code") return U("unsupported_response_type");
|
|
1635
|
+
if (o !== "S256") return U("invalid_request", "PKCE code_challenge_method=S256 is required");
|
|
1636
|
+
if (!nt.test(a)) return U("invalid_request", "Valid PKCE S256 code_challenge is required");
|
|
1637
|
+
let u = wt(t, n);
|
|
1379
1638
|
return u ? u.redirect_uris.includes(r) ? {
|
|
1380
1639
|
clientId: n,
|
|
1381
1640
|
redirectUri: r,
|
|
@@ -1383,48 +1642,48 @@ function at(e, t) {
|
|
|
1383
1642
|
scopes: c,
|
|
1384
1643
|
resource: s,
|
|
1385
1644
|
state: l
|
|
1386
|
-
} :
|
|
1645
|
+
} : U("invalid_request", "redirect_uri is not registered for this client") : U("invalid_client", "Unknown OAuth client_id");
|
|
1387
1646
|
}
|
|
1388
|
-
function
|
|
1647
|
+
function _t(e) {
|
|
1389
1648
|
let t;
|
|
1390
1649
|
try {
|
|
1391
1650
|
t = new URL(e);
|
|
1392
1651
|
} catch {
|
|
1393
1652
|
throw Error("Invalid MCP HTTP public URL; expected an HTTPS /mcp URL");
|
|
1394
1653
|
}
|
|
1395
|
-
if (t.protocol !== "https:" && !
|
|
1654
|
+
if (t.protocol !== "https:" && !xt(t)) throw Error("Invalid MCP HTTP public URL; use HTTPS for non-loopback URLs");
|
|
1396
1655
|
if (t.username || t.password || t.search || t.hash) throw Error("Invalid MCP HTTP public URL; credentials, query strings, and fragments are not allowed");
|
|
1397
1656
|
if (t.pathname === "/" && (t.pathname = "/mcp"), t.pathname !== "/mcp") throw Error("Invalid MCP HTTP public URL; expected /mcp path");
|
|
1398
1657
|
return t;
|
|
1399
1658
|
}
|
|
1400
|
-
function
|
|
1659
|
+
function vt(e) {
|
|
1401
1660
|
return new URL(e.origin);
|
|
1402
1661
|
}
|
|
1403
|
-
function
|
|
1662
|
+
function yt(e) {
|
|
1404
1663
|
for (let t of e) {
|
|
1405
1664
|
let e = new URL(t);
|
|
1406
1665
|
if (e.username || e.password || e.hash) return `Invalid redirect URI: ${t}`;
|
|
1407
|
-
if (e.href !==
|
|
1666
|
+
if (e.href !== Ke && !bt(e)) return `Unsupported redirect URI: ${t}`;
|
|
1408
1667
|
}
|
|
1409
1668
|
return null;
|
|
1410
1669
|
}
|
|
1411
|
-
function
|
|
1670
|
+
function H(e, t) {
|
|
1412
1671
|
return e.length > 0 && e.every((e) => t.has(e));
|
|
1413
1672
|
}
|
|
1414
|
-
function
|
|
1415
|
-
return e.protocol === "http:" &&
|
|
1673
|
+
function bt(e) {
|
|
1674
|
+
return e.protocol === "http:" && qe.has(St(e.hostname)) && e.pathname === "/callback" && e.search === "";
|
|
1416
1675
|
}
|
|
1417
|
-
function
|
|
1418
|
-
let t =
|
|
1419
|
-
return e.protocol === "http:" &&
|
|
1676
|
+
function xt(e) {
|
|
1677
|
+
let t = St(e.hostname);
|
|
1678
|
+
return e.protocol === "http:" && qe.has(t);
|
|
1420
1679
|
}
|
|
1421
|
-
function
|
|
1680
|
+
function St(e) {
|
|
1422
1681
|
return e.replace(/^\[(.*)]$/, "$1").toLowerCase();
|
|
1423
1682
|
}
|
|
1424
|
-
function
|
|
1683
|
+
function Ct(e) {
|
|
1425
1684
|
return e?.split(/\s+/).map((e) => e.trim()).filter(Boolean) ?? [];
|
|
1426
1685
|
}
|
|
1427
|
-
function
|
|
1686
|
+
function U(e, t) {
|
|
1428
1687
|
return {
|
|
1429
1688
|
status: 400,
|
|
1430
1689
|
body: t ? {
|
|
@@ -1433,38 +1692,42 @@ function H(e, t) {
|
|
|
1433
1692
|
} : { error: e }
|
|
1434
1693
|
};
|
|
1435
1694
|
}
|
|
1436
|
-
function
|
|
1695
|
+
function wt(e, t) {
|
|
1437
1696
|
let n = e.getClient(t);
|
|
1438
1697
|
if (n instanceof Promise) throw Error("Asynchronous OAuth client stores are not supported by this HTTP bootstrap yet");
|
|
1439
1698
|
return n;
|
|
1440
1699
|
}
|
|
1441
|
-
function
|
|
1442
|
-
if (typeof e != "string" || e.length !==
|
|
1700
|
+
function W(e) {
|
|
1701
|
+
if (typeof e != "string" || e.length !== et || !tt.test(e)) return null;
|
|
1443
1702
|
let t = Buffer.from(e, "base64url");
|
|
1444
|
-
return t.length ===
|
|
1703
|
+
return t.length === $e ? t : null;
|
|
1445
1704
|
}
|
|
1446
|
-
function
|
|
1447
|
-
return _(
|
|
1705
|
+
function G() {
|
|
1706
|
+
return _($e).toString("base64url");
|
|
1448
1707
|
}
|
|
1449
|
-
function
|
|
1450
|
-
let n =
|
|
1451
|
-
return n ?
|
|
1708
|
+
function K(e, t) {
|
|
1709
|
+
let n = W(e);
|
|
1710
|
+
return n ? Et(n, t) : null;
|
|
1711
|
+
}
|
|
1712
|
+
function q(e) {
|
|
1713
|
+
let t = W(e);
|
|
1714
|
+
return t ? m("sha256").update(t).digest("base64url") : null;
|
|
1452
1715
|
}
|
|
1453
|
-
function
|
|
1454
|
-
return
|
|
1716
|
+
function Tt(e, t) {
|
|
1717
|
+
return Et(e, t);
|
|
1455
1718
|
}
|
|
1456
|
-
function
|
|
1719
|
+
function Et(e, t) {
|
|
1457
1720
|
return h("sha256", t).update(e).digest("base64url");
|
|
1458
1721
|
}
|
|
1459
|
-
function
|
|
1722
|
+
function J(e, t) {
|
|
1460
1723
|
let n = Buffer.from(e), r = Buffer.from(t);
|
|
1461
1724
|
return n.length === r.length && y(n, r);
|
|
1462
1725
|
}
|
|
1463
|
-
function
|
|
1726
|
+
function Dt(e, t) {
|
|
1464
1727
|
let n = new Set(t);
|
|
1465
1728
|
return e.every((e) => n.has(e));
|
|
1466
1729
|
}
|
|
1467
|
-
function
|
|
1730
|
+
function Ot(e) {
|
|
1468
1731
|
return {
|
|
1469
1732
|
clientsStore: e,
|
|
1470
1733
|
async authorize() {
|
|
@@ -1486,14 +1749,14 @@ function _t(e) {
|
|
|
1486
1749
|
}
|
|
1487
1750
|
//#endregion
|
|
1488
1751
|
//#region src/oidc.ts
|
|
1489
|
-
var
|
|
1752
|
+
var kt = "CODEMEM_MCP_OIDC_ISSUER_URL", At = "CODEMEM_MCP_OIDC_CLIENT_ID", jt = "CODEMEM_MCP_OIDC_CLIENT_SECRET", Mt = "CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT", Nt = "CODEMEM_MCP_OAUTH_ALLOWED_EMAIL", Pt = 300 * 1e3, Ft = 100, It = 300 * 1e3, Lt = class {
|
|
1490
1753
|
#e = /* @__PURE__ */ new Map();
|
|
1491
1754
|
issue(e, t = Date.now()) {
|
|
1492
|
-
if (this.#t(t), this.#e.size >=
|
|
1755
|
+
if (this.#t(t), this.#e.size >= Ft) return;
|
|
1493
1756
|
let n = v();
|
|
1494
1757
|
return this.#e.set(n, {
|
|
1495
1758
|
...e,
|
|
1496
|
-
expiresAt: t +
|
|
1759
|
+
expiresAt: t + Pt
|
|
1497
1760
|
}), n;
|
|
1498
1761
|
}
|
|
1499
1762
|
consume(e) {
|
|
@@ -1504,14 +1767,14 @@ var vt = "CODEMEM_MCP_OIDC_ISSUER_URL", yt = "CODEMEM_MCP_OIDC_CLIENT_ID", bt =
|
|
|
1504
1767
|
for (let [t, n] of this.#e) n.expiresAt <= e && this.#e.delete(t);
|
|
1505
1768
|
}
|
|
1506
1769
|
};
|
|
1507
|
-
function
|
|
1508
|
-
return new
|
|
1770
|
+
function Rt() {
|
|
1771
|
+
return new Lt();
|
|
1509
1772
|
}
|
|
1510
|
-
function
|
|
1511
|
-
let t = e[
|
|
1773
|
+
function zt(e = process.env) {
|
|
1774
|
+
let t = e[kt]?.trim(), n = e[At]?.trim(), r = e[jt]?.trim(), i = e[Mt]?.trim(), a = e[Nt]?.trim().toLowerCase();
|
|
1512
1775
|
if (!(!t && !n && !r && !i && !a)) {
|
|
1513
1776
|
if (!t || !n || !r) throw Error("Incomplete MCP OIDC configuration");
|
|
1514
|
-
if (
|
|
1777
|
+
if (Y(t, "issuer", { allowLoopbackHttp: !0 }), !i && !a) throw Error("MCP OIDC requires CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT or CODEMEM_MCP_OAUTH_ALLOWED_EMAIL");
|
|
1515
1778
|
return {
|
|
1516
1779
|
issuerUrl: t,
|
|
1517
1780
|
clientId: n,
|
|
@@ -1521,39 +1784,39 @@ function Ot(e = process.env) {
|
|
|
1521
1784
|
};
|
|
1522
1785
|
}
|
|
1523
1786
|
}
|
|
1524
|
-
async function
|
|
1525
|
-
if (!r) return
|
|
1526
|
-
let o =
|
|
1787
|
+
async function Bt(e, t, n, r, i, a = Date.now()) {
|
|
1788
|
+
if (!r) return X("temporarily_unavailable", "OIDC is not configured");
|
|
1789
|
+
let o = gt(e, t);
|
|
1527
1790
|
if ("status" in o) return o;
|
|
1528
|
-
let s = await
|
|
1791
|
+
let s = await Ut(r.issuerUrl), c = v(), l = n.issue({
|
|
1529
1792
|
oauthParams: e.toString(),
|
|
1530
1793
|
nonce: c
|
|
1531
1794
|
}, a);
|
|
1532
|
-
if (!l) return
|
|
1533
|
-
let u =
|
|
1795
|
+
if (!l) return X("temporarily_unavailable", "Too many pending OIDC authorizations");
|
|
1796
|
+
let u = Ht(i), d = new URL(s.authorization_endpoint);
|
|
1534
1797
|
return d.searchParams.set("response_type", "code"), d.searchParams.set("client_id", r.clientId), d.searchParams.set("redirect_uri", u), d.searchParams.set("scope", "openid email"), d.searchParams.set("state", l), d.searchParams.set("nonce", c), {
|
|
1535
1798
|
status: 302,
|
|
1536
1799
|
location: d.href
|
|
1537
1800
|
};
|
|
1538
1801
|
}
|
|
1539
|
-
async function
|
|
1802
|
+
async function Vt(e, t, n, r, i = Date.now()) {
|
|
1540
1803
|
try {
|
|
1541
1804
|
let a = e.get("code") ?? "", o = e.get("state") ?? "";
|
|
1542
|
-
if (!o) return
|
|
1805
|
+
if (!o) return X("invalid_request", "Missing OIDC state");
|
|
1543
1806
|
let s = t.consume(o);
|
|
1544
|
-
if (!s || s.expiresAt <= i) return
|
|
1545
|
-
if (!a) return
|
|
1546
|
-
let c = await
|
|
1547
|
-
return l.id_token ?
|
|
1807
|
+
if (!s || s.expiresAt <= i) return X("invalid_request", "Expired or unknown OIDC state");
|
|
1808
|
+
if (!a) return X("invalid_request", "Missing OIDC code");
|
|
1809
|
+
let c = await Ut(n.issuerUrl), l = await Wt(c.token_endpoint, n, Ht(r), a);
|
|
1810
|
+
return l.id_token ? Yt(await Gt(l.id_token, c, n.clientId, s.nonce, i), n) ? { oauthParams: new URLSearchParams(s.oauthParams) } : X("access_denied", "OIDC identity is not allowed") : X("invalid_request", "OIDC token exchange failed");
|
|
1548
1811
|
} catch {
|
|
1549
|
-
return
|
|
1812
|
+
return X("access_denied", "OIDC identity verification failed");
|
|
1550
1813
|
}
|
|
1551
1814
|
}
|
|
1552
|
-
function
|
|
1815
|
+
function Ht(e) {
|
|
1553
1816
|
let t = new URL(e);
|
|
1554
1817
|
return new URL("/oauth/callback", t.origin).href;
|
|
1555
1818
|
}
|
|
1556
|
-
async function
|
|
1819
|
+
async function Ut(e) {
|
|
1557
1820
|
let t = new URL(e);
|
|
1558
1821
|
if (t.search || t.hash) throw Error("OIDC issuer must not include query or fragment");
|
|
1559
1822
|
if (t.username || t.password) throw Error("OIDC issuer must not include credentials");
|
|
@@ -1562,10 +1825,10 @@ async function Mt(e) {
|
|
|
1562
1825
|
let i = await r.json();
|
|
1563
1826
|
if (i.issuer !== t.href && i.issuer !== t.href.replace(/\/$/, "")) throw Error("OIDC discovery issuer mismatch");
|
|
1564
1827
|
if (!i.authorization_endpoint || !i.token_endpoint || !i.jwks_uri) throw Error("OIDC discovery metadata is incomplete");
|
|
1565
|
-
let a = t.protocol === "http:" &&
|
|
1566
|
-
return
|
|
1828
|
+
let a = t.protocol === "http:" && Xt(t.hostname);
|
|
1829
|
+
return Y(i.authorization_endpoint, "authorization endpoint", { allowLoopbackHttp: a }), Y(i.token_endpoint, "token endpoint", { allowLoopbackHttp: a }), Y(i.jwks_uri, "JWKS URI", { allowLoopbackHttp: a }), i;
|
|
1567
1830
|
}
|
|
1568
|
-
async function
|
|
1831
|
+
async function Wt(e, t, n, r) {
|
|
1569
1832
|
let i = new URLSearchParams({
|
|
1570
1833
|
grant_type: "authorization_code",
|
|
1571
1834
|
code: r,
|
|
@@ -1580,17 +1843,17 @@ async function Nt(e, t, n, r) {
|
|
|
1580
1843
|
if (!a.ok) throw Error("OIDC token request failed");
|
|
1581
1844
|
return await a.json();
|
|
1582
1845
|
}
|
|
1583
|
-
async function
|
|
1846
|
+
async function Gt(e, t, n, r, i) {
|
|
1584
1847
|
let [a, o, s] = e.split(".");
|
|
1585
1848
|
if (!a || !o || !s) throw Error("Invalid OIDC id_token");
|
|
1586
|
-
let c =
|
|
1849
|
+
let c = Kt(a), l = Kt(o);
|
|
1587
1850
|
if (c.alg !== "RS256" || !c.kid) throw Error("Unsupported OIDC id_token signature");
|
|
1588
1851
|
if (l.iss !== t.issuer) throw Error("OIDC id_token issuer mismatch");
|
|
1589
|
-
if (!
|
|
1590
|
-
if (!
|
|
1852
|
+
if (!qt(l.aud, n)) throw Error("OIDC id_token audience mismatch");
|
|
1853
|
+
if (!Jt(l.aud, l.azp, n)) throw Error("OIDC id_token authorized party mismatch");
|
|
1591
1854
|
if (typeof l.exp != "number" || !Number.isFinite(l.exp) || l.exp * 1e3 <= i) throw Error("OIDC id_token is expired");
|
|
1592
1855
|
if (typeof l.iat != "number" || !Number.isFinite(l.iat)) throw Error("OIDC id_token issued-at time is missing");
|
|
1593
|
-
if (l.iat * 1e3 > i +
|
|
1856
|
+
if (l.iat * 1e3 > i + It) throw Error("OIDC id_token issued-at time is in the future");
|
|
1594
1857
|
if (l.nonce !== r) throw Error("OIDC id_token nonce mismatch");
|
|
1595
1858
|
if (!l.sub) throw Error("OIDC id_token subject is missing");
|
|
1596
1859
|
let u = await fetch(t.jwks_uri);
|
|
@@ -1604,28 +1867,28 @@ async function Pt(e, t, n, r, i) {
|
|
|
1604
1867
|
if (!b("RSA-SHA256", Buffer.from(p), f, Buffer.from(s, "base64url"))) throw Error("OIDC id_token signature verification failed");
|
|
1605
1868
|
return l;
|
|
1606
1869
|
}
|
|
1607
|
-
function
|
|
1870
|
+
function Kt(e) {
|
|
1608
1871
|
return JSON.parse(Buffer.from(e, "base64url").toString("utf8"));
|
|
1609
1872
|
}
|
|
1610
|
-
function
|
|
1873
|
+
function qt(e, t) {
|
|
1611
1874
|
return Array.isArray(e) ? e.includes(t) : e === t;
|
|
1612
1875
|
}
|
|
1613
|
-
function
|
|
1876
|
+
function Jt(e, t, n) {
|
|
1614
1877
|
return t && t !== n ? !1 : !Array.isArray(e) || e.length <= 1 || t === n;
|
|
1615
1878
|
}
|
|
1616
|
-
function
|
|
1879
|
+
function Yt(e, t) {
|
|
1617
1880
|
return t.allowedSubject && e.sub === t.allowedSubject ? !0 : t.allowedEmail ? e.email_verified === !0 && e.email?.toLowerCase() === t.allowedEmail : !1;
|
|
1618
1881
|
}
|
|
1619
|
-
function
|
|
1882
|
+
function Y(e, t, n = {}) {
|
|
1620
1883
|
let r = new URL(e);
|
|
1621
1884
|
if (r.username || r.password) throw Error(`OIDC ${t} must not include credentials`);
|
|
1622
|
-
if (r.protocol !== "https:" && !(n.allowLoopbackHttp && r.protocol === "http:" &&
|
|
1885
|
+
if (r.protocol !== "https:" && !(n.allowLoopbackHttp && r.protocol === "http:" && Xt(r.hostname))) throw Error(`OIDC ${t} must use HTTPS`);
|
|
1623
1886
|
}
|
|
1624
|
-
function
|
|
1887
|
+
function Xt(e) {
|
|
1625
1888
|
let t = e.replace(/^\[(.*)]$/, "$1").toLowerCase();
|
|
1626
1889
|
return t === "localhost" || t === "127.0.0.1" || t === "::1";
|
|
1627
1890
|
}
|
|
1628
|
-
function
|
|
1891
|
+
function X(e, t) {
|
|
1629
1892
|
return {
|
|
1630
1893
|
status: 400,
|
|
1631
1894
|
body: t ? {
|
|
@@ -1636,7 +1899,7 @@ function J(e, t) {
|
|
|
1636
1899
|
}
|
|
1637
1900
|
//#endregion
|
|
1638
1901
|
//#region src/provider.ts
|
|
1639
|
-
var
|
|
1902
|
+
var Zt = class {
|
|
1640
1903
|
#e;
|
|
1641
1904
|
#t;
|
|
1642
1905
|
#n;
|
|
@@ -1646,44 +1909,44 @@ var Bt = class {
|
|
|
1646
1909
|
#o;
|
|
1647
1910
|
#s;
|
|
1648
1911
|
constructor(e) {
|
|
1649
|
-
this.#e = e.clientsStore, this.#t = e.codeStore, this.#n = e.tokenStore, this.#r = e.refreshTokenStore ??
|
|
1912
|
+
this.#e = e.clientsStore, this.#t = e.codeStore, this.#n = e.tokenStore, this.#r = e.refreshTokenStore ?? dt(), this.#i = e.publicMcpUrl, this.#a = new URL(e.publicMcpUrl).href, this.#o = e.oidc, this.#s = e.now ?? Date.now;
|
|
1650
1913
|
}
|
|
1651
1914
|
get clientsStore() {
|
|
1652
1915
|
return this.#e;
|
|
1653
1916
|
}
|
|
1654
1917
|
async authorize(e, t, n) {
|
|
1655
|
-
if (!this.#o) throw new
|
|
1656
|
-
let r = await
|
|
1918
|
+
if (!this.#o) throw new A("OIDC is not configured");
|
|
1919
|
+
let r = await Bt(Qt(e, t), this.#e, this.#o.pendingStore, this.#o.config, this.#i, this.#s());
|
|
1657
1920
|
if (r.status === 302) {
|
|
1658
1921
|
n.redirect(302, r.location);
|
|
1659
1922
|
return;
|
|
1660
1923
|
}
|
|
1661
|
-
throw
|
|
1924
|
+
throw $t(r.body);
|
|
1662
1925
|
}
|
|
1663
1926
|
async challengeForAuthorizationCode(e, t) {
|
|
1664
1927
|
let n = this.#t.peekCode(t);
|
|
1665
|
-
if (!n) throw new
|
|
1666
|
-
if (n.clientId !== e.client_id) throw new
|
|
1667
|
-
if (n.expiresAt <= this.#s()) throw this.#t.consumeCode(t), new
|
|
1928
|
+
if (!n) throw new k("Invalid or already used code");
|
|
1929
|
+
if (n.clientId !== e.client_id) throw new k("Code does not match client");
|
|
1930
|
+
if (n.expiresAt <= this.#s()) throw this.#t.consumeCode(t), new k("Expired code");
|
|
1668
1931
|
return n.codeChallenge;
|
|
1669
1932
|
}
|
|
1670
1933
|
async exchangeAuthorizationCode(e, t, n, r, i) {
|
|
1671
1934
|
let a = this.#s(), o = this.#t.peekCode(t);
|
|
1672
|
-
if (!o) throw new
|
|
1673
|
-
if (o.expiresAt <= a) throw this.#t.consumeCode(t), new
|
|
1674
|
-
if (o.clientId !== e.client_id) throw this.#t.consumeCode(t), new
|
|
1675
|
-
if (r === void 0 || o.redirectUri !== r) throw this.#t.consumeCode(t), new
|
|
1676
|
-
if ((o.resource ?? null) !== (i?.href ?? null)) throw this.#t.consumeCode(t), new
|
|
1677
|
-
let s =
|
|
1935
|
+
if (!o) throw new k("Invalid or already used code");
|
|
1936
|
+
if (o.expiresAt <= a) throw this.#t.consumeCode(t), new k("Expired code");
|
|
1937
|
+
if (o.clientId !== e.client_id) throw this.#t.consumeCode(t), new k("Code does not match client");
|
|
1938
|
+
if (r === void 0 || o.redirectUri !== r) throw this.#t.consumeCode(t), new k("Code does not match redirect_uri");
|
|
1939
|
+
if ((o.resource ?? null) !== (i?.href ?? null)) throw this.#t.consumeCode(t), new k("Code does not match resource");
|
|
1940
|
+
let s = tn(o.scopes) ?? [], c = this.#r.issueGrant({
|
|
1678
1941
|
clientId: e.client_id,
|
|
1679
1942
|
scopes: s,
|
|
1680
1943
|
resource: o.resource
|
|
1681
1944
|
}, a);
|
|
1682
|
-
if (!c) throw new
|
|
1945
|
+
if (!c) throw new A("Too many active refresh grants");
|
|
1683
1946
|
let l = this.#n.issueToken(e.client_id, a, o.resource, c.grant.grantId, s);
|
|
1684
|
-
if (!l) throw this.#r.revokeGrant(c.grant.grantId, a), new
|
|
1685
|
-
if (!this.#t.consumeCode(t)) throw this.#n.revokeToken(l.token, a), this.#r.revokeGrant(c.grant.grantId, a), new
|
|
1686
|
-
return
|
|
1947
|
+
if (!l) throw this.#r.revokeGrant(c.grant.grantId, a), new A("Too many active access tokens");
|
|
1948
|
+
if (!this.#t.consumeCode(t)) throw this.#n.revokeToken(l.token, a), this.#r.revokeGrant(c.grant.grantId, a), new k("Authorization code already used");
|
|
1949
|
+
return le.parse({
|
|
1687
1950
|
access_token: l.token,
|
|
1688
1951
|
token_type: "Bearer",
|
|
1689
1952
|
expires_in: l.expiresIn,
|
|
@@ -1692,13 +1955,13 @@ var Bt = class {
|
|
|
1692
1955
|
}
|
|
1693
1956
|
async exchangeRefreshToken(e, t, n, r) {
|
|
1694
1957
|
let i = this.#s(), a = this.#r.rotateRefreshToken(e.client_id, t, {
|
|
1695
|
-
scopes:
|
|
1958
|
+
scopes: tn(n),
|
|
1696
1959
|
...r ? { resource: r.href } : {}
|
|
1697
1960
|
}, i);
|
|
1698
|
-
if (!a.ok) throw a.reason === "refresh_token_replay" && a.grantId && this.#n.revokeTokensForGrant?.(a.grantId, i), new
|
|
1961
|
+
if (!a.ok) throw a.reason === "refresh_token_replay" && a.grantId && this.#n.revokeTokensForGrant?.(a.grantId, i), new k(en(a.reason));
|
|
1699
1962
|
let o = this.#n.issueToken(e.client_id, i, a.grant.resource, a.grant.grantId, a.grant.scopes);
|
|
1700
|
-
if (!o) throw new
|
|
1701
|
-
return
|
|
1963
|
+
if (!o) throw new A("Too many active access tokens");
|
|
1964
|
+
return le.parse({
|
|
1702
1965
|
access_token: o.token,
|
|
1703
1966
|
token_type: "Bearer",
|
|
1704
1967
|
expires_in: o.expiresIn,
|
|
@@ -1707,7 +1970,7 @@ var Bt = class {
|
|
|
1707
1970
|
}
|
|
1708
1971
|
async verifyAccessToken(e) {
|
|
1709
1972
|
let t = this.#n.verifyToken(e, this.#s());
|
|
1710
|
-
if (!t.ok) throw new
|
|
1973
|
+
if (!t.ok) throw new ae(t.reason === "expired_token" ? "Token has expired" : t.reason === "revoked_token" ? "Token has been revoked" : "Token is invalid");
|
|
1711
1974
|
let n = {
|
|
1712
1975
|
token: e,
|
|
1713
1976
|
clientId: t.record.clientId,
|
|
@@ -1715,7 +1978,7 @@ var Bt = class {
|
|
|
1715
1978
|
expiresAt: Math.floor(t.record.expiresAt / 1e3)
|
|
1716
1979
|
};
|
|
1717
1980
|
if (t.record.resource) {
|
|
1718
|
-
if (new URL(t.record.resource).href !== this.#a) throw new
|
|
1981
|
+
if (new URL(t.record.resource).href !== this.#a) throw new ae("Token audience does not match this resource server");
|
|
1719
1982
|
n.resource = new URL(t.record.resource);
|
|
1720
1983
|
}
|
|
1721
1984
|
return n;
|
|
@@ -1727,22 +1990,22 @@ var Bt = class {
|
|
|
1727
1990
|
r && this.#n.revokeTokensForGrant?.(r, n);
|
|
1728
1991
|
}
|
|
1729
1992
|
};
|
|
1730
|
-
function
|
|
1993
|
+
function Qt(e, t) {
|
|
1731
1994
|
let n = new URLSearchParams();
|
|
1732
1995
|
return n.set("client_id", e.client_id), n.set("redirect_uri", t.redirectUri), n.set("response_type", "code"), n.set("code_challenge", t.codeChallenge), n.set("code_challenge_method", "S256"), t.state && n.set("state", t.state), t.scopes?.length && n.set("scope", t.scopes.join(" ")), t.resource && n.set("resource", t.resource.href), n;
|
|
1733
1996
|
}
|
|
1734
|
-
function
|
|
1997
|
+
function $t(e) {
|
|
1735
1998
|
let t = e.error_description ?? e.error;
|
|
1736
1999
|
switch (e.error) {
|
|
1737
|
-
case "temporarily_unavailable": return new
|
|
1738
|
-
case "invalid_request": return new
|
|
1739
|
-
case "invalid_client": return new
|
|
1740
|
-
case "access_denied": return new
|
|
1741
|
-
case "unsupported_response_type": return new
|
|
1742
|
-
default: return new
|
|
2000
|
+
case "temporarily_unavailable": return new A(t);
|
|
2001
|
+
case "invalid_request": return new ie(t);
|
|
2002
|
+
case "invalid_client": return new re(t);
|
|
2003
|
+
case "access_denied": return new ne(t);
|
|
2004
|
+
case "unsupported_response_type": return new se(t);
|
|
2005
|
+
default: return new oe(t);
|
|
1743
2006
|
}
|
|
1744
2007
|
}
|
|
1745
|
-
function
|
|
2008
|
+
function en(e) {
|
|
1746
2009
|
switch (e) {
|
|
1747
2010
|
case "expired_refresh_token": return "Refresh token has expired";
|
|
1748
2011
|
case "revoked_refresh_token": return "Refresh token has been revoked";
|
|
@@ -1753,49 +2016,49 @@ function Ut(e) {
|
|
|
1753
2016
|
default: return "Invalid refresh token";
|
|
1754
2017
|
}
|
|
1755
2018
|
}
|
|
1756
|
-
function
|
|
2019
|
+
function tn(e) {
|
|
1757
2020
|
let t = e?.map((e) => e.trim()).filter(Boolean).map((e) => e === "memory:read_access" ? "memory:read" : e === "memory:write_access" ? "memory:write" : e);
|
|
1758
2021
|
return t && t.length > 0 ? t : void 0;
|
|
1759
2022
|
}
|
|
1760
2023
|
//#endregion
|
|
1761
2024
|
//#region src/http.ts
|
|
1762
|
-
var
|
|
2025
|
+
var nn = "127.0.0.1", rn = 38889, an = 80, on = new Set(["https://claude.ai"]), sn = "authorization,content-type,mcp-session-id", cn = "600", ln = 256, un = 900 * 1e3, dn = 600, fn = /^[a-zA-Z0-9.-]+$/, pn = new Set([
|
|
1763
2026
|
"127.0.0.1",
|
|
1764
2027
|
"::1",
|
|
1765
2028
|
"localhost"
|
|
1766
2029
|
]);
|
|
1767
|
-
function
|
|
2030
|
+
function mn(e, t = !1) {
|
|
1768
2031
|
let r = e?.trim() || "127.0.0.1";
|
|
1769
|
-
if (r.includes("://") || r.includes("/") || r.includes("\\") || !(n(r) || r === "localhost" ||
|
|
1770
|
-
if (!t && !
|
|
2032
|
+
if (r.includes("://") || r.includes("/") || r.includes("\\") || !(n(r) || r === "localhost" || fn.test(r))) throw Error(`Invalid MCP HTTP host: ${e}`);
|
|
2033
|
+
if (!t && !Z(r)) throw Error(`Refusing unsafe MCP HTTP host ${r}; set CODEMEM_MCP_HTTP_UNSAFE_PUBLIC=1 to allow non-loopback binding`);
|
|
1771
2034
|
return r;
|
|
1772
2035
|
}
|
|
1773
|
-
function
|
|
1774
|
-
return
|
|
2036
|
+
function Z(e) {
|
|
2037
|
+
return pn.has(Q(e));
|
|
1775
2038
|
}
|
|
1776
|
-
function
|
|
2039
|
+
function hn(e = process.env.CODEMEM_MCP_HTTP_UNSAFE_PUBLIC) {
|
|
1777
2040
|
return e === "1" || e?.toLowerCase() === "true" || e?.toLowerCase() === "yes";
|
|
1778
2041
|
}
|
|
1779
|
-
function
|
|
1780
|
-
let n =
|
|
1781
|
-
return !n || !
|
|
2042
|
+
function gn(e, t) {
|
|
2043
|
+
let n = yn(e);
|
|
2044
|
+
return !n || !Z(n.host) ? !1 : n.port === null ? t === an : n.port === t;
|
|
1782
2045
|
}
|
|
1783
|
-
function
|
|
2046
|
+
function _n(e, t) {
|
|
1784
2047
|
if (!e) return !0;
|
|
1785
2048
|
try {
|
|
1786
2049
|
let n = new URL(e), r = n.port ? Number(n.port) : n.protocol === "https:" ? 443 : 80;
|
|
1787
|
-
return (n.protocol === "http:" || n.protocol === "https:") && n.username === "" && n.password === "" && n.pathname === "/" && n.search === "" && n.hash === "" &&
|
|
2050
|
+
return (n.protocol === "http:" || n.protocol === "https:") && n.username === "" && n.password === "" && n.pathname === "/" && n.search === "" && n.hash === "" && Z(n.hostname) && r === t;
|
|
1788
2051
|
} catch {
|
|
1789
2052
|
return !1;
|
|
1790
2053
|
}
|
|
1791
2054
|
}
|
|
1792
|
-
function
|
|
1793
|
-
return e ?
|
|
2055
|
+
function vn(e) {
|
|
2056
|
+
return e ? Z(e.replace(/^::ffff:/, "")) : !1;
|
|
1794
2057
|
}
|
|
1795
|
-
function
|
|
2058
|
+
function Q(e) {
|
|
1796
2059
|
return e.replace(/^\[(.*)]$/, "$1").toLowerCase();
|
|
1797
2060
|
}
|
|
1798
|
-
function
|
|
2061
|
+
function yn(e) {
|
|
1799
2062
|
if (!e) return null;
|
|
1800
2063
|
if (e.startsWith("[")) {
|
|
1801
2064
|
let t = /^\[([^\]]+)]:(\d+)$/.exec(e);
|
|
@@ -1820,68 +2083,69 @@ function Q(e) {
|
|
|
1820
2083
|
port: r
|
|
1821
2084
|
} : null;
|
|
1822
2085
|
}
|
|
1823
|
-
function
|
|
1824
|
-
if (e === void 0 || e === "") return
|
|
2086
|
+
function bn(e) {
|
|
2087
|
+
if (e === void 0 || e === "") return rn;
|
|
1825
2088
|
let t = typeof e == "number" ? e : Number(e);
|
|
1826
2089
|
if (!Number.isInteger(t) || t < 0 || t > 65535) throw Error(`Invalid MCP HTTP port: ${e}`);
|
|
1827
2090
|
return t;
|
|
1828
2091
|
}
|
|
1829
|
-
async function
|
|
1830
|
-
let r =
|
|
1831
|
-
|
|
1832
|
-
let
|
|
2092
|
+
async function xn(n = {}) {
|
|
2093
|
+
let r = mn(n.host ?? process.env.CODEMEM_MCP_HTTP_HOST, n.allowUnsafePublic ?? hn()), i = bn(n.port ?? process.env.CODEMEM_MCP_HTTP_PORT), c = n.publicUrl ?? process.env.CODEMEM_MCP_HTTP_PUBLIC_URL, p = c ? _t(c) : void 0, m = new a(n.dbPath ?? o()), h = n.oauthAccessTokenStore ? void 0 : ft(n.oauthStatePath), g = h ?? ct(), _ = h ?? lt(), v = n.oauthAccessTokenStore ?? h ?? ut(), y = zt(), b = Rt(), ee = p !== void 0 || y !== void 0, x = Ve(n.auditEmitter ?? We()), S = /* @__PURE__ */ new Set(), te = null, C = f();
|
|
2094
|
+
C.disable("x-powered-by"), C.set("trust proxy", "loopback");
|
|
2095
|
+
let w = t(C);
|
|
1833
2096
|
await new Promise((e, t) => {
|
|
1834
|
-
|
|
2097
|
+
w.once("error", t), w.listen({
|
|
1835
2098
|
host: r,
|
|
1836
2099
|
port: i
|
|
1837
2100
|
}, () => {
|
|
1838
|
-
|
|
2101
|
+
w.off("error", t), e();
|
|
1839
2102
|
});
|
|
1840
2103
|
});
|
|
1841
|
-
let
|
|
1842
|
-
clientsStore:
|
|
1843
|
-
codeStore:
|
|
1844
|
-
tokenStore:
|
|
1845
|
-
publicMcpUrl:
|
|
1846
|
-
...
|
|
1847
|
-
|
|
1848
|
-
|
|
2104
|
+
let T = p?.href ?? Mn(w, r), E = new URL(T), D = Nn(E, $(w)), ne = new Zt({
|
|
2105
|
+
clientsStore: g,
|
|
2106
|
+
codeStore: _,
|
|
2107
|
+
tokenStore: v,
|
|
2108
|
+
publicMcpUrl: T,
|
|
2109
|
+
...h ? { refreshTokenStore: h } : {},
|
|
2110
|
+
...y ? { oidc: {
|
|
2111
|
+
config: y,
|
|
2112
|
+
pendingStore: b
|
|
1849
2113
|
} } : {}
|
|
1850
|
-
}),
|
|
1851
|
-
|
|
1852
|
-
windowMs:
|
|
1853
|
-
limit:
|
|
2114
|
+
}), re = l(E);
|
|
2115
|
+
C.use(Re({
|
|
2116
|
+
windowMs: un,
|
|
2117
|
+
limit: dn,
|
|
1854
2118
|
standardHeaders: "draft-8",
|
|
1855
2119
|
legacyHeaders: !1,
|
|
1856
2120
|
ipv6Subnet: !1
|
|
1857
|
-
})),
|
|
1858
|
-
let r = $(
|
|
2121
|
+
})), C.use((e, t, n) => {
|
|
2122
|
+
let r = $(w), i = Fn(e.path);
|
|
1859
2123
|
if (i === "/mcp") {
|
|
1860
|
-
if (
|
|
1861
|
-
if (
|
|
2124
|
+
if (Sn(e, r, p)) {
|
|
2125
|
+
if (En(e, t, p), e.method === "OPTIONS") {
|
|
1862
2126
|
t.status(204).send("");
|
|
1863
2127
|
return;
|
|
1864
2128
|
}
|
|
1865
2129
|
return n();
|
|
1866
2130
|
}
|
|
1867
|
-
|
|
2131
|
+
On(e, i, p), t.status(403).type("text/plain").send("Forbidden");
|
|
1868
2132
|
return;
|
|
1869
2133
|
}
|
|
1870
|
-
if (
|
|
1871
|
-
if (
|
|
1872
|
-
if (
|
|
2134
|
+
if (Pn(i)) {
|
|
2135
|
+
if (wn(e, r, p)) {
|
|
2136
|
+
if (En(e, t, p), e.method === "OPTIONS") {
|
|
1873
2137
|
t.status(204).send("");
|
|
1874
2138
|
return;
|
|
1875
2139
|
}
|
|
1876
2140
|
return n();
|
|
1877
2141
|
}
|
|
1878
|
-
|
|
2142
|
+
On(e, i, p), t.status(403).type("text/plain").send("Forbidden");
|
|
1879
2143
|
return;
|
|
1880
2144
|
}
|
|
1881
2145
|
n();
|
|
1882
|
-
}),
|
|
2146
|
+
}), C.use(In(x)), C.get("/oauth/callback", async (e, t) => {
|
|
1883
2147
|
let n = e.socket.remoteAddress ?? void 0;
|
|
1884
|
-
if (!
|
|
2148
|
+
if (!y) {
|
|
1885
2149
|
x(L("oidc_callback", {
|
|
1886
2150
|
outcome: "denied",
|
|
1887
2151
|
reason: "oidc_not_configured",
|
|
@@ -1892,7 +2156,7 @@ async function cn(n = {}) {
|
|
|
1892
2156
|
});
|
|
1893
2157
|
return;
|
|
1894
2158
|
}
|
|
1895
|
-
let r = await
|
|
2159
|
+
let r = await Vt(new URLSearchParams(e.query), b, y, T);
|
|
1896
2160
|
if ("status" in r) {
|
|
1897
2161
|
x(L("oidc_callback", {
|
|
1898
2162
|
outcome: "denied",
|
|
@@ -1901,11 +2165,11 @@ async function cn(n = {}) {
|
|
|
1901
2165
|
})), t.status(r.status).json(r.body);
|
|
1902
2166
|
return;
|
|
1903
2167
|
}
|
|
1904
|
-
let i = r.oauthParams.get("client_id") ?? void 0, a =
|
|
2168
|
+
let i = r.oauthParams.get("client_id") ?? void 0, a = _.issueCode({
|
|
1905
2169
|
clientId: r.oauthParams.get("client_id") ?? "",
|
|
1906
2170
|
redirectUri: r.oauthParams.get("redirect_uri") ?? "",
|
|
1907
2171
|
codeChallenge: r.oauthParams.get("code_challenge") ?? "",
|
|
1908
|
-
scopes:
|
|
2172
|
+
scopes: Gn(r.oauthParams.get("scope")),
|
|
1909
2173
|
...r.oauthParams.get("resource") ? { resource: r.oauthParams.get("resource") ?? void 0 } : {},
|
|
1910
2174
|
expiresAt: Date.now() + 300 * 1e3
|
|
1911
2175
|
});
|
|
@@ -1930,28 +2194,28 @@ async function cn(n = {}) {
|
|
|
1930
2194
|
clientId: i,
|
|
1931
2195
|
remoteAddress: n
|
|
1932
2196
|
})), t.redirect(302, o.href);
|
|
1933
|
-
}),
|
|
1934
|
-
t.status(200).json(
|
|
1935
|
-
mcpUrl:
|
|
1936
|
-
clientsStore:
|
|
2197
|
+
}), C.get("/.well-known/oauth-authorization-server", (e, t) => {
|
|
2198
|
+
t.status(200).json(mt({
|
|
2199
|
+
mcpUrl: T,
|
|
2200
|
+
clientsStore: g
|
|
1937
2201
|
}));
|
|
1938
|
-
}),
|
|
1939
|
-
t.status(200).json(
|
|
1940
|
-
}),
|
|
1941
|
-
provider:
|
|
1942
|
-
issuerUrl:
|
|
1943
|
-
baseUrl:
|
|
1944
|
-
resourceServerUrl:
|
|
1945
|
-
resourceName:
|
|
2202
|
+
}), C.get("/.well-known/oauth-protected-resource/mcp", (e, t) => {
|
|
2203
|
+
t.status(200).json(ht(T));
|
|
2204
|
+
}), C.use(u({
|
|
2205
|
+
provider: ne,
|
|
2206
|
+
issuerUrl: D,
|
|
2207
|
+
baseUrl: D,
|
|
2208
|
+
resourceServerUrl: E,
|
|
2209
|
+
resourceName: Ge,
|
|
1946
2210
|
scopesSupported: R,
|
|
1947
2211
|
serviceDocumentationUrl: new URL(z),
|
|
1948
2212
|
clientRegistrationOptions: { clientSecretExpirySeconds: 0 }
|
|
1949
2213
|
}));
|
|
1950
|
-
let
|
|
1951
|
-
verifier:
|
|
1952
|
-
resourceMetadataUrl:
|
|
1953
|
-
}) : (e, t, n) => n(),
|
|
1954
|
-
return
|
|
2214
|
+
let O = ee ? s({
|
|
2215
|
+
verifier: ne,
|
|
2216
|
+
resourceMetadataUrl: re
|
|
2217
|
+
}) : (e, t, n) => n(), k = ee ? Un(x, v) : (e, t, n) => n();
|
|
2218
|
+
return C.post("/mcp", k, O, async (t, n) => {
|
|
1955
2219
|
t.auth && x(L("bearer", {
|
|
1956
2220
|
outcome: "success",
|
|
1957
2221
|
clientId: t.auth.clientId,
|
|
@@ -1964,59 +2228,59 @@ async function cn(n = {}) {
|
|
|
1964
2228
|
} finally {
|
|
1965
2229
|
S.delete(a), await r.close();
|
|
1966
2230
|
}
|
|
1967
|
-
}),
|
|
2231
|
+
}), C.all("/mcp", (e, t) => {
|
|
1968
2232
|
t.setHeader("Allow", "POST"), t.status(405).type("text/plain").send("Method not allowed");
|
|
1969
|
-
}),
|
|
2233
|
+
}), C.use((e, t) => {
|
|
1970
2234
|
t.status(404).type("text/plain").send("Not found");
|
|
1971
2235
|
}), {
|
|
1972
|
-
server:
|
|
2236
|
+
server: w,
|
|
1973
2237
|
store: m,
|
|
1974
|
-
url: `http://${
|
|
1975
|
-
close: () => (
|
|
2238
|
+
url: `http://${jn(r)}:${$(w)}/mcp`,
|
|
2239
|
+
close: () => (te ??= (async () => {
|
|
1976
2240
|
await Promise.allSettled([...S].map(({ mcpServer: e }) => e.close())), await new Promise((e, t) => {
|
|
1977
|
-
|
|
2241
|
+
w.close((n) => {
|
|
1978
2242
|
if (!n || n.code === "ERR_SERVER_NOT_RUNNING") {
|
|
1979
2243
|
e();
|
|
1980
2244
|
return;
|
|
1981
2245
|
}
|
|
1982
2246
|
t(n);
|
|
1983
|
-
}),
|
|
2247
|
+
}), w.closeAllConnections();
|
|
1984
2248
|
}), m.close();
|
|
1985
|
-
})(),
|
|
2249
|
+
})(), te)
|
|
1986
2250
|
};
|
|
1987
2251
|
}
|
|
1988
|
-
function
|
|
1989
|
-
return
|
|
2252
|
+
function Sn(e, t, n) {
|
|
2253
|
+
return Cn(e, t) ? !0 : n ? An(e.headers.host, n) && Tn(e.headers.origin, n) : !1;
|
|
1990
2254
|
}
|
|
1991
|
-
function
|
|
1992
|
-
return
|
|
2255
|
+
function Cn(e, t) {
|
|
2256
|
+
return vn(e.socket.remoteAddress) && gn(e.headers.host, t) && _n(e.headers.origin, t);
|
|
1993
2257
|
}
|
|
1994
|
-
function
|
|
1995
|
-
return
|
|
2258
|
+
function wn(e, t, n) {
|
|
2259
|
+
return Cn(e, t) ? !0 : n ? An(e.headers.host, n) && Tn(e.headers.origin, n) : !1;
|
|
1996
2260
|
}
|
|
1997
|
-
function
|
|
2261
|
+
function Tn(e, t) {
|
|
1998
2262
|
if (!e) return !0;
|
|
1999
2263
|
try {
|
|
2000
2264
|
let n = new URL(e);
|
|
2001
|
-
return n.origin === t.origin ||
|
|
2265
|
+
return n.origin === t.origin || on.has(n.origin);
|
|
2002
2266
|
} catch {
|
|
2003
2267
|
return !1;
|
|
2004
2268
|
}
|
|
2005
2269
|
}
|
|
2006
|
-
function
|
|
2270
|
+
function En(e, t, n) {
|
|
2007
2271
|
if (!n) return;
|
|
2008
|
-
let r =
|
|
2009
|
-
r && (t.setHeader("Access-Control-Allow-Origin", r), t.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"), t.setHeader("Access-Control-Allow-Headers", e.headers["access-control-request-headers"] ??
|
|
2272
|
+
let r = Dn(e.headers.origin, n);
|
|
2273
|
+
r && (t.setHeader("Access-Control-Allow-Origin", r), t.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"), t.setHeader("Access-Control-Allow-Headers", e.headers["access-control-request-headers"] ?? sn), t.setHeader("Access-Control-Max-Age", cn), t.setHeader("Vary", "Origin"));
|
|
2010
2274
|
}
|
|
2011
|
-
function
|
|
2275
|
+
function Dn(e, t) {
|
|
2012
2276
|
if (e) try {
|
|
2013
2277
|
let n = new URL(e).origin;
|
|
2014
|
-
if (n === t.origin ||
|
|
2278
|
+
if (n === t.origin || on.has(n)) return n;
|
|
2015
2279
|
} catch {
|
|
2016
2280
|
return;
|
|
2017
2281
|
}
|
|
2018
2282
|
}
|
|
2019
|
-
function
|
|
2283
|
+
function On(e, t, n) {
|
|
2020
2284
|
console.warn(JSON.stringify({
|
|
2021
2285
|
source: "codemem-mcp-http-guard",
|
|
2022
2286
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -2024,50 +2288,50 @@ function hn(e, t, n) {
|
|
|
2024
2288
|
reason: "host_or_origin_mismatch",
|
|
2025
2289
|
method: e.method,
|
|
2026
2290
|
path: t,
|
|
2027
|
-
host:
|
|
2028
|
-
origin:
|
|
2291
|
+
host: kn(e.headers.host),
|
|
2292
|
+
origin: kn(e.headers.origin),
|
|
2029
2293
|
expectedOrigin: n?.origin,
|
|
2030
2294
|
remoteAddress: e.socket.remoteAddress ?? void 0
|
|
2031
2295
|
}));
|
|
2032
2296
|
}
|
|
2033
|
-
function
|
|
2034
|
-
return !e || e.length <=
|
|
2297
|
+
function kn(e) {
|
|
2298
|
+
return !e || e.length <= ln ? e : `${e.slice(0, ln)}…`;
|
|
2035
2299
|
}
|
|
2036
|
-
function
|
|
2037
|
-
let n =
|
|
2300
|
+
function An(e, t) {
|
|
2301
|
+
let n = yn(e);
|
|
2038
2302
|
if (!n) return !1;
|
|
2039
2303
|
let r = t.port ? Number(t.port) : t.protocol === "https:" ? 443 : 80, i = t.protocol === "https:" ? 443 : 80, a = n.port ?? i;
|
|
2040
|
-
return
|
|
2304
|
+
return Q(n.host) === Q(t.hostname) && a === r;
|
|
2041
2305
|
}
|
|
2042
2306
|
function $(e) {
|
|
2043
2307
|
let t = e.address();
|
|
2044
|
-
return !t || typeof t == "string" ?
|
|
2308
|
+
return !t || typeof t == "string" ? rn : t.port;
|
|
2045
2309
|
}
|
|
2046
|
-
function
|
|
2310
|
+
function jn(e) {
|
|
2047
2311
|
return n(e) === 6 ? `[${e}]` : e;
|
|
2048
2312
|
}
|
|
2049
|
-
function
|
|
2050
|
-
return `http://${
|
|
2313
|
+
function Mn(e, t) {
|
|
2314
|
+
return `http://${jn(t)}:${$(e)}/mcp`;
|
|
2051
2315
|
}
|
|
2052
|
-
function
|
|
2053
|
-
return e.protocol === "https:" ||
|
|
2316
|
+
function Nn(e, t) {
|
|
2317
|
+
return e.protocol === "https:" || Z(e.hostname) && Q(e.hostname) !== "::1" ? new URL(e.origin) : new URL(`http://localhost:${t}/`);
|
|
2054
2318
|
}
|
|
2055
|
-
function
|
|
2319
|
+
function Pn(e) {
|
|
2056
2320
|
return e === "/register" || e === "/authorize" || e === "/token" || e === "/revoke" || e === "/oauth/callback" || e === "/.well-known/oauth-authorization-server" || e === "/.well-known/oauth-protected-resource/mcp";
|
|
2057
2321
|
}
|
|
2058
|
-
function
|
|
2322
|
+
function Fn(e) {
|
|
2059
2323
|
return e.length > 1 ? e.replace(/\/+$/, "") : e;
|
|
2060
2324
|
}
|
|
2061
|
-
function
|
|
2325
|
+
function In(e) {
|
|
2062
2326
|
return (t, n, r) => {
|
|
2063
2327
|
let i = t.path;
|
|
2064
|
-
if (!
|
|
2328
|
+
if (!Ln(i)) return r();
|
|
2065
2329
|
let a, o = n.json.bind(n);
|
|
2066
2330
|
n.json = ((e) => (a = e, o(e))), n.on("finish", () => {
|
|
2067
2331
|
if (i === "/oauth/callback") return;
|
|
2068
|
-
let r =
|
|
2332
|
+
let r = Rn(i, t);
|
|
2069
2333
|
if (!r) return;
|
|
2070
|
-
let o =
|
|
2334
|
+
let o = Bn(n, a), s = Hn(t, a);
|
|
2071
2335
|
e(L(r, {
|
|
2072
2336
|
outcome: o ? "denied" : "success",
|
|
2073
2337
|
...o ? { reason: o } : {},
|
|
@@ -2077,17 +2341,17 @@ function Cn(e) {
|
|
|
2077
2341
|
}), r();
|
|
2078
2342
|
};
|
|
2079
2343
|
}
|
|
2080
|
-
function
|
|
2081
|
-
return
|
|
2344
|
+
function Ln(e) {
|
|
2345
|
+
return zn(e) !== null;
|
|
2082
2346
|
}
|
|
2083
|
-
function
|
|
2084
|
-
return e === "/token" && t.body?.grant_type === "refresh_token" ? "refresh" :
|
|
2347
|
+
function Rn(e, t) {
|
|
2348
|
+
return e === "/token" && t.body?.grant_type === "refresh_token" ? "refresh" : zn(e);
|
|
2085
2349
|
}
|
|
2086
|
-
function
|
|
2350
|
+
function zn(e) {
|
|
2087
2351
|
return e === "/register" ? "registration" : e === "/authorize" ? "authorize" : e === "/token" ? "token" : e === "/revoke" ? "revocation" : null;
|
|
2088
2352
|
}
|
|
2089
|
-
function
|
|
2090
|
-
let n =
|
|
2353
|
+
function Bn(e, t) {
|
|
2354
|
+
let n = Vn(t);
|
|
2091
2355
|
if (n) return n;
|
|
2092
2356
|
let r = e.getHeader("location");
|
|
2093
2357
|
if (typeof r == "string") try {
|
|
@@ -2096,15 +2360,15 @@ function Dn(e, t) {
|
|
|
2096
2360
|
return;
|
|
2097
2361
|
}
|
|
2098
2362
|
}
|
|
2099
|
-
function
|
|
2363
|
+
function Vn(e) {
|
|
2100
2364
|
if (typeof e == "object" && e && "error" in e && typeof e.error == "string") return e.error;
|
|
2101
2365
|
}
|
|
2102
|
-
function
|
|
2366
|
+
function Hn(e, t) {
|
|
2103
2367
|
return typeof t == "object" && t && "client_id" in t && typeof t.client_id == "string" ? t.client_id : (typeof e.body?.client_id == "string" ? e.body.client_id : void 0) || (typeof e.query.client_id == "string" ? e.query.client_id : void 0);
|
|
2104
2368
|
}
|
|
2105
|
-
function
|
|
2369
|
+
function Un(e, t) {
|
|
2106
2370
|
return (n, r, i) => {
|
|
2107
|
-
let a =
|
|
2371
|
+
let a = Wn(n.headers.authorization, t);
|
|
2108
2372
|
a && e(L("bearer", {
|
|
2109
2373
|
outcome: "denied",
|
|
2110
2374
|
reason: a,
|
|
@@ -2112,22 +2376,22 @@ function An(e, t) {
|
|
|
2112
2376
|
})), i();
|
|
2113
2377
|
};
|
|
2114
2378
|
}
|
|
2115
|
-
function
|
|
2379
|
+
function Wn(e, t) {
|
|
2116
2380
|
if (!e) return "missing_authorization_header";
|
|
2117
2381
|
let [n, r, i] = e.trim().split(/\s+/);
|
|
2118
2382
|
if (!n || !r || i || n.toLowerCase() !== "bearer") return "malformed_authorization_header";
|
|
2119
2383
|
let a = t.verifyToken(r);
|
|
2120
2384
|
return a.ok ? null : a.reason;
|
|
2121
2385
|
}
|
|
2122
|
-
function
|
|
2386
|
+
function Gn(e) {
|
|
2123
2387
|
return e?.split(/\s+/).map((e) => e.trim()).filter(Boolean) ?? [];
|
|
2124
2388
|
}
|
|
2125
|
-
function
|
|
2389
|
+
function Kn() {
|
|
2126
2390
|
let e = process.argv[1];
|
|
2127
2391
|
return e ? import.meta.url === i(e).href : !1;
|
|
2128
2392
|
}
|
|
2129
|
-
async function
|
|
2130
|
-
let e = await
|
|
2393
|
+
async function qn() {
|
|
2394
|
+
let e = await xn();
|
|
2131
2395
|
console.error(`codemem MCP HTTP server listening at ${e.url}`);
|
|
2132
2396
|
let t = async () => {
|
|
2133
2397
|
try {
|
|
@@ -2137,10 +2401,10 @@ async function Pn() {
|
|
|
2137
2401
|
};
|
|
2138
2402
|
process.on("SIGINT", t), process.on("SIGTERM", t);
|
|
2139
2403
|
}
|
|
2140
|
-
|
|
2404
|
+
Kn() && qn().catch((e) => {
|
|
2141
2405
|
console.error("codemem MCP HTTP server failed to start:", e), process.exit(1);
|
|
2142
2406
|
});
|
|
2143
2407
|
//#endregion
|
|
2144
|
-
export {
|
|
2408
|
+
export { nn as DEFAULT_MCP_HTTP_HOST, rn as DEFAULT_MCP_HTTP_PORT, gn as isAllowedMcpHttpRequestHost, _n as isAllowedMcpHttpRequestOrigin, vn as isAllowedMcpHttpRequestRemoteAddress, Z as isLoopbackHost, hn as isUnsafePublicBindAllowed, bn as parseMcpHttpPort, xn as startCodememMcpHttpServer, mn as validateMcpHttpHost };
|
|
2145
2409
|
|
|
2146
2410
|
//# sourceMappingURL=http.js.map
|