From 2432e230c5d4904c8d867d696d57366ff9e71cc5 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 5 Apr 2026 10:44:47 +0300 Subject: [PATCH] chore(etapi): enforce MIME for image upload --- apps/server/src/etapi/notes.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/server/src/etapi/notes.ts b/apps/server/src/etapi/notes.ts index 9fae830704..d85f128240 100644 --- a/apps/server/src/etapi/notes.ts +++ b/apps/server/src/etapi/notes.ts @@ -66,6 +66,11 @@ function register(router: Router) { eu.validateAndPatch(_params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_NOTE); const params = _params as NoteParams; + // Validate MIME type for image notes + if (params.type === "image" && params.mime && !params.mime.startsWith("image/")) { + throw new eu.EtapiError(400, "INVALID_MIME_FOR_IMAGE", `MIME type '${params.mime}' is not allowed for image notes. MIME must start with 'image/'.`); + } + try { const resp = noteService.createNewNote(params); @@ -93,6 +98,13 @@ function register(router: Router) { throw new eu.EtapiError(400, "NOTE_IS_PROTECTED", `Note '${req.params.noteId}' is protected and cannot be modified through ETAPI.`); } + // Validate MIME type for image notes (check both current and new type/mime) + const effectiveType = req.body.type || note.type; + const effectiveMime = req.body.mime || note.mime; + if (effectiveType === "image" && effectiveMime && !effectiveMime.startsWith("image/")) { + throw new eu.EtapiError(400, "INVALID_MIME_FOR_IMAGE", `MIME type '${effectiveMime}' is not allowed for image notes. MIME must start with 'image/'.`); + } + noteService.saveRevisionIfNeeded(note); eu.validateAndPatch(note, req.body, ALLOWED_PROPERTIES_FOR_PATCH); note.save();