fix: use per-request upload limit from DB and fix silent truncation
Reads max_upload_size_bytes from instance_settings per-request and passes it to request.file() so Fastify kills the stream at the admin's configured limit. Checks file.truncated to properly reject files that exceed the limit instead of saving corrupted data.
This commit is contained in:
@@ -61,7 +61,7 @@ async function main(): Promise<void> {
|
|||||||
|
|
||||||
await app.register(multipart, {
|
await app.register(multipart, {
|
||||||
limits: {
|
limits: {
|
||||||
fileSize: config.maxUploadSize,
|
fileSize: 500 * 1024 * 1024, // 500MB hard ceiling — actual limit enforced per-request
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,13 @@ export async function uploadRoutes(app: FastifyInstance): Promise<void> {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, async (request, reply) => {
|
}, async (request, reply) => {
|
||||||
const data = await request.file();
|
// Read dynamic upload limit from instance settings
|
||||||
|
const db = getDb();
|
||||||
|
const settings = db.select({ maxUploadSizeBytes: schema.instanceSettings.maxUploadSizeBytes })
|
||||||
|
.from(schema.instanceSettings).where(eq(schema.instanceSettings.id, 1)).get();
|
||||||
|
const maxSize = settings?.maxUploadSizeBytes ?? config.maxUploadSize;
|
||||||
|
|
||||||
|
const data = await request.file({ limits: { fileSize: maxSize } });
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return reply.code(400).send({ error: 'No file provided', statusCode: 400 });
|
return reply.code(400).send({ error: 'No file provided', statusCode: 400 });
|
||||||
}
|
}
|
||||||
@@ -56,18 +62,17 @@ export async function uploadRoutes(app: FastifyInstance): Promise<void> {
|
|||||||
const writeStream = fs.createWriteStream(filepath);
|
const writeStream = fs.createWriteStream(filepath);
|
||||||
await pipeline(data.file, writeStream);
|
await pipeline(data.file, writeStream);
|
||||||
|
|
||||||
// Get file size
|
// Check if file was truncated by multipart limit
|
||||||
const stats = fs.statSync(filepath);
|
if ((data.file as any).truncated) {
|
||||||
const size = stats.size;
|
|
||||||
|
|
||||||
// Check size limit
|
|
||||||
if (size > config.maxUploadSize) {
|
|
||||||
fs.unlinkSync(filepath);
|
fs.unlinkSync(filepath);
|
||||||
return reply.code(413).send({ error: 'File too large', statusCode: 413 });
|
return reply.code(413).send({ error: 'File too large', statusCode: 413 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get file size
|
||||||
|
const stats = fs.statSync(filepath);
|
||||||
|
const size = stats.size;
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const db = getDb();
|
|
||||||
|
|
||||||
// ─── Media processing ────────────────────────────────────────────────────
|
// ─── Media processing ────────────────────────────────────────────────────
|
||||||
let thumbnailFilename: string | null = null;
|
let thumbnailFilename: string | null = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user