diff --git a/lib/admin/settings.ts b/lib/admin/settings.ts index f2ecce40..7b168ef4 100644 --- a/lib/admin/settings.ts +++ b/lib/admin/settings.ts @@ -125,7 +125,12 @@ let writableCache: boolean | null = null export function isSettingsWritable(): boolean { if (writableCache !== null) return writableCache try { - const dir = path.dirname(getSettingsPath()) + const filePath = getSettingsPath() + if (fs.existsSync(filePath) && !fs.statSync(filePath).isFile()) { + writableCache = false + return writableCache + } + const dir = path.dirname(filePath) fs.mkdirSync(dir, { recursive: true }) fs.accessSync(dir, fs.constants.W_OK) writableCache = true diff --git a/tests/unit/admin-settings.test.ts b/tests/unit/admin-settings.test.ts index c9fe084f..c07e9808 100644 --- a/tests/unit/admin-settings.test.ts +++ b/tests/unit/admin-settings.test.ts @@ -154,9 +154,9 @@ describe("isSettingsWritable", () => { expect(isSettingsWritable()).toBe(true) }) - it("returns false for an unwritable path", () => { + it("returns false when the settings path is a directory", () => { _resetForTests() - process.env.SETTINGS_FILE = "/nonexistent-root-dir/settings.json" + process.env.SETTINGS_FILE = tmpDir expect(isSettingsWritable()).toBe(false) }) }) @@ -170,7 +170,9 @@ describe("settings file on disk", () => { version: 1, values: { TEST_ADMIN_VAR: "secret" }, }) - const mode = fs.statSync(filePath).mode & 0o777 - expect(mode).toBe(0o600) + if (process.platform !== "win32") { + const mode = fs.statSync(filePath).mode & 0o777 + expect(mode).toBe(0o600) + } }) })