release: 1.1.0
TallyNote release / linux-x64 (push) Successful in 6m24s

This commit is contained in:
Qiufeng
2026-08-31 20:11:34 +08:00
parent cbe0d65320
commit 12495fb6a4
66 changed files with 4315 additions and 77 deletions
+24 -3
View File
@@ -226,26 +226,47 @@ export async function fileReadStream(config: AppConfig, storagePath: string) {
return safeReadStream(config.filesDir, storagePath);
}
function mapReadError(error: unknown): unknown {
if (error instanceof AppError) return error;
const code = (error as NodeJS.ErrnoException | undefined)?.code;
if (code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP") {
return new AppError(410, "ATTACHMENT_MISSING", "附件文件已不可用");
}
return error;
}
/** Open a private file by descriptor and keep the no-follow guarantee through
* the subsequent read. Used for both attachment and export downloads. */
export async function safeReadStream(root: string, relativePath: string) {
const handle = await open(safeStoragePath(root, relativePath), fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
let handle: Awaited<ReturnType<typeof open>>;
try {
handle = await open(safeStoragePath(root, relativePath), fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
} catch (error) {
throw mapReadError(error);
}
try {
const info = await handle.stat();
if (!info.isFile()) throw new AppError(410, "ATTACHMENT_MISSING", "附件文件已不可用");
return handle.createReadStream({ autoClose: true });
} catch (error) {
await handle.close().catch(() => undefined);
throw error;
throw mapReadError(error);
}
}
export async function readStorageFile(config: AppConfig, storagePath: string): Promise<Buffer> {
const handle = await open(safeStoragePath(config.filesDir, storagePath), fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
let handle: Awaited<ReturnType<typeof open>>;
try {
handle = await open(safeStoragePath(config.filesDir, storagePath), fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
} catch (error) {
throw mapReadError(error);
}
try {
const info = await handle.stat();
if (!info.isFile()) throw new AppError(410, "ATTACHMENT_MISSING", "附件文件已不可用");
return await handle.readFile();
} catch (error) {
throw mapReadError(error);
} finally {
await handle.close();
}