diff --git a/server/endpoints/api/document/index.js b/server/endpoints/api/document/index.js index e3ab050c..158f4df6 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 { setupMulter } = require("../../../utils/files/multer"); +const { handleFileUpload } = require("../../../utils/files/multer"); const { viewLocalFiles, findDocumentInDocuments, @@ -9,7 +9,6 @@ const { const { reqBody } = require("../../../utils/http"); const { EventLogs } = require("../../../models/eventLogs"); const { CollectorApi } = require("../../../utils/collectorApi"); -const { handleUploads } = setupMulter(); const fs = require("fs"); const path = require("path"); const { Document } = require("../../../models/documents"); @@ -23,8 +22,7 @@ function apiDocumentEndpoints(app) { app.post( "/v1/document/upload", - [validApiKey], - handleUploads.single("file"), + [validApiKey, handleFileUpload], async (request, response) => { /* #swagger.tags = ['Documents'] diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 2e0eda84..753825b8 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -12,13 +12,11 @@ const { multiUserMode, queryParams, } = require("../utils/http"); -const { setupLogoUploads, setupPfpUploads } = require("../utils/files/multer"); +const { handleAssetUpload, handlePfpUpload } = require("../utils/files/multer"); const { v4 } = require("uuid"); const { SystemSettings } = require("../models/systemSettings"); const { User } = require("../models/user"); const { validatedRequest } = require("../utils/middleware/validatedRequest"); -const { handleLogoUploads } = setupLogoUploads(); -const { handlePfpUploads } = setupPfpUploads(); const fs = require("fs"); const path = require("path"); const { @@ -531,8 +529,7 @@ function systemEndpoints(app) { app.post( "/system/upload-pfp", - [validatedRequest, flexUserRoleValid([ROLES.all])], - handlePfpUploads.single("file"), + [validatedRequest, flexUserRoleValid([ROLES.all]), handlePfpUpload], async function (request, response) { try { const user = await userFromSession(request, response); @@ -605,10 +602,13 @@ function systemEndpoints(app) { app.post( "/system/upload-logo", - [validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])], - handleLogoUploads.single("logo"), + [ + validatedRequest, + flexUserRoleValid([ROLES.admin, ROLES.manager]), + handleAssetUpload, + ], async (request, response) => { - if (!request.file || !request.file.originalname) { + if (!request?.file || !request?.file.originalname) { return response.status(400).json({ message: "No logo file provided." }); } diff --git a/server/endpoints/workspaces.js b/server/endpoints/workspaces.js index d3715cd8..da9e2ad9 100644 --- a/server/endpoints/workspaces.js +++ b/server/endpoints/workspaces.js @@ -1,10 +1,13 @@ +const path = require("path"); +const fs = require("fs"); const { reqBody, multiUserMode, userFromSession } = require("../utils/http"); +const { normalizePath } = require("../utils/files"); const { Workspace } = require("../models/workspace"); const { Document } = require("../models/documents"); const { DocumentVectors } = require("../models/vectors"); const { WorkspaceChats } = require("../models/workspaceChats"); const { getVectorDbClass } = require("../utils/helpers"); -const { setupMulter } = require("../utils/files/multer"); +const { handleFileUpload, handlePfpUpload } = require("../utils/files/multer"); const { validatedRequest } = require("../utils/middleware/validatedRequest"); const { Telemetry } = require("../models/telemetry"); const { @@ -18,12 +21,6 @@ const { const { validWorkspaceSlug } = require("../utils/middleware/validWorkspace"); const { convertToChatHistory } = require("../utils/helpers/chat/responses"); const { CollectorApi } = require("../utils/collectorApi"); -const { handleUploads } = setupMulter(); -const { setupPfpUploads } = require("../utils/files/multer"); -const { normalizePath } = require("../utils/files"); -const { handlePfpUploads } = setupPfpUploads(); -const path = require("path"); -const fs = require("fs"); const { determineWorkspacePfpFilepath, fetchPfp, @@ -102,8 +99,11 @@ function workspaceEndpoints(app) { app.post( "/workspace/:slug/upload", - [validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])], - handleUploads.single("file"), + [ + validatedRequest, + flexUserRoleValid([ROLES.admin, ROLES.manager]), + handleFileUpload, + ], async function (request, response) { const Collector = new CollectorApi(); const { originalname } = request.file; @@ -479,8 +479,11 @@ function workspaceEndpoints(app) { app.post( "/workspace/:slug/upload-pfp", - [validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])], - handlePfpUploads.single("file"), + [ + validatedRequest, + flexUserRoleValid([ROLES.admin, ROLES.manager]), + handlePfpUpload, + ], async function (request, response) { try { const { slug } = request.params; diff --git a/server/utils/files/multer.js b/server/utils/files/multer.js index 874e7278..22f1217e 100644 --- a/server/utils/files/multer.js +++ b/server/utils/files/multer.js @@ -3,71 +3,114 @@ const path = require("path"); const fs = require("fs"); const { v4 } = require("uuid"); -function setupMulter() { - // Handle File uploads for auto-uploading. - const storage = 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) { - file.originalname = Buffer.from(file.originalname, "latin1").toString( - "utf8" - ); - cb(null, file.originalname); - }, - }); +// Handle File uploads for auto-uploading. +const fileUploadStorage = 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) { + file.originalname = Buffer.from(file.originalname, "latin1").toString( + "utf8" + ); + cb(null, file.originalname); + }, +}); - return { handleUploads: multer({ storage }) }; +// Asset storage for logos +const assetUploadStorage = multer.diskStorage({ + destination: function (_, __, cb) { + const uploadOutput = + process.env.NODE_ENV === "development" + ? path.resolve(__dirname, `../../storage/assets`) + : path.resolve(process.env.STORAGE_DIR, "assets"); + fs.mkdirSync(uploadOutput, { recursive: true }); + return cb(null, uploadOutput); + }, + filename: function (_, file, cb) { + file.originalname = Buffer.from(file.originalname, "latin1").toString( + "utf8" + ); + cb(null, file.originalname); + }, +}); + +// Asset sub-storage manager for pfp icons. +const pfpUploadStorage = multer.diskStorage({ + destination: function (_, __, cb) { + const uploadOutput = + process.env.NODE_ENV === "development" + ? path.resolve(__dirname, `../../storage/assets/pfp`) + : path.resolve(process.env.STORAGE_DIR, "assets/pfp"); + fs.mkdirSync(uploadOutput, { recursive: true }); + return cb(null, uploadOutput); + }, + filename: function (req, file, cb) { + const randomFileName = `${v4()}${path.extname(file.originalname)}`; + req.randomFileName = randomFileName; + cb(null, randomFileName); + }, +}); + +// Handle Generic file upload as documents +function handleFileUpload(request, response, next) { + const upload = multer({ storage: fileUploadStorage }).single("file"); + upload(request, response, function (err) { + if (err) { + response + .status(500) + .json({ + success: false, + error: `Invalid file upload. ${err.message}`, + }) + .end(); + return; + } + next(); + }); } -function setupLogoUploads() { - // Handle Logo uploads. - const storage = multer.diskStorage({ - destination: function (_, __, cb) { - const uploadOutput = - process.env.NODE_ENV === "development" - ? path.resolve(__dirname, `../../storage/assets`) - : path.resolve(process.env.STORAGE_DIR, "assets"); - fs.mkdirSync(uploadOutput, { recursive: true }); - return cb(null, uploadOutput); - }, - filename: function (_, file, cb) { - file.originalname = Buffer.from(file.originalname, "latin1").toString( - "utf8" - ); - cb(null, file.originalname); - }, +// Handle logo asset uploads +function handleAssetUpload(request, response, next) { + const upload = multer({ storage: assetUploadStorage }).single("logo"); + upload(request, response, function (err) { + if (err) { + response + .status(500) + .json({ + success: false, + error: `Invalid file upload. ${err.message}`, + }) + .end(); + return; + } + next(); }); - - return { handleLogoUploads: multer({ storage }) }; } -function setupPfpUploads() { - const storage = multer.diskStorage({ - destination: function (_, __, cb) { - const uploadOutput = - process.env.NODE_ENV === "development" - ? path.resolve(__dirname, `../../storage/assets/pfp`) - : path.resolve(process.env.STORAGE_DIR, "assets/pfp"); - fs.mkdirSync(uploadOutput, { recursive: true }); - return cb(null, uploadOutput); - }, - filename: function (req, file, cb) { - const randomFileName = `${v4()}${path.extname(file.originalname)}`; - req.randomFileName = randomFileName; - cb(null, randomFileName); - }, +// Handle PFP file upload as logos +function handlePfpUpload(request, response, next) { + const upload = multer({ storage: pfpUploadStorage }).single("file"); + upload(request, response, function (err) { + if (err) { + response + .status(500) + .json({ + success: false, + error: `Invalid file upload. ${err.message}`, + }) + .end(); + return; + } + next(); }); - - return { handlePfpUploads: multer({ storage }) }; } module.exports = { - setupMulter, - setupLogoUploads, - setupPfpUploads, + handleFileUpload, + handleAssetUpload, + handlePfpUpload, };