Skip to content

Commit 2d7b200

Browse files
committed
fix(gateway): redact fast-path console logs
1 parent 8e8f791 commit 2d7b200

4 files changed

Lines changed: 41 additions & 3 deletions

File tree

src/cli/run-main.exit.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const runCrestodianMock = vi.hoisted(() =>
3434
const commanderParseAsyncMock = vi.hoisted(() => vi.fn(async () => {}));
3535
const addGatewayRunCommandMock = vi.hoisted(() => vi.fn((command: unknown) => command));
3636
const emitCliBannerMock = vi.hoisted(() => vi.fn());
37+
const enableConsoleCaptureMock = vi.hoisted(() => vi.fn());
3738
const progressDoneMock = vi.hoisted(() => vi.fn());
3839
const createCliProgressMock = vi.hoisted(() =>
3940
vi.fn(() => ({
@@ -95,6 +96,11 @@ vi.mock("./banner.js", () => ({
9596
emitCliBanner: emitCliBannerMock,
9697
}));
9798

99+
vi.mock("../logging.js", async () => ({
100+
...(await vi.importActual<typeof import("../logging.js")>("../logging.js")),
101+
enableConsoleCapture: enableConsoleCaptureMock,
102+
}));
103+
98104
vi.mock("./container-target.js", () => ({
99105
maybeRunCliInContainer: maybeRunCliInContainerMock,
100106
parseCliContainerArgs: (argv: string[]) => ({ ok: true, container: null, argv }),
@@ -325,6 +331,17 @@ describe("runCli exit behavior", () => {
325331
]);
326332
});
327333

334+
it("installs console capture before parsing the gateway foreground fast path", async () => {
335+
await runCli(["node", "openclaw", "gateway", "--force"]);
336+
337+
expect(enableConsoleCaptureMock).toHaveBeenCalledTimes(1);
338+
expect(commanderParseAsyncMock).toHaveBeenCalledTimes(1);
339+
const captureOrder = enableConsoleCaptureMock.mock.invocationCallOrder[0] ?? 0;
340+
const parseOrder = commanderParseAsyncMock.mock.invocationCallOrder[0] ?? 0;
341+
expect(captureOrder).toBeGreaterThan(0);
342+
expect(parseOrder).toBeGreaterThan(captureOrder);
343+
});
344+
328345
it("honors banner suppression on the gateway foreground fast path", async () => {
329346
process.env.OPENCLAW_HIDE_BANNER = "1";
330347

src/cli/run-main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,15 @@ async function tryRunGatewayRunFastPath(
150150
{ VERSION },
151151
{ emitCliBanner },
152152
{ resolveCliStartupPolicy },
153+
{ enableConsoleCapture },
153154
] = await startupTrace.measure("gateway-run-imports", () =>
154155
Promise.all([
155156
import("commander"),
156157
import("./gateway-cli/run.js"),
157158
import("../version.js"),
158159
import("./banner.js"),
159160
import("./command-startup-policy.js"),
161+
import("../logging.js"),
160162
]),
161163
);
162164
const invocation = resolveCliArgvInvocation(argv);
@@ -182,6 +184,7 @@ async function tryRunGatewayRunFastPath(
182184
addGatewayRunCommand(
183185
gateway.command("run").description("Run the WebSocket Gateway (foreground)"),
184186
);
187+
enableConsoleCapture();
185188
try {
186189
await startupTrace.measure("gateway-run-parse", () => program.parseAsync(argv));
187190
} catch (error) {

src/logging/console-capture.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
2+
import { setVerbose } from "../global-state.js";
23
import {
34
enableConsoleCapture,
45
resetLogger,
@@ -28,6 +29,7 @@ beforeEach(() => {
2829
loggingState.forceConsoleToStderr = false;
2930
loggingState.consoleTimestampPrefix = false;
3031
loggingState.rawConsole = null;
32+
setVerbose(false);
3133
resetLogger();
3234
});
3335

@@ -37,6 +39,7 @@ afterEach(() => {
3739
loggingState.forceConsoleToStderr = false;
3840
loggingState.consoleTimestampPrefix = false;
3941
loggingState.rawConsole = null;
42+
setVerbose(false);
4043
resetLogger();
4144
setLoggerOverride(null);
4245
vi.restoreAllMocks();
@@ -187,6 +190,21 @@ describe("enableConsoleCapture", () => {
187190
other.code = "EACCES";
188191
expect(() => process.stdout.emit("error", other)).toThrow("EACCES");
189192
});
193+
194+
it("suppresses libsignal session dumps even in verbose mode", () => {
195+
setLoggerOverride({ level: "info", file: tempLogPath() });
196+
const info = vi.fn();
197+
console.info = info;
198+
setVerbose(true);
199+
enableConsoleCapture();
200+
201+
console.info("Closing session:", {
202+
currentRatchet: { rootKey: Buffer.from("root-key") },
203+
privKey: "private-key",
204+
});
205+
206+
expect(info).not.toHaveBeenCalled();
207+
});
190208
});
191209

192210
function tempLogPath() {

src/logging/console.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ const SUPPRESSED_CONSOLE_PREFIXES = [
149149
] as const;
150150

151151
function shouldSuppressConsoleMessage(message: string): boolean {
152-
if (isVerbose()) {
153-
return false;
154-
}
155152
if (SUPPRESSED_CONSOLE_PREFIXES.some((prefix) => message.startsWith(prefix))) {
156153
return true;
157154
}
155+
if (isVerbose()) {
156+
return false;
157+
}
158158
return false;
159159
}
160160

0 commit comments

Comments
 (0)