diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js index a8f8c30ed240..5dfc152c58cf 100644 --- a/src/node/handler/ImportHandler.js +++ b/src/node/handler/ImportHandler.js @@ -89,24 +89,24 @@ const doImport = async (req, res, padId, authorId) => { maxFileSize: settings.importMaxFileSize, }); - // locally wrapped Promise, since form.parse requires a callback - let srcFile = await new Promise((resolve, reject) => { - form.parse(req, (err, fields, files) => { - if (err != null) { - logger.warn(`Import failed due to form error: ${err.stack || err}`); - // I hate doing indexOf here but I can't see anything to use... - if (err && err.stack && err.stack.indexOf('maxFileSize') !== -1) { - return reject(new ImportError('maxFileSize')); - } - return reject(new ImportError('uploadFailed')); - } - if (!files.file) { - logger.warn('Import failed because form had no file'); - return reject(new ImportError('uploadFailed')); - } - resolve(files.file[0].filepath); - }); - }); + let srcFile; + let files; + let fields; + try { + [fields, files] = await form.parse(req); + } catch (err) { + logger.warn(`Import failed due to form error: ${err.stack || err}`); + if (err.code === Formidable.formidableErrors.biggerThanMaxFileSize) { + throw new ImportError('maxFileSize'); + } + throw new ImportError('uploadFailed'); + } + if (!files.file) { + logger.warn('Import failed because form had no file'); + throw new ImportError('uploadFailed'); + } else { + srcFile = files.file[0].filepath; + } // ensure this is a file ending we know, else we change the file ending to .txt // this allows us to accept source code files like .c or .java diff --git a/src/node/hooks/express/apicalls.js b/src/node/hooks/express/apicalls.js index 010ab14e520e..5dbb57e16388 100644 --- a/src/node/hooks/express/apicalls.js +++ b/src/node/hooks/express/apicalls.js @@ -8,20 +8,19 @@ const util = require('util'); exports.expressPreSession = async (hookName, {app}) => { // The Etherpad client side sends information about how a disconnect happened - app.post('/ep/pad/connection-diagnostic-info', (req, res) => { - new Formidable().parse(req, (err, fields, files) => { - clientLogger.info(`DIAGNOSTIC-INFO: ${fields.diagnosticInfo}`); - res.end('OK'); - }); + app.post('/ep/pad/connection-diagnostic-info', async (req, res) => { + const [fields, files] = await (new Formidable({})).parse(req); + clientLogger.info(`DIAGNOSTIC-INFO: ${fields.diagnosticInfo}`); + res.end('OK'); }); - const parseJserrorForm = async (req) => await new Promise((resolve, reject) => { + const parseJserrorForm = async (req) => { const form = new Formidable({ maxFileSize: 1, // Files are not expected. Not sure if 0 means unlimited, so 1 is used. }); - form.on('error', (err) => reject(err)); - form.parse(req, (err, fields) => err != null ? reject(err) : resolve(fields.errorInfo)); - }); + const [fields, files] = await form.parse(req); + return fields.errorInfo; + }; // The Etherpad client side sends information about client side javscript errors app.post('/jserror', (req, res, next) => { diff --git a/src/node/hooks/express/openapi.js b/src/node/hooks/express/openapi.js index 0531854aa5ba..240b6fcf5811 100644 --- a/src/node/hooks/express/openapi.js +++ b/src/node/hooks/express/openapi.js @@ -15,8 +15,7 @@ */ const OpenAPIBackend = require('openapi-backend').default; -const formidable = require('formidable'); -const {promisify} = require('util'); +const IncomingForm = require('formidable').IncomingForm; const cloneDeep = require('lodash.clonedeep'); const createHTTPError = require('http-errors'); @@ -596,9 +595,13 @@ exports.expressPreSession = async (hookName, {app}) => { // read form data if method was POST let formData = {}; if (c.request.method === 'post') { - const form = new formidable.IncomingForm(); - const parseForm = promisify(form.parse).bind(form); - formData = await parseForm(req); + const form = new IncomingForm(); + formData = (await form.parse(req))[0]; + for (const k of Object.keys(formData)) { + if (formData[k] instanceof Array) { + formData[k] = formData[k][0]; + } + } } const fields = Object.assign({}, header, params, query, formData);