@suveren/gateway 0.35.1 → 0.35.2
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/mcp-server/http.mjs
CHANGED
|
@@ -5749,18 +5749,19 @@ async function finalizeAttachmentsForExecution(integrationManager2, integrationI
|
|
|
5749
5749
|
contentBase64: d.contentBase64
|
|
5750
5750
|
}));
|
|
5751
5751
|
} else {
|
|
5752
|
-
const
|
|
5753
|
-
const
|
|
5754
|
-
const
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5752
|
+
const arg = transport.arg;
|
|
5753
|
+
const attachments = resolvedDocs.map((d) => ({ filename: d.filename, contentType: d.contentType, contentBase64: d.contentBase64 }));
|
|
5754
|
+
const withRaw = (a) => ({
|
|
5755
|
+
...a,
|
|
5756
|
+
[arg]: toBase64Url(buildMimeMessage({
|
|
5757
|
+
to: toStringArray(a.to),
|
|
5758
|
+
cc: toStringArray(a.cc),
|
|
5759
|
+
subject: typeof a.subject === "string" ? a.subject : "",
|
|
5760
|
+
bodyText: typeof a.body === "string" ? a.body : "",
|
|
5761
|
+
attachments
|
|
5762
|
+
}))
|
|
5762
5763
|
});
|
|
5763
|
-
|
|
5764
|
+
return { ok: true, args: withRaw(outgoing), rebuildTransport: withRaw };
|
|
5764
5765
|
}
|
|
5765
5766
|
}
|
|
5766
5767
|
return { ok: true, args: outgoing };
|
|
@@ -6795,12 +6796,14 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
|
|
|
6795
6796
|
}
|
|
6796
6797
|
}
|
|
6797
6798
|
let finalArgs = callArgs;
|
|
6799
|
+
let rebuildTransport;
|
|
6798
6800
|
if (tool.gating?.attachmentsArg || tool.gating?.insertFields?.length) {
|
|
6799
6801
|
const finalized = await finalizeAttachmentsForExecution(integrationManager2, tool.integrationId, callArgs);
|
|
6800
6802
|
if (!finalized.ok) {
|
|
6801
6803
|
return { content: [{ type: "text", text: finalized.message }], isError: true };
|
|
6802
6804
|
}
|
|
6803
6805
|
finalArgs = finalized.args;
|
|
6806
|
+
rebuildTransport = finalized.rebuildTransport;
|
|
6804
6807
|
}
|
|
6805
6808
|
let receiptId;
|
|
6806
6809
|
try {
|
|
@@ -7031,6 +7034,7 @@ Proposal ID: ${proposal.id}. Use check-pending-commitments to track status.` + a
|
|
|
7031
7034
|
});
|
|
7032
7035
|
let outgoingArgs = shouldAttachFooter() && receiptId ? appendVerificationFooter(tool, finalArgs, receiptId, auth.subjects?.[0]) : finalArgs;
|
|
7033
7036
|
if (receiptId) outgoingArgs = attachTicketId(tool, outgoingArgs, receiptId);
|
|
7037
|
+
if (rebuildTransport) outgoingArgs = rebuildTransport(outgoingArgs);
|
|
7034
7038
|
outgoingArgs = encodeOutgoingArgs(tool, outgoingArgs);
|
|
7035
7039
|
outgoingArgs = stripSourceLink(outgoingArgs);
|
|
7036
7040
|
outgoingArgs = stripAttachmentsSealedMeta(outgoingArgs);
|
|
@@ -8654,6 +8658,9 @@ function withoutBlockedArgs(schema, blocked) {
|
|
|
8654
8658
|
}
|
|
8655
8659
|
return out;
|
|
8656
8660
|
}
|
|
8661
|
+
function stableEnvKey(env) {
|
|
8662
|
+
return JSON.stringify(Object.keys(env).sort().map((k) => [k, env[k]]));
|
|
8663
|
+
}
|
|
8657
8664
|
var RESPAWN_DELAYS = [2e3, 4e3, 6e3];
|
|
8658
8665
|
var MAX_RESPAWN_ATTEMPTS = 3;
|
|
8659
8666
|
var CONNECT_TIMEOUT_MS = 3e4;
|
|
@@ -8995,6 +9002,7 @@ var IntegrationManager = class {
|
|
|
8995
9002
|
);
|
|
8996
9003
|
}
|
|
8997
9004
|
const env = this.resolveEnvKeys(config);
|
|
9005
|
+
const credentialEnv = stableEnvKey(env);
|
|
8998
9006
|
if (isSimulationMode()) {
|
|
8999
9007
|
const manifest = getManifest(config.id);
|
|
9000
9008
|
const simDecl = manifest?.simulation;
|
|
@@ -9068,7 +9076,8 @@ var IntegrationManager = class {
|
|
|
9068
9076
|
client,
|
|
9069
9077
|
transport,
|
|
9070
9078
|
tools,
|
|
9071
|
-
respawnAttempts: 0
|
|
9079
|
+
respawnAttempts: 0,
|
|
9080
|
+
credentialEnv
|
|
9072
9081
|
};
|
|
9073
9082
|
this.running.set(config.id, entry);
|
|
9074
9083
|
transport.onclose = () => {
|
|
@@ -9391,6 +9400,21 @@ var IntegrationManager = class {
|
|
|
9391
9400
|
isRunning(id) {
|
|
9392
9401
|
return this.running.has(id);
|
|
9393
9402
|
}
|
|
9403
|
+
/**
|
|
9404
|
+
* True when the integration is running but the vault credentials would now
|
|
9405
|
+
* resolve to a different env than the one its process was started with.
|
|
9406
|
+
*
|
|
9407
|
+
* Why: at boot the gateway starts connectors whose settings are all optional
|
|
9408
|
+
* (ERP, CRM — mode/adapter/company file) BEFORE the vault is unlocked, so they
|
|
9409
|
+
* come up on their defaults (simulation). The settings arrive on unlock, and
|
|
9410
|
+
* without a restart the process keeps running on the wrong mode — the user's
|
|
9411
|
+
* live data silently disappears from view.
|
|
9412
|
+
*/
|
|
9413
|
+
credentialsChangedSinceStart(config) {
|
|
9414
|
+
const entry = this.running.get(config.id);
|
|
9415
|
+
if (!entry) return false;
|
|
9416
|
+
return stableEnvKey(this.resolveEnvKeys(config)) !== entry.credentialEnv;
|
|
9417
|
+
}
|
|
9394
9418
|
/**
|
|
9395
9419
|
* Check if all required env keys for an integration can be resolved.
|
|
9396
9420
|
*/
|
|
@@ -9557,7 +9581,8 @@ var IntegrationManager = class {
|
|
|
9557
9581
|
client: null,
|
|
9558
9582
|
transport: null,
|
|
9559
9583
|
tools: [],
|
|
9560
|
-
respawnAttempts: attempts + 1
|
|
9584
|
+
respawnAttempts: attempts + 1,
|
|
9585
|
+
credentialEnv: ""
|
|
9561
9586
|
};
|
|
9562
9587
|
this.running.set(id, fakeEntry);
|
|
9563
9588
|
this.handleCrash(id);
|
|
@@ -11708,11 +11733,16 @@ async function startIntegrationForService(serviceId) {
|
|
|
11708
11733
|
(c) => c.id === serviceId || Object.values(c.envKeys ?? {}).some((ref) => typeof ref === "string" && ref.startsWith(`${serviceId}.`))
|
|
11709
11734
|
);
|
|
11710
11735
|
for (const config of candidates) {
|
|
11736
|
+
if (integrationManager.isRunning(config.id) && integrationManager.credentialsChangedSinceStart(config)) {
|
|
11737
|
+
console.error(`[Suveren MCP] ${config.id}: credentials changed since start \u2014 restarting`);
|
|
11738
|
+
await startOneIntegration(config, { restart: true });
|
|
11739
|
+
continue;
|
|
11740
|
+
}
|
|
11711
11741
|
await startOneIntegration(config);
|
|
11712
11742
|
}
|
|
11713
11743
|
}
|
|
11714
|
-
async function startOneIntegration(config) {
|
|
11715
|
-
if (integrationManager.isRunning(config.id)) return;
|
|
11744
|
+
async function startOneIntegration(config, opts = {}) {
|
|
11745
|
+
if (!opts.restart && integrationManager.isRunning(config.id)) return;
|
|
11716
11746
|
const needsCreds = Object.keys(config.envKeys ?? {}).length > 0;
|
|
11717
11747
|
if (needsCreds && !integrationManager.canResolveEnvKeys(config)) {
|
|
11718
11748
|
const missing = [];
|
|
@@ -11731,7 +11761,7 @@ async function startOneIntegration(config) {
|
|
|
11731
11761
|
const manifest = getManifest(config.id);
|
|
11732
11762
|
const effectiveConfig = manifest ? { ...config, toolGating: manifest.toolGating, npmPackage: manifest.npmPackage ?? config.npmPackage } : config;
|
|
11733
11763
|
try {
|
|
11734
|
-
await integrationManager.startIntegration(effectiveConfig, { skipIfRunning:
|
|
11764
|
+
await integrationManager.startIntegration(effectiveConfig, { skipIfRunning: !opts.restart });
|
|
11735
11765
|
} catch (err) {
|
|
11736
11766
|
console.error(`[Suveren MCP] Failed to start integration ${config.id}:`, err);
|
|
11737
11767
|
}
|