Media: enforce file mode after writes

This commit is contained in:
Val Alexander
2026-03-27 07:19:07 -05:00
committed by Val Alexander
parent b1c982bb2d
commit 206c29514c
2 changed files with 12 additions and 4 deletions

View File

@@ -207,6 +207,7 @@ Docs: https://docs.openclaw.ai
- Discord/config types: add missing `autoArchiveDuration` to `DiscordGuildChannelConfig` so TypeScript config definitions match the existing schema and runtime support. (#43427) Thanks @davidguttman.
- Docs/IRC: fix five `json55` code-fence typos in the IRC channel examples so Mintlify applies JSON5 syntax highlighting correctly. (#50842) Thanks @Hollychou924.
- Discord/commands: trim overlong slash-command descriptions to Discord's 100-character limit and map rejected deploy indexes from Discord validation payloads back to command names/descriptions, so deploys stop failing on long descriptions and startup logs identify the rejected commands. (#54118) thanks @huntharo
- Media/store: enforce the intended media file mode after writes and redirect downloads so restrictive umasks do not silently narrow saved media permissions.
## 2026.3.23

View File

@@ -229,7 +229,8 @@ async function downloadToFile(
}
});
pipeline(res, out)
.then(() => {
.then(async () => {
await enforceMediaFileMode(dest);
const sniffBuffer = Buffer.concat(sniffChunks, Math.min(sniffLen, 16384));
const rawHeader = res.headers["content-type"];
const headerMime = Array.isArray(rawHeader) ? rawHeader[0] : rawHeader;
@@ -285,15 +286,20 @@ 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, () =>
fs.writeFile(dest, params.buffer, { mode: MEDIA_FILE_MODE }),
);
await retryAfterRecreatingDir(params.dir, async () => {
await fs.writeFile(dest, params.buffer, { mode: MEDIA_FILE_MODE });
await enforceMediaFileMode(dest);
});
return dest;
}
@@ -366,6 +372,7 @@ 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