diff --git a/src/middleware/multer.js b/src/middleware/multer.js new file mode 100644 index 0000000000..e15c146ff3 --- /dev/null +++ b/src/middleware/multer.js @@ -0,0 +1,16 @@ +'use strict'; + +const multer = require('multer'); +const storage = multer.diskStorage({}); +const upload = multer({ storage, + // from https://github.com/TriliumNext/Trilium/pull/3058/files + fileFilter: (req, file, cb) => { + // UTF-8 file names are not well decoded by multer/busboy, so we handle the conversion on our side. + // See https://github.com/expressjs/multer/pull/1102. + file.originalname = Buffer.from(file.originalname, 'latin1').toString('utf-8'); + cb(null, true); + } +}); + +module.exports = upload; + diff --git a/src/routes/admin.js b/src/routes/admin.js index 5421b4d0ef..4788593c5a 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -85,9 +85,7 @@ function apiRoutes(router, name, middleware, controllers) { router.post(`/api/${name}/manage/categories/:cid/name`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.categories.renameRemote)); router.delete(`/api/${name}/manage/categories/:cid`, middleware.ensureLoggedIn, helpers.tryRoute(controllers.admin.categories.removeRemote)); - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer'); const middlewares = [ upload.array('files[]', 20), diff --git a/src/routes/api.js b/src/routes/api.js index 4424d9a979..79fb83b811 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -23,9 +23,7 @@ module.exports = function (app, middleware, controllers) { router.get('/topic/teaser/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.teaser)); router.get('/topic/pagination/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.pagination)); - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer'); const postMiddlewares = [ middleware.maintenanceMode, diff --git a/src/routes/authentication.js b/src/routes/authentication.js index 720675b29d..9836cf22a5 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -154,10 +154,7 @@ Auth.reloadRoutes = async function (params) { }); }); - - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer') const middlewares = [ upload.any(), Auth.middleware.applyCSRF, diff --git a/src/routes/helpers.js b/src/routes/helpers.js index 2109a0bd9c..079eb36536 100644 --- a/src/routes/helpers.js +++ b/src/routes/helpers.js @@ -54,9 +54,7 @@ helpers.setupApiRoute = function (...args) { const [router, verb, name] = args; let middlewares = args.length > 4 ? args[args.length - 2] : []; const controller = args[args.length - 1]; - const multer = require('multer'); - const storage = multer.diskStorage({}); - const upload = multer({ storage }); + const upload = require('../middleware/multer'); middlewares = [ middleware.autoLocale, middleware.applyBlacklist, diff --git a/test/files/测试.jpg b/test/files/测试.jpg new file mode 100644 index 0000000000..905e886eef Binary files /dev/null and b/test/files/测试.jpg differ diff --git a/test/uploads.js b/test/uploads.js index 1e5b3d19e3..8a57c0d06e 100644 --- a/test/uploads.js +++ b/test/uploads.js @@ -194,6 +194,12 @@ describe('Upload Controllers', () => { assert(body.response.images[0].url); }); + it('should upload a file with utf8 characters in the name to a post', async () => { + const { body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/测试.jpg'), {}, jar, csrf_token); + + assert(body.response.images[0].url.endsWith('测试.jpg')); + }); + it('should fail to upload image to post if image dimensions are too big', async () => { const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/toobig.png'), {}, jar, csrf_token); assert.strictEqual(response.statusCode, 500);