fix(cron): enforce dir perms and gate posix tests on windows

This commit is contained in:
linhey 2026-03-06 08:45:36 +08:00
parent 15b64d6f77
commit 42dd1b9643
4 changed files with 36 additions and 26 deletions

View File

@ -95,21 +95,24 @@ describe("cron run log", () => {
});
});
it("writes run log files with secure permissions", async () => {
await withRunLogDir("openclaw-cron-log-perms-", async (dir) => {
const logPath = path.join(dir, "runs", "job-1.jsonl");
it.skipIf(process.platform === "win32")(
"writes run log files with secure permissions",
async () => {
await withRunLogDir("openclaw-cron-log-perms-", async (dir) => {
const logPath = path.join(dir, "runs", "job-1.jsonl");
await appendCronRunLog(logPath, {
ts: 1,
jobId: "job-1",
action: "finished",
status: "ok",
await appendCronRunLog(logPath, {
ts: 1,
jobId: "job-1",
action: "finished",
status: "ok",
});
const mode = (await fs.stat(logPath)).mode & 0o777;
expect(mode).toBe(0o600);
});
const mode = (await fs.stat(logPath)).mode & 0o777;
expect(mode).toBe(0o600);
});
});
},
);
it("reads newest entries and filters by jobId", async () => {
await withRunLogDir("openclaw-cron-log-read-", async (dir) => {

View File

@ -145,7 +145,9 @@ export async function appendCronRunLog(
const next = prev
.catch(() => undefined)
.then(async () => {
await fs.mkdir(path.dirname(resolved), { recursive: true, mode: 0o700 });
const runDir = path.dirname(resolved);
await fs.mkdir(runDir, { recursive: true, mode: 0o700 });
await fs.chmod(runDir, 0o700).catch(() => undefined);
await fs.appendFile(resolved, `${JSON.stringify(entry)}\n`, {
encoding: "utf-8",
mode: 0o600,

View File

@ -80,20 +80,23 @@ describe("cron store", () => {
expect(JSON.parse(backupRaw)).toEqual(first);
});
it("writes store and backup files with secure permissions", async () => {
const store = await makeStorePath();
const first = makeStore("job-1", true);
const second = makeStore("job-2", false);
it.skipIf(process.platform === "win32")(
"writes store and backup files with secure permissions",
async () => {
const store = await makeStorePath();
const first = makeStore("job-1", true);
const second = makeStore("job-2", false);
await saveCronStore(store.storePath, first);
await saveCronStore(store.storePath, second);
await saveCronStore(store.storePath, first);
await saveCronStore(store.storePath, second);
const storeMode = (await fs.stat(store.storePath)).mode & 0o777;
const backupMode = (await fs.stat(`${store.storePath}.bak`)).mode & 0o777;
const storeMode = (await fs.stat(store.storePath)).mode & 0o777;
const backupMode = (await fs.stat(`${store.storePath}.bak`)).mode & 0o777;
expect(storeMode).toBe(0o600);
expect(backupMode).toBe(0o600);
});
expect(storeMode).toBe(0o600);
expect(backupMode).toBe(0o600);
},
);
});
describe("saveCronStore", () => {

View File

@ -65,7 +65,9 @@ export async function saveCronStore(
store: CronStoreFile,
opts?: SaveCronStoreOptions,
) {
await fs.promises.mkdir(path.dirname(storePath), { recursive: true, mode: 0o700 });
const storeDir = path.dirname(storePath);
await fs.promises.mkdir(storeDir, { recursive: true, mode: 0o700 });
await fs.promises.chmod(storeDir, 0o700).catch(() => undefined);
const json = JSON.stringify(store, null, 2);
const cached = serializedStoreCache.get(storePath);
if (cached === json) {