@suveren/gateway 0.36.0 → 0.36.1
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.
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"icon": "briefcase",
|
|
7
7
|
"profile": "sales",
|
|
8
8
|
"npmPackage": "@humanagencyp/erp-mcp",
|
|
9
|
-
"npmVersion": "0.9.
|
|
9
|
+
"npmVersion": "0.9.4",
|
|
10
10
|
"mcp": {
|
|
11
11
|
"command": "erp-mcp",
|
|
12
12
|
"args": [],
|
|
@@ -113,11 +113,13 @@
|
|
|
113
113
|
"requiredValue": "unlimited"
|
|
114
114
|
},
|
|
115
115
|
"find_customers": {
|
|
116
|
+
"readAlsoUnder": ["invoicing"],
|
|
116
117
|
"category": "read",
|
|
117
118
|
"boundField": "read_access",
|
|
118
119
|
"requiredValue": "unlimited"
|
|
119
120
|
},
|
|
120
121
|
"get_customer": {
|
|
122
|
+
"readAlsoUnder": ["invoicing"],
|
|
121
123
|
"category": "read",
|
|
122
124
|
"boundField": "read_access",
|
|
123
125
|
"requiredValue": "unlimited"
|
|
@@ -3,6 +3,13 @@ import {
|
|
|
3
3
|
setPromptOverride
|
|
4
4
|
} from "./chunk-3BNWN6VP.mjs";
|
|
5
5
|
|
|
6
|
+
// src/lib/no-foreign-framing.ts
|
|
7
|
+
function noForeignFraming(_req, res, next) {
|
|
8
|
+
res.setHeader("X-Frame-Options", "SAMEORIGIN");
|
|
9
|
+
res.setHeader("Content-Security-Policy", "frame-ancestors 'self'");
|
|
10
|
+
next();
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
// src/index.ts
|
|
7
14
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
8
15
|
import { existsSync as existsSync13, readFileSync as readFileSync18, renameSync as renameSync6 } from "fs";
|
|
@@ -5398,6 +5405,7 @@ var shownSnapshotStore = new ShownSnapshotStore(DATA_DIR);
|
|
|
5398
5405
|
var internalSecret2 = process.env.SUVEREN_INTERNAL_SECRET ?? randomBytes3(32).toString("hex");
|
|
5399
5406
|
setInternalSecret(internalSecret2);
|
|
5400
5407
|
var app = express();
|
|
5408
|
+
app.use(noForeignFraming);
|
|
5401
5409
|
var jsonParser = express.json();
|
|
5402
5410
|
var loginAttempts = /* @__PURE__ */ new Map();
|
|
5403
5411
|
var LOGIN_WINDOW_MS = 6e4;
|
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -4067,6 +4067,20 @@ function invalidMessageReason(toolName, entry) {
|
|
|
4067
4067
|
}
|
|
4068
4068
|
return null;
|
|
4069
4069
|
}
|
|
4070
|
+
function invalidManifestReadAlsoUnderReason(manifest) {
|
|
4071
|
+
const overrides = manifest.toolGating?.overrides ?? {};
|
|
4072
|
+
for (const [toolName, entry] of Object.entries(overrides)) {
|
|
4073
|
+
const extra = entry?.readAlsoUnder;
|
|
4074
|
+
if (extra === void 0) continue;
|
|
4075
|
+
const at = `override "${toolName}".readAlsoUnder`;
|
|
4076
|
+
if (!Array.isArray(extra) || extra.length === 0 || !extra.every((p) => typeof p === "string" && p.length > 0)) {
|
|
4077
|
+
return `${at} must be a non-empty list of area names`;
|
|
4078
|
+
}
|
|
4079
|
+
if (entry?.category !== "read") return `${at} is allowed on read tools only (category "read")`;
|
|
4080
|
+
if (entry?.read !== void 0) return `${at} cannot be combined with a read adapter (age window)`;
|
|
4081
|
+
}
|
|
4082
|
+
return null;
|
|
4083
|
+
}
|
|
4070
4084
|
function invalidManifestMessageReason(manifest) {
|
|
4071
4085
|
const overrides = manifest.toolGating?.overrides ?? {};
|
|
4072
4086
|
for (const [toolName, entry] of Object.entries(overrides)) {
|
|
@@ -4504,6 +4518,11 @@ function loadManifests(integrationsDir) {
|
|
|
4504
4518
|
console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${internalReason}`);
|
|
4505
4519
|
continue;
|
|
4506
4520
|
}
|
|
4521
|
+
const readAlsoReason = invalidManifestReadAlsoUnderReason(manifest);
|
|
4522
|
+
if (readAlsoReason) {
|
|
4523
|
+
console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${readAlsoReason}`);
|
|
4524
|
+
continue;
|
|
4525
|
+
}
|
|
4507
4526
|
const messageReason = invalidManifestMessageReason(manifest);
|
|
4508
4527
|
if (messageReason) {
|
|
4509
4528
|
console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${messageReason}`);
|
|
@@ -6354,9 +6373,10 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
|
|
|
6354
6373
|
};
|
|
6355
6374
|
}
|
|
6356
6375
|
const { profile, executionMapping, staticExecution, category, boundField: toolBoundField, requiredValue: toolRequiredValue } = tool.gating;
|
|
6376
|
+
const toolAreas = category === "read" ? [profile, ...tool.gating.readAlsoUnder ?? []] : [profile];
|
|
6357
6377
|
const eligibleMandates = () => {
|
|
6358
6378
|
const refusals = [];
|
|
6359
|
-
const matching = state2.getEnrichedAuthorizations().filter((a) => a.complete && profileMatches(a.profileId,
|
|
6379
|
+
const matching = state2.getEnrichedAuthorizations().filter((a) => a.complete && toolAreas.some((p) => profileMatches(a.profileId, p))).filter((a) => {
|
|
6360
6380
|
const refusal = integrationManager2.mandateRefusal?.(tool, a) ?? null;
|
|
6361
6381
|
if (refusal) refusals.push(refusal);
|
|
6362
6382
|
return !refusal;
|
|
@@ -7124,7 +7144,8 @@ function buildProxiedToolDescription(tool) {
|
|
|
7124
7144
|
return `[Suveren: no gating config] ${tool.description}`;
|
|
7125
7145
|
}
|
|
7126
7146
|
const profile = tool.gating.profile;
|
|
7127
|
-
const
|
|
7147
|
+
const areas = tool.gating.category === "read" ? [shortProfile(profile), ...(tool.gating.readAlsoUnder ?? []).map(shortProfile)] : [shortProfile(profile)];
|
|
7148
|
+
const condition = `works only under a ${areas.join(" or ")} mandate, check list-authorizations`;
|
|
7128
7149
|
if (tool.gating.category === "read") {
|
|
7129
7150
|
return `[Suveren: ${profile} \u2014 read; ${condition}] ${tool.description}`;
|
|
7130
7151
|
}
|
|
@@ -7342,7 +7363,8 @@ function listedWithoutMandate(authorizations, integrationManager2) {
|
|
|
7342
7363
|
for (const tool of integrationManager2.getAllTools()) {
|
|
7343
7364
|
if (!toolAlwaysListed(tool, isBuiltin, builtinAlwaysListed)) continue;
|
|
7344
7365
|
const profile = tool.gating.profile;
|
|
7345
|
-
|
|
7366
|
+
const areas = tool.gating.category === "read" ? [profile, ...tool.gating.readAlsoUnder ?? []] : [profile];
|
|
7367
|
+
if (authorizations.some((a) => a.complete && areas.some((p) => profileMatches(a.profileId, p)))) continue;
|
|
7346
7368
|
const short = shortProfileName2(profile);
|
|
7347
7369
|
byProfile.set(short, [...byProfile.get(short) ?? [], tool.namespacedName]);
|
|
7348
7370
|
}
|
|
@@ -9541,7 +9563,9 @@ var IntegrationManager = class {
|
|
|
9541
9563
|
hideUnlessAuthorized: ext.hideUnlessAuthorized,
|
|
9542
9564
|
simulationOnly: ext.simulationOnly,
|
|
9543
9565
|
approvalView: ext.approvalView,
|
|
9544
|
-
internal: ext.internal
|
|
9566
|
+
internal: ext.internal,
|
|
9567
|
+
// Further areas whose mandates may authorize this read (manifest).
|
|
9568
|
+
readAlsoUnder: ext.readAlsoUnder
|
|
9545
9569
|
};
|
|
9546
9570
|
}
|
|
9547
9571
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suveren/gateway",
|
|
3
|
-
"version": "0.36.
|
|
3
|
+
"version": "0.36.1",
|
|
4
4
|
"description": "Suveren gateway — local agent gateway built in compliance with the Human Agency Protocol (HAP). Runs the UI, control plane, and MCP server in one Node process.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|