





























@@ -671,4 +671,63 @@ describe("config io audit helpers", () => {
671671expect(after).toContain("xoxb-real-bot-token");
672672expect(fs.existsSync(`${auditPath}.scrub.tmp`)).toBe(false);
673673});
674+675+it("aborts without overwriting when the audit log is appended to after temp write", async () => {
676+const home = await suiteRootTracker.make("scrub-race-after-temp-write");
677+const auditPath = path.join(home, ".openclaw", "logs", "config-audit.jsonl");
678+fs.mkdirSync(path.dirname(auditPath), { recursive: true, mode: 0o700 });
679+const unredacted = {
680+ts: "2026-05-02T00:03:48.471Z",
681+argv: [
682+"node",
683+"openclaw.mjs",
684+"config",
685+"set",
686+"channels.slack.botToken",
687+"xoxb-real-bot-token-1234567890abcdef0123456789abcdef",
688+],
689+execArgv: [],
690+};
691+const appended = {
692+ts: "2026-05-02T00:04:00.000Z",
693+argv: ["node", "openclaw.mjs", "config", "set", "theme", "dark"],
694+execArgv: [],
695+};
696+const original = `${JSON.stringify(unredacted)}\n`;
697+const appendedLine = `${JSON.stringify(appended)}\n`;
698+fs.writeFileSync(auditPath, original, { encoding: "utf-8", mode: 0o600 });
699+let renameCalled = false;
700+701+const raceFs = {
702+promises: {
703+readFile: fsPromises.readFile,
704+stat: fsPromises.stat,
705+writeFile: async (
706+p: string,
707+data: string,
708+options?: { encoding?: BufferEncoding; mode?: number },
709+) => {
710+await fsPromises.writeFile(p, data, options);
711+await fsPromises.appendFile(auditPath, appendedLine, "utf-8");
712+},
713+rename: async () => {
714+renameCalled = true;
715+},
716+unlink: fsPromises.unlink,
717+},
718+};
719+const result = await scrubConfigAuditLog({
720+fs: raceFs,
721+env: {} as NodeJS.ProcessEnv,
722+homedir: () => home,
723+});
724+725+expect(result.aborted).toBe(true);
726+expect(result.rewritten).toBeGreaterThan(0);
727+expect(renameCalled).toBe(false);
728+const after = fs.readFileSync(auditPath, "utf-8");
729+expect(after).toBe(`${original}${appendedLine}`);
730+expect(after).toContain("xoxb-real-bot-token");
731+expect(fs.existsSync(`${auditPath}.scrub.tmp`)).toBe(false);
732+});
674733});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。