diff --git a/src/middleware/multipart.js b/src/middleware/multipart.js index 3c36e634a..8eb723904 100644 --- a/src/middleware/multipart.js +++ b/src/middleware/multipart.js @@ -3,6 +3,7 @@ 'use strict'; const multiparty = require('multiparty'), + safe = require('safetydance'), timeout = require('connect-timeout'); function _mime(req) { @@ -19,18 +20,21 @@ module.exports = function multipart(options) { keepExtensions: true, maxFieldsSize: options.maxFieldsSize || (2 * 1024), // only field size, not files limit: options.limit || '8mb', // file sizes - autoFiles: true + autoFiles: true // emit files instead of emitting 'part' }); // increase timeout of file uploads by default to 3 mins if (req.clearTimeout) req.clearTimeout(); // clear any previous installed timeout middleware timeout(options.timeout || (3 * 60 * 1000))(req, res, function () { - req.fields = { }; - req.files = { }; + req.fields = {}; + req.files = {}; - form.parse(req, function (err /*, fields, files */) { - if (err) return res.status(400).send('Error parsing request'); + form.parse(req, function (error, fields, files) { + if (error) { + for (const file in files) safe.fs.unlinkSync(file.path); + return res.status(400).send('Error parsing request'); + } next(null); }); diff --git a/src/routes/apps.js b/src/routes/apps.js index e4fe53227..9b07b2de9 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -939,7 +939,7 @@ async function uploadFile(req, res, next) { req.clearTimeout(); const [error] = await safe(apps.uploadFile(req.app, req.files.file.path, req.query.file)); - safe.fs.unlinkSync(req.files.file.path); // remove file in /tmp + safe.fs.unlinkSync(req.files.file.path); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(202, {})); diff --git a/src/routes/branding.js b/src/routes/branding.js index 069e0d02c..8fa018c2d 100644 --- a/src/routes/branding.js +++ b/src/routes/branding.js @@ -59,6 +59,7 @@ async function setCloudronAvatar(req, res, next) { if (!req.files.avatar) return next(new HttpError(400, 'avatar must be provided')); const avatar = safe.fs.readFileSync(req.files.avatar.path); + safe.fs.unlinkSync(req.files.avatar.path); if (!avatar) return next(500, safe.error.message); const [error] = await safe(branding.setCloudronAvatar(avatar)); @@ -86,6 +87,7 @@ async function setCloudronBackground(req, res, next) { if (req.files.background) { backgroundImage = safe.fs.readFileSync(req.files.background.path); + safe.fs.unlinkSync(req.files.background.path); if (!backgroundImage) return next(500, safe.error.message); } diff --git a/src/routes/profile.js b/src/routes/profile.js index 0e303557d..cda836e04 100644 --- a/src/routes/profile.js +++ b/src/routes/profile.js @@ -128,6 +128,7 @@ async function setAvatar(req, res, next) { if (req.files && req.files.avatar) { avatar = safe.fs.readFileSync(req.files.avatar.path); + safe.fs.unlinkSync(req.files.avatar.path); if (!avatar) return next(BoxError.toHttpError(new BoxError(BoxError.FS_ERROR, safe.error.message))); } else if (!avatar || (!avatar.equals(constants.AVATAR_GRAVATAR) && !avatar.equals(constants.AVATAR_NONE))) { return next(new HttpError(400, `avatar must be a file, ${constants.AVATAR_GRAVATAR} or ${constants.AVATAR_NONE}`)); @@ -176,6 +177,7 @@ async function setBackgroundImage(req, res, next) { if (req.files && req.files.backgroundImage) { backgroundImage = safe.fs.readFileSync(req.files.backgroundImage.path); + safe.fs.unlinkSync(req.files.backgroundImage.path); if (!backgroundImage) return next(BoxError.toHttpError(new BoxError(BoxError.FS_ERROR, safe.error.message))); }