From df28f7026ea38ff74ba8f5ecc9ee2ad95c47e2a8 Mon Sep 17 00:00:00 2001 From: Marc-Roig Date: Tue, 13 Sep 2022 10:21:30 +0200 Subject: [PATCH] checkFileSize in provider upload --- packages/core/upload/server/config.js | 4 +--- packages/core/upload/server/register.js | 21 +++++++++++++++++++ .../core/upload/server/services/provider.js | 2 ++ packages/core/upload/server/utils/file.js | 2 ++ packages/providers/upload-local/lib/index.js | 13 +----------- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/packages/core/upload/server/config.js b/packages/core/upload/server/config.js index 8c8be58aa9..80084c5066 100644 --- a/packages/core/upload/server/config.js +++ b/packages/core/upload/server/config.js @@ -4,9 +4,7 @@ module.exports = { default: { enabled: true, provider: 'local', - providerOptions: { - sizeLimit: 1000000, - }, + sizeLimit: 1000000, actionOptions: {}, }, validator() {}, diff --git a/packages/core/upload/server/register.js b/packages/core/upload/server/register.js index a93863306f..a2945a826f 100644 --- a/packages/core/upload/server/register.js +++ b/packages/core/upload/server/register.js @@ -1,7 +1,9 @@ 'use strict'; +const { PayloadTooLargeError } = require('@strapi/utils/lib/errors'); const _ = require('lodash'); const registerUploadMiddleware = require('./middlewares/upload'); +const { kbytesToBytes } = require('./utils/file'); /** * Register upload plugin @@ -60,6 +62,25 @@ const createProvider = (config) => { ); } + if (providerOptions.sizeLimit) { + // TODO V5: remove sizeLimit from providerOptions + process.emitWarning( + `[deprecated] In future versions, "sizeLimit" argument will be ignored from upload.config.providerOptions. Move it to upload.config` + ); + } + + if (!providerInstance.checkFileSize) { + providerInstance.checkFileSize = (file) => { + const fileSize = kbytesToBytes(file.size); + + if (providerOptions.sizeLimit && fileSize > providerOptions.sizeLimit) { + throw new PayloadTooLargeError(); + } else if (config.sizeLimit && fileSize > config.sizeLimit) { + throw new PayloadTooLargeError(); + } + }; + } + const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => { return async function (file, options = actionOptions[methodName]) { return providerInstance[methodName](file, options); diff --git a/packages/core/upload/server/services/provider.js b/packages/core/upload/server/services/provider.js index c286776016..09710d411c 100644 --- a/packages/core/upload/server/services/provider.js +++ b/packages/core/upload/server/services/provider.js @@ -5,6 +5,8 @@ const { streamToBuffer } = require('../utils/file'); module.exports = ({ strapi }) => ({ async upload(file) { + await strapi.plugin('upload').provider.checkFileSize(file); + if (isFunction(strapi.plugin('upload').provider.uploadStream)) { file.stream = file.getStream(); await strapi.plugin('upload').provider.uploadStream(file); diff --git a/packages/core/upload/server/utils/file.js b/packages/core/upload/server/utils/file.js index 245bb3ba02..23f9fdf829 100644 --- a/packages/core/upload/server/utils/file.js +++ b/packages/core/upload/server/utils/file.js @@ -6,6 +6,7 @@ const { Writable } = require('stream'); const bytesToKbytes = (bytes) => Math.round((bytes / 1000) * 100) / 100; +const kbytesToBytes = (kbytes) => kbytes * 1000; const streamToBuffer = (stream) => new Promise((resolve, reject) => { @@ -46,6 +47,7 @@ function writableDiscardStream(options) { module.exports = { streamToBuffer, bytesToKbytes, + kbytesToBytes, getStreamSize, writableDiscardStream, }; diff --git a/packages/providers/upload-local/lib/index.js b/packages/providers/upload-local/lib/index.js index 1a46b7fffb..9614606651 100644 --- a/packages/providers/upload-local/lib/index.js +++ b/packages/providers/upload-local/lib/index.js @@ -9,18 +9,11 @@ const { pipeline } = require('stream'); const fs = require('fs'); const path = require('path'); const fse = require('fs-extra'); -const { PayloadTooLargeError } = require('@strapi/utils').errors; const UPLOADS_FOLDER_NAME = 'uploads'; module.exports = { - init({ sizeLimit = 1000000 } = {}) { - const verifySize = (file) => { - if (file.size > sizeLimit) { - throw new PayloadTooLargeError(); - } - }; - + init() { // Ensure uploads folder exists const uploadPath = path.resolve(strapi.dirs.static.public, UPLOADS_FOLDER_NAME); if (!fse.pathExistsSync(uploadPath)) { @@ -31,8 +24,6 @@ module.exports = { return { uploadStream(file) { - verifySize(file); - return new Promise((resolve, reject) => { pipeline( file.stream, @@ -50,8 +41,6 @@ module.exports = { }); }, upload(file) { - verifySize(file); - return new Promise((resolve, reject) => { // write file in public/assets folder fs.writeFile(path.join(uploadPath, `${file.hash}${file.ext}`), file.buffer, (err) => {