From 52c7495618f18f2847b7f9468421442c1c573da1 Mon Sep 17 00:00:00 2001 From: x3M3x Date: Thu, 3 Sep 2026 23:18:54 +0400 Subject: [PATCH 1/2] fix: use portable exclusive config temp creation --- src/config/atomic-write.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/config/atomic-write.ts b/src/config/atomic-write.ts index 0ec0831c4c..69bc112146 100644 --- a/src/config/atomic-write.ts +++ b/src/config/atomic-write.ts @@ -1,7 +1,6 @@ import { chmodSync, closeSync, - constants, fchmodSync, fstatSync, lstatSync, @@ -121,7 +120,7 @@ function writePrivateTempFile( timeoutMemoKey: string, onCreated: () => void, ): void { - const descriptor = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, 0o600); + const descriptor = openSync(path, "wx", 0o600); onCreated(); try { if (process.platform === "win32") { @@ -142,7 +141,7 @@ async function writePrivateTempFileAsync( timeoutMemoKey: string, onCreated: () => void, ): Promise { - const descriptor = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, 0o600); + const descriptor = openSync(path, "wx", 0o600); onCreated(); try { if (process.platform === "win32") { From 744eb644028492784446fe9f0f73813d5d1fe59f Mon Sep 17 00:00:00 2001 From: x3M3x Date: Mon, 7 Sep 2026 15:50:47 +0400 Subject: [PATCH 2/2] test: guard atomic temp writes against Bun/Windows ENOENT --- tests/windows/windows-secret-acl.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/windows/windows-secret-acl.test.ts b/tests/windows/windows-secret-acl.test.ts index aa011bb516..079e4d187d 100644 --- a/tests/windows/windows-secret-acl.test.ts +++ b/tests/windows/windows-secret-acl.test.ts @@ -632,6 +632,18 @@ describe("icacls executable authority", () => { }); }); +describe("atomic secret temp writer portability", () => { + test("sync and async secret temp writers use Bun-portable exclusive creation", async () => { + // Bun on Windows misinterpreted the equivalent numeric O_* combination as + // ENOENT, so every pid/config/oauth temp write failed during ocx start + // and on management-API config saves. Keep both writers on the portable + // exclusive-write spelling ("wx" keeps O_EXCL; 0o600 keeps the private + // mode) so the O_CREAT bit can never be dropped again. + const src = readFileSync(repoPath("src", "config", "atomic-write.ts"), "utf8"); + expect(src.match(/openSync\(path, "wx", 0o600\)/g)).toHaveLength(2); + }); +}); + describe("diagnostics sanitization contract", () => { test("HardenResult diagnostics field is a plain string when present", () => { const filePath = join(testDir, "diag-test.json");