diff --git a/src/comment_upload_handler.mjs b/src/comment_upload_handler.mjs index 600837e..89a171e 100644 --- a/src/comment_upload_handler.mjs +++ b/src/comment_upload_handler.mjs @@ -92,12 +92,19 @@ const parseMultipartFiles = (buffer, boundary) => { }; /** - * Build the allowed MIME list for comment uploads (image/*, video/*, audio/*). - * Filters from cfg.mimes, excluding PDF, SWF, etc. + * Build the allowed MIME list for comment uploads. + * Respects cfg.websrv.fileupload_comments_mimes (e.g. ["image", "video", "audio"]) to + * allow a different set of categories than the global allowedMimes used for page uploads. + * Falls back to image/video/audio if the setting is absent. */ const getAllowedCommentMimes = () => { + const allowedCats = Array.isArray(cfg.websrv.fileupload_comments_mimes) + ? cfg.websrv.fileupload_comments_mimes.map(c => c.toLowerCase()) + : ['image', 'video', 'audio']; return Object.keys(cfg.mimes).filter(mime => - mime.startsWith('image/') || mime.startsWith('video/') || mime.startsWith('audio/') + allowedCats.some(cat => + cat.includes('/') ? mime === cat : mime.startsWith(`${cat}/`) + ) ); }; diff --git a/src/index.mjs b/src/index.mjs index f27d913..1942af3 100644 --- a/src/index.mjs +++ b/src/index.mjs @@ -1147,6 +1147,7 @@ process.on('uncaughtException', err => { fileupload_comments_size: cfg.websrv.fileupload_comments_size || (10 * 1024 * 1024), fileupload_comments_max: cfg.websrv.fileupload_comments_max || 5, fileupload_comments_mode: cfg.websrv.fileupload_comments_mode || 'attachment', + fileupload_comments_mimes: Array.isArray(cfg.websrv.fileupload_comments_mimes) ? cfg.websrv.fileupload_comments_mimes : ['image', 'video', 'audio'], get fonts() { try { diff --git a/src/upload_handler.mjs b/src/upload_handler.mjs index 45daf93..8cf9448 100644 --- a/src/upload_handler.mjs +++ b/src/upload_handler.mjs @@ -157,7 +157,18 @@ export const handleUpload = async (req, res, self) => { } // Validate MIME type - const allowedMimes = Object.keys(cfg.mimes); + // cfg.allowedMimes entries can be category prefixes ("image", "video", "audio") + // OR exact MIME types ("application/pdf"). Entries with "/" are matched exactly. + const allowedCats = Array.isArray(cfg.allowedMimes) + ? cfg.allowedMimes.map(c => c.toLowerCase()) + : null; + const allowedMimes = allowedCats + ? Object.keys(cfg.mimes).filter(m => + allowedCats.some(cat => + cat.includes('/') ? m === cat : m.startsWith(`${cat}/`) + ) + ) + : Object.keys(cfg.mimes); let mime = file.contentType; if (!allowedMimes.includes(mime)) { @@ -224,7 +235,7 @@ export const handleUpload = async (req, res, self) => { // Save temporarily to detect actual MIME await fs.writeFile(tmpPath, file.data); - // Verify MIME + // Verify actual MIME (second check after file-command detection) let actualMime = (await queue.spawn('file', ['--mime-type', '-b', tmpPath])).stdout.trim(); if (!allowedMimes.includes(actualMime)) { await fs.unlink(tmpPath).catch(() => { });