mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 23:00:43 +00:00
* fix(logging): redact gmail watcher startup args * fix(logging): normalize redaction formatting * fix(logging): harden gmail watcher log redaction * fix(logging): honor configured log tail redaction * fix(logging): skip redact pattern resolution when off * fix(logging): reuse compiled redact regexes * chore: untrack USER.md (covered by .gitignore) * chore: untrack USER.md (covered by .gitignore) * fix(logging): avoid double-resolution in log-tail redaction * fix(logging): redact across line boundaries for multiline patterns * fix(logging): guard redactSensitiveLines against empty input * chore(changelog): add Gmail watcher log redaction entry --------- Co-authored-by: Devin Robison <drobison@nvidia.com>
57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { resetLogger, setLoggerOverride } from "../logging.js";
|
|
|
|
const resolvedRedaction = { mode: "tools" as const, patterns: [/custom-secret-[a-z]+/g] };
|
|
|
|
const { redactSensitiveLinesMock, resolveRedactOptionsMock } = vi.hoisted(() => ({
|
|
redactSensitiveLinesMock: vi.fn((lines: string[], options?: unknown) =>
|
|
options === resolvedRedaction
|
|
? lines.map((line) => line.replace("custom-secret-abcdefghijklmnopqrstuvwxyz", "custom…wxyz"))
|
|
: lines,
|
|
),
|
|
resolveRedactOptionsMock: vi.fn(() => resolvedRedaction),
|
|
}));
|
|
|
|
vi.mock("./redact.js", async () => {
|
|
const actual = await vi.importActual<typeof import("./redact.js")>("./redact.js");
|
|
return {
|
|
...actual,
|
|
redactSensitiveLines: (lines: string[], options?: unknown) =>
|
|
redactSensitiveLinesMock(lines, options),
|
|
resolveRedactOptions: () => resolveRedactOptionsMock(),
|
|
};
|
|
});
|
|
|
|
describe("readConfiguredLogTail", () => {
|
|
afterEach(() => {
|
|
resolveRedactOptionsMock.mockClear();
|
|
redactSensitiveLinesMock.mockClear();
|
|
resetLogger();
|
|
setLoggerOverride(null);
|
|
});
|
|
|
|
it("applies redaction once per request across all returned lines", async () => {
|
|
const { readConfiguredLogTail } = await import("./log-tail.js");
|
|
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-log-tail-"));
|
|
const file = path.join(tempDir, "openclaw-2026-01-22.log");
|
|
|
|
await fs.writeFile(file, "custom-secret-abcdefghijklmnopqrstuvwxyz\nsecond line\n");
|
|
setLoggerOverride({ file });
|
|
|
|
const result = await readConfiguredLogTail();
|
|
|
|
expect(resolveRedactOptionsMock).toHaveBeenCalledTimes(1);
|
|
expect(redactSensitiveLinesMock).toHaveBeenCalledTimes(1);
|
|
expect(redactSensitiveLinesMock).toHaveBeenCalledWith(
|
|
["custom-secret-abcdefghijklmnopqrstuvwxyz", "second line"],
|
|
resolvedRedaction,
|
|
);
|
|
expect(result.lines).toEqual(["custom…wxyz", "second line"]);
|
|
|
|
await fs.rm(tempDir, { recursive: true, force: true });
|
|
});
|
|
});
|