neuralos 3.7.7 → 3.8.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/bin/gybackend.cjs +181 -55
- package/package.json +1 -1
package/bin/gybackend.cjs
CHANGED
|
@@ -296501,6 +296501,8 @@ var PSRPTransport = class {
|
|
|
296501
296501
|
/** pypsrp WSMan.session_id — one uuid for the life of the transport. */
|
|
296502
296502
|
sessionId = `uuid:${(0, import_node_crypto3.randomUUID)().toUpperCase()}`;
|
|
296503
296503
|
http;
|
|
296504
|
+
/** Persistent runspace (v3.8.0): reuse one Microsoft.PowerShell shell across commands. */
|
|
296505
|
+
pool = null;
|
|
296504
296506
|
constructor(opts) {
|
|
296505
296507
|
this.http = new WinHttpAuth({
|
|
296506
296508
|
host: opts.host,
|
|
@@ -296524,6 +296526,7 @@ var PSRPTransport = class {
|
|
|
296524
296526
|
const wsmv = "http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd";
|
|
296525
296527
|
return `<s:Envelope xmlns:s="${NS2.s}" xmlns:wsa="${NS2.a}" xmlns:wsman="${NS2.w}" xmlns:wsmv="${wsmv}" xmlns:rsp="${NS2.rsp}" xml:lang="en-US"><s:Header><wsa:Action s:mustUnderstand="true">${action}</wsa:Action><wsmv:DataLocale s:mustUnderstand="false" xml:lang="en-US" /><wsman:Locale s:mustUnderstand="false" xml:lang="en-US" /><wsman:MaxEnvelopeSize s:mustUnderstand="true">512000</wsman:MaxEnvelopeSize><wsa:MessageID>${mid}</wsa:MessageID><wsman:OperationTimeout>PT60.000S</wsman:OperationTimeout><wsa:ReplyTo><wsa:Address s:mustUnderstand="true">${NS2.a}/role/anonymous</wsa:Address></wsa:ReplyTo><wsman:ResourceURI s:mustUnderstand="true">${PSRP_SHELL_URI}</wsman:ResourceURI><wsmv:SessionId s:mustUnderstand="false">${this.sessionId}</wsmv:SessionId><wsa:To>${to}</wsa:To>${extraHeaders}</s:Header><s:Body>${body}</s:Body></s:Envelope>`;
|
|
296526
296528
|
}
|
|
296529
|
+
/** Test hook: subclasses may override. */
|
|
296527
296530
|
async post(action, body, extraHeaders) {
|
|
296528
296531
|
const envelope = this.envelope(action, body, extraHeaders);
|
|
296529
296532
|
const res = await this.http.post(envelope);
|
|
@@ -296537,6 +296540,57 @@ var PSRPTransport = class {
|
|
|
296537
296540
|
* Receive loop (PIPELINE_OUTPUT / ERROR_RECORD / PIPELINE_STATE) → Delete.
|
|
296538
296541
|
* The script travels inside the PSRP message body — no command-line length limit.
|
|
296539
296542
|
*/
|
|
296543
|
+
/** Open (or return) a persistent runspace pool. */
|
|
296544
|
+
async ensurePool(opts) {
|
|
296545
|
+
if (this.pool) return { shellId: this.pool.shellId, rpid: this.pool.rpid };
|
|
296546
|
+
const deadline = Date.now() + (opts?.timeoutMs ?? 12e4);
|
|
296547
|
+
const rpid = (0, import_node_crypto3.randomUUID)().toUpperCase();
|
|
296548
|
+
const creation = fragmentMessages([
|
|
296549
|
+
psrpMessage(MSG.SESSION_CAPABILITY, rpid, "00000000-0000-0000-0000-000000000000", sessionCapabilityXml()),
|
|
296550
|
+
psrpMessage(MSG.INIT_RUNSPACEPOOL, rpid, "00000000-0000-0000-0000-000000000000", initRunspacePoolXml())
|
|
296551
|
+
], 1);
|
|
296552
|
+
const createBody = `<rsp:Shell ShellId="${rpid}"><rsp:InputStreams>stdin pr</rsp:InputStreams><rsp:OutputStreams>stdout</rsp:OutputStreams><creationXml xmlns="http://schemas.microsoft.com/powershell">` + creation.blob.toString("base64") + `</creationXml></rsp:Shell>`;
|
|
296553
|
+
const createHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option MustComply="true" Name="protocolversion">2.3</wsman:Option></wsman:OptionSet>`;
|
|
296554
|
+
const created = await this.post(
|
|
296555
|
+
"http://schemas.xmlsoap.org/ws/2004/09/transfer/Create",
|
|
296556
|
+
createBody,
|
|
296557
|
+
createHeaders
|
|
296558
|
+
);
|
|
296559
|
+
this.assertOk(created, "Create");
|
|
296560
|
+
const shellId = extractShellId2(created.body);
|
|
296561
|
+
if (!shellId) throw new Error("PSRP Create succeeded but no ShellId returned.");
|
|
296562
|
+
await this.waitForRunspaceOpened(shellId, deadline, opts?.signal);
|
|
296563
|
+
this.pool = { shellId, rpid, nextObjectId: creation.nextObjectId };
|
|
296564
|
+
return { shellId, rpid };
|
|
296565
|
+
}
|
|
296566
|
+
async closePool() {
|
|
296567
|
+
const p = this.pool;
|
|
296568
|
+
this.pool = null;
|
|
296569
|
+
if (p) await this.deleteShell(p.shellId);
|
|
296570
|
+
}
|
|
296571
|
+
/**
|
|
296572
|
+
* Run a script on the persistent pool (opens one if needed). Does NOT delete
|
|
296573
|
+
* the shell — call closePool() when the tab dies.
|
|
296574
|
+
*/
|
|
296575
|
+
async runScriptOnPool(script, opts) {
|
|
296576
|
+
const deadline = Date.now() + (opts?.timeoutMs ?? 12e4);
|
|
296577
|
+
const pool = await this.ensurePool(opts);
|
|
296578
|
+
const pipelineId = (0, import_node_crypto3.randomUUID)().toUpperCase();
|
|
296579
|
+
const createPipelineMsg = psrpMessage(MSG.CREATE_PIPELINE, pool.rpid, pipelineId, createPipelineXml(script));
|
|
296580
|
+
const frag = fragmentMessages([createPipelineMsg], this.pool.nextObjectId);
|
|
296581
|
+
this.pool.nextObjectId = frag.nextObjectId;
|
|
296582
|
+
const commandBody = `<rsp:CommandLine CommandId="${pipelineId}"><rsp:Command></rsp:Command><rsp:Arguments>${frag.blob.toString("base64")}</rsp:Arguments></rsp:CommandLine>`;
|
|
296583
|
+
const commandHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WINRS_SKIP_CMD_SHELL">False</wsman:Option></wsman:OptionSet>` + this.shellHeaders(pool.shellId);
|
|
296584
|
+
const commanded = await this.post(
|
|
296585
|
+
"http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command",
|
|
296586
|
+
commandBody,
|
|
296587
|
+
commandHeaders
|
|
296588
|
+
);
|
|
296589
|
+
this.assertOk(commanded, "Command");
|
|
296590
|
+
const commandId = firstText2(commanded.body, "CommandId");
|
|
296591
|
+
if (!commandId) throw new Error("PSRP Command succeeded but no CommandId returned.");
|
|
296592
|
+
return this.receivePipeline(pool.shellId, commandId, deadline, opts);
|
|
296593
|
+
}
|
|
296540
296594
|
async runScript(script, opts) {
|
|
296541
296595
|
const deadline = Date.now() + (opts?.timeoutMs ?? 12e4);
|
|
296542
296596
|
const rpid = (0, import_node_crypto3.randomUUID)().toUpperCase();
|
|
@@ -296569,63 +296623,76 @@ var PSRPTransport = class {
|
|
|
296569
296623
|
this.assertOk(commanded, "Command");
|
|
296570
296624
|
const commandId = firstText2(commanded.body, "CommandId");
|
|
296571
296625
|
if (!commandId) throw new Error("PSRP Command succeeded but no CommandId returned.");
|
|
296572
|
-
|
|
296573
|
-
let stderr = "";
|
|
296574
|
-
let hadErrors = false;
|
|
296575
|
-
let exitCode = 0;
|
|
296576
|
-
let pipelineDone = false;
|
|
296577
|
-
for (; ; ) {
|
|
296578
|
-
if (opts?.signal?.aborted) throw new Error("AbortError");
|
|
296579
|
-
if (Date.now() > deadline) {
|
|
296580
|
-
throw new Error(`PSRP command timed out after ${opts?.timeoutMs ?? 12e4}ms`);
|
|
296581
|
-
}
|
|
296582
|
-
const receiveBody = `<rsp:Receive><rsp:DesiredStream CommandId="${commandId}">stdout</rsp:DesiredStream></rsp:Receive>`;
|
|
296583
|
-
const receiveHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WSMAN_CMDSHELL_OPTION_KEEPALIVE">True</wsman:Option></wsman:OptionSet>` + this.shellHeaders(shellId);
|
|
296584
|
-
const received = await this.post(
|
|
296585
|
-
"http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive",
|
|
296586
|
-
receiveBody,
|
|
296587
|
-
receiveHeaders
|
|
296588
|
-
);
|
|
296589
|
-
this.assertOk(received, "Receive");
|
|
296590
|
-
const streamRe = /<\w*:?Stream\b[^>]*\bName="(?:stdout|stderr|pr)"[^>]*>([\s\S]*?)<\/\w*:?Stream>/gi;
|
|
296591
|
-
let m2;
|
|
296592
|
-
while ((m2 = streamRe.exec(received.body)) !== null) {
|
|
296593
|
-
const b64 = m2[1].replace(/\s+/g, "");
|
|
296594
|
-
if (!b64) continue;
|
|
296595
|
-
for (const raw of unfragmentMessages(import_node_buffer2.Buffer.from(b64, "base64"))) {
|
|
296596
|
-
if (raw.length < 40) continue;
|
|
296597
|
-
const messageType = raw.readUInt32LE(4);
|
|
296598
|
-
const payload = raw.subarray(40).toString("utf8").replace(/^\uFEFF/, "");
|
|
296599
|
-
if (messageType === MSG.PIPELINE_OUTPUT) {
|
|
296600
|
-
const sRe = /<S[^>]*>([\s\S]*?)<\/S>/gi;
|
|
296601
|
-
let sm;
|
|
296602
|
-
while ((sm = sRe.exec(payload)) !== null) stdout += sm[1];
|
|
296603
|
-
} else if (messageType === MSG.ERROR_RECORD) {
|
|
296604
|
-
hadErrors = true;
|
|
296605
|
-
const mRe = payload.match(/<S N="Message">([\s\S]*?)<\/S>/i);
|
|
296606
|
-
stderr += (mRe ? mRe[1] : payload) + "\n";
|
|
296607
|
-
} else if (messageType === MSG.PIPELINE_STATE) {
|
|
296608
|
-
pipelineDone = true;
|
|
296609
|
-
const stateMatch = payload.match(/<I32 N="State">(\d+)<\/I32>/i);
|
|
296610
|
-
if (stateMatch) {
|
|
296611
|
-
if (parseInt(stateMatch[1], 10) === 5) hadErrors = true;
|
|
296612
|
-
}
|
|
296613
|
-
const ec = payload.match(/N="ExitCode"[^>]*>(-?\d+)</i);
|
|
296614
|
-
if (ec) exitCode = parseInt(ec[1], 10);
|
|
296615
|
-
}
|
|
296616
|
-
}
|
|
296617
|
-
}
|
|
296618
|
-
const wsExit = received.body.match(/<\w*:?ExitCode>\s*(-?\d+)\s*<\/\w*:?ExitCode>/i);
|
|
296619
|
-
if (wsExit) exitCode = parseInt(wsExit[1], 10);
|
|
296620
|
-
if (pipelineDone) break;
|
|
296621
|
-
if (/CommandState\/Done/i.test(received.body)) break;
|
|
296622
|
-
}
|
|
296623
|
-
if (exitCode !== 0) hadErrors = true;
|
|
296624
|
-
return { stdout, stderr, exitCode, hadErrors };
|
|
296626
|
+
return await this.receivePipeline(shellId, commandId, deadline, opts);
|
|
296625
296627
|
} finally {
|
|
296626
296628
|
await this.deleteShell(shellId);
|
|
296627
296629
|
}
|
|
296628
296630
|
}
|
|
296631
|
+
async receivePipeline(shellId, commandId, deadline, opts) {
|
|
296632
|
+
let stdout = "";
|
|
296633
|
+
let stderr = "";
|
|
296634
|
+
let hadErrors = false;
|
|
296635
|
+
let exitCode = 0;
|
|
296636
|
+
let pipelineDone = false;
|
|
296637
|
+
for (; ; ) {
|
|
296638
|
+
if (opts?.signal?.aborted) throw new Error("AbortError");
|
|
296639
|
+
if (Date.now() > deadline) {
|
|
296640
|
+
throw new Error(`PSRP command timed out after ${opts?.timeoutMs ?? 12e4}ms`);
|
|
296641
|
+
}
|
|
296642
|
+
const receiveBody = `<rsp:Receive><rsp:DesiredStream CommandId="${commandId}">stdout</rsp:DesiredStream></rsp:Receive>`;
|
|
296643
|
+
const receiveHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WSMAN_CMDSHELL_OPTION_KEEPALIVE">True</wsman:Option></wsman:OptionSet>` + this.shellHeaders(shellId);
|
|
296644
|
+
const received = await this.post(
|
|
296645
|
+
"http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive",
|
|
296646
|
+
receiveBody,
|
|
296647
|
+
receiveHeaders
|
|
296648
|
+
);
|
|
296649
|
+
this.assertOk(received, "Receive");
|
|
296650
|
+
const streamRe = /<\w*:?Stream\b[^>]*\bName="(?:stdout|stderr|pr)"[^>]*>([\s\S]*?)<\/\w*:?Stream>/gi;
|
|
296651
|
+
let m2;
|
|
296652
|
+
while ((m2 = streamRe.exec(received.body)) !== null) {
|
|
296653
|
+
const b64 = m2[1].replace(/\s+/g, "");
|
|
296654
|
+
if (!b64) continue;
|
|
296655
|
+
for (const raw of unfragmentMessages(import_node_buffer2.Buffer.from(b64, "base64"))) {
|
|
296656
|
+
if (raw.length < 40) continue;
|
|
296657
|
+
const messageType = raw.readUInt32LE(4);
|
|
296658
|
+
const payload = raw.subarray(40).toString("utf8").replace(/^\uFEFF/, "");
|
|
296659
|
+
if (messageType === MSG.PIPELINE_OUTPUT) {
|
|
296660
|
+
const sRe = /<S[^>]*>([\s\S]*?)<\/S>/gi;
|
|
296661
|
+
let sm;
|
|
296662
|
+
let extracted = false;
|
|
296663
|
+
while ((sm = sRe.exec(payload)) !== null) {
|
|
296664
|
+
stdout += sm[1];
|
|
296665
|
+
extracted = true;
|
|
296666
|
+
}
|
|
296667
|
+
if (!extracted) {
|
|
296668
|
+
const nRe = /<(?:I32|I64|B|ToString)[^>]*>([\s\S]*?)<\/(?:I32|I64|B|ToString)>/i;
|
|
296669
|
+
const nm = payload.match(nRe);
|
|
296670
|
+
if (nm) stdout += nm[1];
|
|
296671
|
+
else stdout += payload.replace(/<[^>]+>/g, "").trim();
|
|
296672
|
+
}
|
|
296673
|
+
} else if (messageType === MSG.ERROR_RECORD) {
|
|
296674
|
+
hadErrors = true;
|
|
296675
|
+
const mRe = payload.match(/<S N="Message">([\s\S]*?)<\/S>/i);
|
|
296676
|
+
stderr += (mRe ? mRe[1] : payload) + "\n";
|
|
296677
|
+
} else if (messageType === MSG.PIPELINE_STATE) {
|
|
296678
|
+
pipelineDone = true;
|
|
296679
|
+
const stateMatch = payload.match(/<I32 N="State">(\d+)<\/I32>/i);
|
|
296680
|
+
if (stateMatch) {
|
|
296681
|
+
if (parseInt(stateMatch[1], 10) === 5) hadErrors = true;
|
|
296682
|
+
}
|
|
296683
|
+
const ec = payload.match(/N="ExitCode"[^>]*>(-?\d+)</i);
|
|
296684
|
+
if (ec) exitCode = parseInt(ec[1], 10);
|
|
296685
|
+
}
|
|
296686
|
+
}
|
|
296687
|
+
}
|
|
296688
|
+
const wsExit = received.body.match(/<\w*:?ExitCode>\s*(-?\d+)\s*<\/\w*:?ExitCode>/i);
|
|
296689
|
+
if (wsExit) exitCode = parseInt(wsExit[1], 10);
|
|
296690
|
+
if (pipelineDone) break;
|
|
296691
|
+
if (/CommandState\/Done/i.test(received.body)) break;
|
|
296692
|
+
}
|
|
296693
|
+
if (exitCode !== 0) hadErrors = true;
|
|
296694
|
+
return { stdout, stderr, exitCode, hadErrors };
|
|
296695
|
+
}
|
|
296629
296696
|
/**
|
|
296630
296697
|
* Drain Receive until RUNSPACEPOOL_STATE reports Opened (state=2).
|
|
296631
296698
|
* Must run after Create and before Command.
|
|
@@ -296830,7 +296897,7 @@ Run commands with exec_command / run_fleet_command. Interactive TUI apps are not
|
|
|
296830
296897
|
\x1B[36m\u276F ${command}\x1B[0m\r
|
|
296831
296898
|
`);
|
|
296832
296899
|
const ps = this.translateCmdToPowerShell(command, instance.cwd);
|
|
296833
|
-
const result = await transport.
|
|
296900
|
+
const result = await transport.runScriptOnPool(ps, {
|
|
296834
296901
|
timeoutMs: options?.timeoutMs ?? DEFAULT_WINRM_TIMEOUT_MS,
|
|
296835
296902
|
signal: options?.signal
|
|
296836
296903
|
});
|
|
@@ -296951,6 +297018,9 @@ Run commands with exec_command / run_fleet_command. Interactive TUI apps are not
|
|
|
296951
297018
|
void instance.winrm.deleteShell(instance.persistentShellId);
|
|
296952
297019
|
instance.persistentShellId = void 0;
|
|
296953
297020
|
}
|
|
297021
|
+
if (instance.psrp) {
|
|
297022
|
+
void instance.psrp.closePool();
|
|
297023
|
+
}
|
|
296954
297024
|
instance.exitCallback?.(0);
|
|
296955
297025
|
}
|
|
296956
297026
|
onData(ptyId, callback) {
|
|
@@ -345290,6 +345360,28 @@ var MessagesZodState = external_exports.object({ messages: withLangGraph(externa
|
|
|
345290
345360
|
// ../../node_modules/@langchain/langgraph/dist/index.js
|
|
345291
345361
|
initializeAsyncLocalStorageSingleton();
|
|
345292
345362
|
|
|
345363
|
+
// ../../packages/backend/src/services/redaction/secretRedact.ts
|
|
345364
|
+
var PATTERNS = [
|
|
345365
|
+
{ re: /\b(gys_at_[A-Za-z0-9_-]{16,})\b/g, label: "RTERM_TOKEN" },
|
|
345366
|
+
{ re: /\b(ghp_[A-Za-z0-9]{20,})\b/g, label: "GITHUB_PAT" },
|
|
345367
|
+
{ re: /\b(sk-[A-Za-z0-9_-]{20,})\b/g, label: "API_KEY" },
|
|
345368
|
+
{ re: /\b(AKIA[0-9A-Z]{16})\b/g, label: "AWS_KEY" },
|
|
345369
|
+
{ re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, label: "PRIVATE_KEY" },
|
|
345370
|
+
{ re: /(password|passwd|pwd|secret|token)\s*[:=]\s*["']?([^\s"']{6,})/gi, label: "CREDENTIAL" }
|
|
345371
|
+
];
|
|
345372
|
+
function redactText(input, extraValues = []) {
|
|
345373
|
+
let out = String(input ?? "");
|
|
345374
|
+
for (const v of extraValues) {
|
|
345375
|
+
const t = String(v || "");
|
|
345376
|
+
if (t.length < 4) continue;
|
|
345377
|
+
out = out.split(t).join(`[REDACTED]`);
|
|
345378
|
+
}
|
|
345379
|
+
for (const p of PATTERNS) {
|
|
345380
|
+
out = out.replace(p.re, `[REDACTED:${p.label}]`);
|
|
345381
|
+
}
|
|
345382
|
+
return out;
|
|
345383
|
+
}
|
|
345384
|
+
|
|
345293
345385
|
// ../../packages/backend/src/services/agentRunLedger.ts
|
|
345294
345386
|
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
345295
345387
|
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
@@ -366967,7 +367059,7 @@ function reconcileToolCalls(toolCalls) {
|
|
|
366967
367059
|
var TOOL_RESULT_MAX_CHARS = 32768;
|
|
366968
367060
|
function stringifyToolResult(result) {
|
|
366969
367061
|
const raw = typeof result === "string" ? result : JSON.stringify(result);
|
|
366970
|
-
return clipTextMiddle(raw, TOOL_RESULT_MAX_CHARS);
|
|
367062
|
+
return redactText(clipTextMiddle(raw, TOOL_RESULT_MAX_CHARS));
|
|
366971
367063
|
}
|
|
366972
367064
|
function clipTextMiddle(input, maxChars) {
|
|
366973
367065
|
if (maxChars <= 0) return "";
|
|
@@ -373029,6 +373121,26 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
373029
373121
|
|
|
373030
373122
|
// ../../packages/backend/src/services/Gateway/WebSocketGatewayAdapter.ts
|
|
373031
373123
|
var import_node_module4 = require("node:module");
|
|
373124
|
+
|
|
373125
|
+
// ../../packages/backend/src/services/security/tokenScopes.ts
|
|
373126
|
+
var SCOPE_FULL = "*";
|
|
373127
|
+
function methodAllowed(method, scopes) {
|
|
373128
|
+
if (!scopes || scopes.length === 0) return true;
|
|
373129
|
+
if (scopes.includes(SCOPE_FULL)) return true;
|
|
373130
|
+
const m2 = String(method || "");
|
|
373131
|
+
for (const s of scopes) {
|
|
373132
|
+
if (s === m2) return true;
|
|
373133
|
+
if (s.endsWith(":*")) {
|
|
373134
|
+
const prefix = s.slice(0, -1);
|
|
373135
|
+
if (m2.startsWith(prefix)) return true;
|
|
373136
|
+
if (prefix === "terminals:" && m2.startsWith("terminal:")) return true;
|
|
373137
|
+
}
|
|
373138
|
+
if (s.endsWith("*") && m2.startsWith(s.slice(0, -1))) return true;
|
|
373139
|
+
}
|
|
373140
|
+
return false;
|
|
373141
|
+
}
|
|
373142
|
+
|
|
373143
|
+
// ../../packages/backend/src/services/Gateway/WebSocketGatewayAdapter.ts
|
|
373032
373144
|
var import_meta7 = {};
|
|
373033
373145
|
var nodeRequire = (0, import_node_module4.createRequire)(
|
|
373034
373146
|
typeof __filename !== "undefined" ? __filename : import_meta7.url
|
|
@@ -373133,6 +373245,7 @@ var WebSocketGatewayAdapter = class {
|
|
|
373133
373245
|
server = null;
|
|
373134
373246
|
transportIdBySocket = /* @__PURE__ */ new Map();
|
|
373135
373247
|
isSameMachineBySocket = /* @__PURE__ */ new WeakMap();
|
|
373248
|
+
scopesBySocket = /* @__PURE__ */ new WeakMap();
|
|
373136
373249
|
serverFactory;
|
|
373137
373250
|
logger;
|
|
373138
373251
|
start() {
|
|
@@ -373230,6 +373343,12 @@ var WebSocketGatewayAdapter = class {
|
|
|
373230
373343
|
this.isLoopbackAddress(String(remote))
|
|
373231
373344
|
);
|
|
373232
373345
|
this.gateway.registerTransport(transport);
|
|
373346
|
+
const token = this.extractAccessToken(request);
|
|
373347
|
+
const scopeFn = this.options.accessTokenAuth?.scopesForToken;
|
|
373348
|
+
if (token && scopeFn) {
|
|
373349
|
+
const scopes = await scopeFn(token);
|
|
373350
|
+
if (scopes && scopes.length) this.scopesBySocket.set(socket, scopes);
|
|
373351
|
+
}
|
|
373233
373352
|
state.authorized = true;
|
|
373234
373353
|
this.logger.info(
|
|
373235
373354
|
`[WebSocketGatewayAdapter] Client connected: ${remote} (${transport.id})`
|
|
@@ -373527,6 +373646,13 @@ var WebSocketGatewayAdapter = class {
|
|
|
373527
373646
|
);
|
|
373528
373647
|
}
|
|
373529
373648
|
async executeRequest(request, socket) {
|
|
373649
|
+
const scopes = this.scopesBySocket.get(socket);
|
|
373650
|
+
if (scopes && !methodAllowed(request.method, scopes)) {
|
|
373651
|
+
throw new WebSocketRpcError(
|
|
373652
|
+
"FORBIDDEN",
|
|
373653
|
+
`Token is not allowed to call ${request.method}`
|
|
373654
|
+
);
|
|
373655
|
+
}
|
|
373530
373656
|
const params = request.params ?? {};
|
|
373531
373657
|
if (request.method.startsWith("observability:")) {
|
|
373532
373658
|
const bridge = this.options.observabilityBridge;
|