Media: respect umask and clean failed downloads

This commit is contained in:
Val Alexander
2026-03-27 08:46:09 -05:00
committed by Val Alexander
parent 206c29514c
commit bb932beeac
2 changed files with 9 additions and 13 deletions

View File

@@ -90,7 +90,7 @@ describe("media store redirects", () => {
expect(path.extname(saved.path)).toBe(".txt");
expect(await fs.readFile(saved.path, "utf8")).toBe("redirected");
const stat = await fs.stat(saved.path);
const expectedMode = process.platform === "win32" ? 0o666 : 0o644;
const expectedMode = process.platform === "win32" ? 0o666 : 0o644 & ~process.umask();
expect(stat.mode & 0o777).toBe(expectedMode);
});

View File

@@ -229,8 +229,7 @@ async function downloadToFile(
}
});
pipeline(res, out)
.then(async () => {
await enforceMediaFileMode(dest);
.then(() => {
const sniffBuffer = Buffer.concat(sniffChunks, Math.min(sniffLen, 16384));
const rawHeader = res.headers["content-type"];
const headerMime = Array.isArray(rawHeader) ? rawHeader[0] : rawHeader;
@@ -240,7 +239,10 @@ async function downloadToFile(
size: total,
});
})
.catch(reject);
.catch(async (err) => {
await fs.rm(dest, { force: true }).catch(() => {});
reject(err);
});
});
req.on("error", reject);
req.end();
@@ -286,20 +288,15 @@ function buildSavedMediaResult(params: {
};
}
async function enforceMediaFileMode(filePath: string): Promise<void> {
await fs.chmod(filePath, MEDIA_FILE_MODE);
}
async function writeSavedMediaBuffer(params: {
dir: string;
id: string;
buffer: Buffer;
}): Promise<string> {
const dest = path.join(params.dir, params.id);
await retryAfterRecreatingDir(params.dir, async () => {
await fs.writeFile(dest, params.buffer, { mode: MEDIA_FILE_MODE });
await enforceMediaFileMode(dest);
});
await retryAfterRecreatingDir(params.dir, () =>
fs.writeFile(dest, params.buffer, { mode: MEDIA_FILE_MODE }),
);
return dest;
}
@@ -372,7 +369,6 @@ export async function saveMediaSource(
const id = buildSavedMediaId({ baseId, ext });
const finalDest = path.join(dir, id);
await fs.rename(tempDest, finalDest);
await enforceMediaFileMode(finalDest);
return buildSavedMediaResult({ dir, id, size, contentType: mime });
}
// local path