diff --git a/backend/src/config/env.ts b/backend/src/config/env.ts index 13d4119..c251c4c 100644 --- a/backend/src/config/env.ts +++ b/backend/src/config/env.ts @@ -28,7 +28,12 @@ export const env = { FRONTEND_URL: process.env.FRONTEND_URL || 'http://localhost:5173', // Upload - MAX_FILE_SIZE: parseInt(process.env.MAX_FILE_SIZE || '5242880', 10), + // Bilder werden ohnehin auf 1600px heruntergerechnet, die Grenze muss nur + // gross genug fuer ein unbearbeitetes Handyfoto sein. + MAX_FILE_SIZE: parseInt(process.env.MAX_FILE_SIZE || String(20 * 1024 * 1024), 10), + // PDFs werden unveraendert abgelegt. Eine Getraenkekarte mit Bildern liegt + // schnell bei 15-20 MB, deshalb ein eigener, groesserer Wert. + MAX_PDF_SIZE: parseInt(process.env.MAX_PDF_SIZE || String(40 * 1024 * 1024), 10), }; // Validate required environment variables diff --git a/backend/src/index.ts b/backend/src/index.ts index a251732..3790f95 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -73,9 +73,11 @@ fastify.register(jwt, { }, }); +// Der globale Wert ist die Obergrenze fuer alles. Die Routen setzen ihn per +// request.file({ limits }) auf ihren eigenen, engeren Wert herunter. fastify.register(multipart, { limits: { - fileSize: env.MAX_FILE_SIZE, + fileSize: Math.max(env.MAX_FILE_SIZE, env.MAX_PDF_SIZE), }, }); diff --git a/backend/src/routes/content.ts b/backend/src/routes/content.ts index ba5478a..8781c32 100644 --- a/backend/src/routes/content.ts +++ b/backend/src/routes/content.ts @@ -5,6 +5,7 @@ import { contentSections } from '../db/schema.js'; import { eq } from 'drizzle-orm'; import { saveUploadedImage } from '../services/upload.service.js'; import { dropImageIfUnused, extractImageUrls } from '../services/image-refs.service.js'; +import { env } from '../config/env.js'; // Fastify JSON schema for content section body const contentBodyJsonSchema = { @@ -106,7 +107,7 @@ const contentRoute: FastifyPluginAsync = async (fastify) => { preHandler: [fastify.authenticate], }, async (request, reply) => { try { - const file = await (request as any).file(); + const file = await (request as any).file({ limits: { fileSize: env.MAX_FILE_SIZE } }); if (!file) { return reply.code(400).send({ error: 'No file uploaded' }); } diff --git a/backend/src/routes/events.ts b/backend/src/routes/events.ts index 03b1a8b..2beb7e6 100644 --- a/backend/src/routes/events.ts +++ b/backend/src/routes/events.ts @@ -4,6 +4,7 @@ import { events } from '../db/schema.js'; import { eq } from 'drizzle-orm'; import { dropImageIfUnused } from '../services/image-refs.service.js'; import { saveUploadedImage } from '../services/upload.service.js'; +import { env } from '../config/env.js'; /** Raeumt eine Bilddatei weg, ohne dass ein Fehler die Antwort kippt. */ async function dropUnusedImage(fastify: any, url: string | null | undefined, reason: string) { @@ -102,7 +103,7 @@ const eventsRoute: FastifyPluginAsync = async (fastify) => { }, async (request, reply) => { try { // Expect a single file field named "file" - const file = await (request as any).file(); + const file = await (request as any).file({ limits: { fileSize: env.MAX_FILE_SIZE } }); if (!file) { return reply.code(400).send({ error: 'No file uploaded' }); } diff --git a/backend/src/routes/gallery.ts b/backend/src/routes/gallery.ts index c0a4a02..ef44083 100644 --- a/backend/src/routes/gallery.ts +++ b/backend/src/routes/gallery.ts @@ -5,6 +5,7 @@ import { galleryImages } from '../db/schema.js'; import { eq } from 'drizzle-orm'; import { dropImageIfUnused } from '../services/image-refs.service.js'; import { saveUploadedImage } from '../services/upload.service.js'; +import { env } from '../config/env.js'; /** Raeumt eine Bilddatei weg, ohne dass ein Fehler die Antwort kippt. */ async function dropUnusedImage(fastify: any, url: string | null | undefined, reason: string) { @@ -81,7 +82,7 @@ const galleryRoute: FastifyPluginAsync = async (fastify) => { }, async (request, reply) => { try { // Expect a single file field named "file" - const file = await (request as any).file(); + const file = await (request as any).file({ limits: { fileSize: env.MAX_FILE_SIZE } }); if (!file) { return reply.code(400).send({ error: 'No file uploaded' }); } diff --git a/backend/src/routes/pdf.ts b/backend/src/routes/pdf.ts index f3913a0..0d15d0b 100644 --- a/backend/src/routes/pdf.ts +++ b/backend/src/routes/pdf.ts @@ -45,7 +45,7 @@ const pdfRoute: FastifyPluginAsync = async (fastify) => { } try { - const file = await (request as any).file(); + const file = await (request as any).file({ limits: { fileSize: env.MAX_PDF_SIZE } }); if (!file) { return reply.code(400).send({ error: 'No file uploaded' }); } @@ -63,7 +63,7 @@ const pdfRoute: FastifyPluginAsync = async (fastify) => { const buffer = Buffer.concat(chunks); if ((file.file as any)?.truncated) { - const limit = Math.round(env.MAX_FILE_SIZE / 1024 / 1024); + const limit = Math.round(env.MAX_PDF_SIZE / 1024 / 1024); return reply.code(413).send({ error: `PDF too large. Maximum is ${limit} MB` }); } @@ -113,7 +113,7 @@ const pdfRoute: FastifyPluginAsync = async (fastify) => { } catch (err: any) { if (err?.code === 'FST_REQ_FILE_TOO_LARGE') { - const limit = Math.round(env.MAX_FILE_SIZE / 1024 / 1024); + const limit = Math.round(env.MAX_PDF_SIZE / 1024 / 1024); return reply.code(413).send({ error: `PDF too large. Maximum is ${limit} MB` }); } fastify.log.error({ err }, 'PDF upload failed');