From 40800631e3da62a6ddd54116fd892b81ade763ca Mon Sep 17 00:00:00 2001
From: Timothy Carambat <rambat1010@gmail.com>
Date: Fri, 25 Oct 2024 12:03:19 -0700
Subject: [PATCH] Patch `v1/document/upload` filename charset encoding (#2535)

---
 server/endpoints/api/document/index.js |  4 +-
 server/utils/files/multer.js           | 66 ++++++++++++++++++++++++--
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/server/endpoints/api/document/index.js b/server/endpoints/api/document/index.js
index a646fb584..f49cf0dd4 100644
--- a/server/endpoints/api/document/index.js
+++ b/server/endpoints/api/document/index.js
@@ -1,6 +1,6 @@
 const { Telemetry } = require("../../../models/telemetry");
 const { validApiKey } = require("../../../utils/middleware/validApiKey");
-const { handleFileUpload } = require("../../../utils/files/multer");
+const { handleAPIFileUpload } = require("../../../utils/files/multer");
 const {
   viewLocalFiles,
   findDocumentInDocuments,
@@ -23,7 +23,7 @@ function apiDocumentEndpoints(app) {
 
   app.post(
     "/v1/document/upload",
-    [validApiKey, handleFileUpload],
+    [validApiKey, handleAPIFileUpload],
     async (request, response) => {
       /*
     #swagger.tags = ['Documents']
diff --git a/server/utils/files/multer.js b/server/utils/files/multer.js
index 22f1217e3..a4b90042e 100644
--- a/server/utils/files/multer.js
+++ b/server/utils/files/multer.js
@@ -3,7 +3,10 @@ const path = require("path");
 const fs = require("fs");
 const { v4 } = require("uuid");
 
-// Handle File uploads for auto-uploading.
+/**
+ * Handle File uploads for auto-uploading.
+ * Mostly used for internal GUI/API uploads.
+ */
 const fileUploadStorage = multer.diskStorage({
   destination: function (_, __, cb) {
     const uploadOutput =
@@ -20,6 +23,23 @@ const fileUploadStorage = multer.diskStorage({
   },
 });
 
+/**
+ * Handle API file upload as documents - this does not manipulate the filename
+ * at all for encoding/charset reasons.
+ */
+const fileAPIUploadStorage = multer.diskStorage({
+  destination: function (_, __, cb) {
+    const uploadOutput =
+      process.env.NODE_ENV === "development"
+        ? path.resolve(__dirname, `../../../collector/hotdir`)
+        : path.resolve(process.env.STORAGE_DIR, `../../collector/hotdir`);
+    cb(null, uploadOutput);
+  },
+  filename: function (_, file, cb) {
+    cb(null, file.originalname);
+  },
+});
+
 // Asset storage for logos
 const assetUploadStorage = multer.diskStorage({
   destination: function (_, __, cb) {
@@ -38,7 +58,9 @@ const assetUploadStorage = multer.diskStorage({
   },
 });
 
-// Asset sub-storage manager for pfp icons.
+/**
+ * Handle PFP file upload as logos
+ */
 const pfpUploadStorage = multer.diskStorage({
   destination: function (_, __, cb) {
     const uploadOutput =
@@ -55,7 +77,12 @@ const pfpUploadStorage = multer.diskStorage({
   },
 });
 
-// Handle Generic file upload as documents
+/**
+ * Handle Generic file upload as documents from the GUI
+ * @param {Request} request
+ * @param {Response} response
+ * @param {NextFunction} next
+ */
 function handleFileUpload(request, response, next) {
   const upload = multer({ storage: fileUploadStorage }).single("file");
   upload(request, response, function (err) {
@@ -73,7 +100,33 @@ function handleFileUpload(request, response, next) {
   });
 }
 
-// Handle logo asset uploads
+/**
+ * Handle API file upload as documents - this does not manipulate the filename
+ * at all for encoding/charset reasons.
+ * @param {Request} request
+ * @param {Response} response
+ * @param {NextFunction} next
+ */
+function handleAPIFileUpload(request, response, next) {
+  const upload = multer({ storage: fileAPIUploadStorage }).single("file");
+  upload(request, response, function (err) {
+    if (err) {
+      response
+        .status(500)
+        .json({
+          success: false,
+          error: `Invalid file upload. ${err.message}`,
+        })
+        .end();
+      return;
+    }
+    next();
+  });
+}
+
+/**
+ * Handle logo asset uploads
+ */
 function handleAssetUpload(request, response, next) {
   const upload = multer({ storage: assetUploadStorage }).single("logo");
   upload(request, response, function (err) {
@@ -91,7 +144,9 @@ function handleAssetUpload(request, response, next) {
   });
 }
 
-// Handle PFP file upload as logos
+/**
+ * Handle PFP file upload as logos
+ */
 function handlePfpUpload(request, response, next) {
   const upload = multer({ storage: pfpUploadStorage }).single("file");
   upload(request, response, function (err) {
@@ -111,6 +166,7 @@ function handlePfpUpload(request, response, next) {
 
 module.exports = {
   handleFileUpload,
+  handleAPIFileUpload,
   handleAssetUpload,
   handlePfpUpload,
 };
-- 
GitLab