Socket
Socket
Sign inDemoInstall

express-fileupload

Package Overview
Dependencies
3
Maintainers
2
Versions
48
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.6 to 1.1.7-alpha.1

14

lib/fileFactory.js

@@ -16,3 +16,4 @@ 'use strict';

* @param {String} filePath - destination file path.
* @param {Object} options
* @param {Object} options - file factory options.
* @param {Object} fileUploadOptions - middleware options.
* @returns {Function}

@@ -29,3 +30,4 @@ */

* @param {String} filePath - destination file path.
* @param {Object} options
* @param {Object} options - file factory options.
* @param {Object} fileUploadOptions - middleware options.
* @returns {Function}

@@ -55,6 +57,6 @@ */

mv: (filePath, callback) => {
// Determine a propper move function.
const moveFunc = (options.buffer.length && !options.tempFilePath)
? moveFromBuffer(filePath, options)
: moveFromTemp(filePath, options);
// Define a propper move function.
const moveFunc = fileUploadOptions.useTempFiles
? moveFromTemp(filePath, options, fileUploadOptions)
: moveFromBuffer(filePath, options, fileUploadOptions);
// Create a folder for a file.

@@ -61,0 +63,0 @@ checkAndMakeDir(fileUploadOptions, filePath);

'use strict';
const fileFactory = require('./fileFactory');
const processNested = require('./processNested');
const path = require('path');
const processMultipart = require('./processMultipart');

@@ -22,3 +21,3 @@ const isEligibleRequest = require('./isEligibleRequest');

useTempFiles: false,
tempFileDir: '/tmp'
tempFileDir: path.join(process.cwd(), 'tmp')
};

@@ -29,20 +28,13 @@

* @param {Object} options - Middleware options.
* @returns {Function}
* @returns {Function} - express-fileupload middleware.
*/
module.exports = (options) => {
const fileUploadOptions = buildOptions(DEFAULT_OPTIONS, options);
const uploadOptions = buildOptions(DEFAULT_OPTIONS, options);
return (req, res, next) => {
if (!isEligibleRequest(req)) {
debugLog(fileUploadOptions, 'Request is not eligible for file upload!');
debugLog(uploadOptions, 'Request is not eligible for file upload!');
return next();
}
processMultipart(fileUploadOptions, req, res, next);
processMultipart(uploadOptions, req, res, next);
};
};
/**
* Quietly expose fileFactory and processNested; useful for testing
*/
module.exports.fileFactory = fileFactory;
module.exports.processNested = processNested;

@@ -31,4 +31,5 @@ const crypto = require('crypto');

complete: getBuffer,
cleanup: emptyFunc
cleanup: emptyFunc,
getWritePromise: () => Promise.resolve()
};
};

@@ -14,2 +14,4 @@ const Busboy = require('busboy');

const waitFlushProperty = Symbol('wait flush property symbol');
/**

@@ -47,3 +49,11 @@ * Processes multipart request

// Define methods and handlers for upload process.
const {dataHandler, getFilePath, getFileSize, getHash, complete, cleanup} = options.useTempFiles
const {
dataHandler,
getFilePath,
getFileSize,
getHash,
complete,
cleanup,
getWritePromise
} = options.useTempFiles
? tempFileHandler(options, field, filename) // Upload into temporary file.

@@ -98,2 +108,7 @@ : memHandler(options, field, filename); // Upload into RAM.

}, options));
if (!req[waitFlushProperty]) {
req[waitFlushProperty] = [];
}
req[waitFlushProperty].push(getWritePromise());
});

@@ -116,7 +131,24 @@

busboy.on('finish', () => {
if (options.parseNested) {
req.body = processNested(req.body);
req.files = processNested(req.files);
const handler = (err) => {
if (options.parseNested) {
req.body = processNested(req.body);
req.files = processNested(req.files);
}
next(err);
};
if (req[waitFlushProperty]) {
Promise.all(req[waitFlushProperty])
.then(() => {
delete req[waitFlushProperty];
handler();
})
.catch(err => {
delete req[waitFlushProperty];
debugLog(options, `Error wait flush error:${err}`);
handler(err);
});
} else {
handler();
}
next();
});

@@ -123,0 +155,0 @@

@@ -12,3 +12,3 @@ const fs = require('fs');

module.exports = (options, fieldname, filename) => {
const dir = path.normalize(options.tempFileDir || process.cwd() + '/tmp/');
const dir = path.normalize(options.tempFileDir);
const tempFilePath = path.join(dir, getTempFilename());

@@ -22,2 +22,11 @@ checkAndMakeDir({createParentPath: true}, tempFilePath);

let fileSize = 0; // eslint-disable-line
const promise = new Promise((resolve, reject) => {
writeStream.on('finish', () => {
resolve();
});
writeStream.on('error', (err) => {
debugLog(options, `Error write temp file error:${err}`);
reject(err);
});
});

@@ -43,4 +52,7 @@ return {

deleteFile(tempFilePath, (err) => { if (err) throw err; });
},
getWritePromise: () => {
return promise;
}
};
};

@@ -151,17 +151,12 @@ 'use strict';

/**
* Move file via streams by copieng and the deleteing src.
* @param {String} src - Path to the source file
* @param {String} dst - Path to the destination file.
* moveFile - moves the file from src to dst.
* Firstly trying to rename the file if no luck copying it to dst and then deleteing src.
* @param {String} src - Path to the source file
* @param {String} dst - Path to the destination file.
* @param {Function} callback - A callback function.
*/
const moveFile = (src, dst, callback) => {
fs.rename(src, dst, err => {
if (err) {
// Copy file to dst and delete src whether success.
copyFile(src, dst, err => err ? callback(err) : deleteFile(src, callback));
return;
}
callback();
});
};
const moveFile = (src, dst, callback) => fs.rename(src, dst, err => (!err
? callback()
: copyFile(src, dst, err => err ? callback(err) : deleteFile(src, callback))
));

@@ -237,7 +232,9 @@ /**

* Parse file name and extension.
* @param opts {Object} - middleware options.
* @param fileName {String} - Uploaded file name.
* @returns {String}
* @param {Object} opts - middleware options.
* @param {string} fileName - Uploaded file name.
* @returns {string}
*/
const parseFileName = (opts, fileName) => {
// Check fileName argument
if (!fileName || typeof fileName !== 'string') return getTempFilename();
// Cut off file name if it's lenght more then 255.

@@ -244,0 +241,0 @@ let parsedName = fileName.length <= 255 ? fileName : fileName.substr(0, 255);

{
"name": "express-fileupload",
"version": "1.1.6",
"version": "1.1.7-alpha.1",
"author": "Richard Girges <richardgirges@gmail.com>",

@@ -16,3 +16,3 @@ "description": "Simple express file upload middleware that wraps around Busboy",

"engines": {
"node": ">=6.0.0"
"node": ">=8.0.0"
},

@@ -32,12 +32,12 @@ "keywords": [

"devDependencies": {
"body-parser": "^1.19.0",
"coveralls": "^3.0.9",
"eslint": "^6.8.0",
"express": "^4.17.1",
"istanbul": "^0.4.5",
"md5": "^2.2.1",
"body-parser": "^1.18.3",
"coveralls": "^3.0.2",
"eslint": "^5.9.0",
"express": "^4.16.3",
"istanbul": "^0.4.5",
"mocha": "^5.2.0",
"rimraf": "^2.6.2",
"supertest": "^3.3.0"
"mocha": "^7.0.1",
"rimraf": "^3.0.2",
"supertest": "^4.0.2"
}
}

@@ -12,3 +12,3 @@ # express-fileupload

# With NPM
npm install --save express-fileupload
npm i express-fileupload

@@ -34,3 +34,3 @@ # With Yarn

* `req.files.foo.name`: "car.jpg"
* `req.files.foo.mv`: A function to move the file elsewhere on your server
* `req.files.foo.mv`: A function to move the file elsewhere on your server. Can take a callback or return a promise.
* `req.files.foo.mimetype`: The mimetype of your file

@@ -43,7 +43,7 @@ * `req.files.foo.data`: A buffer representation of your file, returns empty buffer in case useTempFiles option was set to true.

**Notes about braking changes with md5 handling:**
**Notes about breaking changes with MD5 handling:**
* Before 1.0.0 `md5` is a MD5 checksum of the uploaded file.
* In 1.0.0 and till 1.1.1 `md5` value is a function to compute md5 hash [Read about it here.](https://github.com/richardgirges/express-fileupload/releases/tag/v1.0.0-alpha.1)
* From 1.1.1 it was reverted back to MD5 checksum value and also added full md5 support in case of using temporary files.
* Before 1.0.0, `md5` is an MD5 checksum of the uploaded file.
* From 1.0.0 until 1.1.1, `md5` is a function to compute an MD5 hash ([Read about it here.](https://github.com/richardgirges/express-fileupload/releases/tag/v1.0.0-alpha.1)).
* From 1.1.1 onward, `md5` is reverted back to MD5 checksum value and also added full MD5 support in case you are using temporary files.

@@ -57,3 +57,3 @@

### Using Busboy Options
Pass in Busboy options directly to the express-fileupload middleware. [Check out the Busboy documentation here.](https://github.com/mscdex/busboy#api)
Pass in Busboy options directly to the express-fileupload middleware. [Check out the Busboy documentation here](https://github.com/mscdex/busboy#api).

@@ -69,7 +69,4 @@ ```javascript

```
Note that this option available for versions 1.0.0 and newer.
```
```javascript
// Note that this option available for versions 1.0.0 and newer.
app.use(fileUpload({

@@ -80,2 +77,3 @@ useTempFiles : true,

```
### Using debug option

@@ -86,3 +84,3 @@

It will show you whether the request is illigable and also common events triggered during upload.
It will show you whether the request is invalid and also common events triggered during upload.
That can be really usfull for troubleshhoting and ***we recommend to attach debug output to each issue on Github***.

@@ -121,4 +119,4 @@

limitHandler | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>function(req, res, next)</code></li></ul> | User defined limit handler which will be invoked if the file is bigger than configured limits.
useTempFiles | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></ul> | Will use temporary files at the specified tempDir for managing uploads rather than using buffers in memory. This avoids memory issues when uploading large files.
tempFileDir | <ul><li><code>String</code>&nbsp;**(path)**</li></ul> | Used with the <code>useTempFiles</code> option. Path to the directory where temp files will be stored during the upload process. Feel free to add trailing slash, but it is not necessary.
useTempFiles | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></ul> | By default this module uploads files into RAM. Setting this option to True turns on using temporary files instead of utilising RAM. This avoids memory overflow issues when uploading large files or in case of uploading lots of files at same time.
tempFileDir | <ul><li><code>String</code>&nbsp;**(path)**</li></ul> | Path to store temporary files.<br />Used along with the <code>useTempFiles</code> option. By default this module uses 'tmp' folder in the current working directory.<br />You can use trailing slash, but it is not necessary.
parseNested | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></li></ul> | By default, req.body and req.files are flattened like this: <code>{'name': 'John', 'hobbies[0]': 'Cinema', 'hobbies[1]': 'Bike'}</code><br /><br/>When this option is enabled they are parsed in order to be nested like this: <code>{'name': 'John', 'hobbies': ['Cinema', 'Bike']}</code>

@@ -125,0 +123,0 @@ debug | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></ul> | Turn on/off upload process logging. Can be usefull for troubleshooting.

'use strict';
const assert = require('assert');
const fs = require('fs');
const md5 = require('md5');
const path = require('path');
const fileFactory = require('../lib').fileFactory;
const {isFunc} = require('../lib/utilities.js');
const assert = require('assert');
const server = require('./server');
const {isFunc} = require('../lib/utilities');
const fileFactory = require('../lib/fileFactory');
const mockFile = path.join(server.fileDir, 'basketball.png');
const mockFileName = 'basketball.png';
const mockFile = path.join(server.fileDir, mockFileName);
const mockBuffer = fs.readFileSync(mockFile);
const mockMd5 = md5(mockBuffer);
const mockFileOpts = {
name: mockFileName,
buffer: mockBuffer,
encoding: 'utf-8',
mimetype: 'image/png',
hash: mockMd5,
tempFilePath: mockFile
};
describe('Test of the fileFactory factory', function() {
beforeEach(function() {
server.clearUploadsDir();
});
beforeEach(() => server.clearUploadsDir());
it('return a file object', function() {
assert.ok(fileFactory({
name: 'basketball.png',
buffer: mockBuffer
}));
});
it('return void if buffer is empty and useTempFiles is false.', function() {
it('return a file object', () => assert.ok(fileFactory(mockFileOpts)));
it('return void if buffer is empty and useTempFiles is false.', () => {
assert.equal(fileFactory({
name: 'basketball.png',
name: mockFileName,
buffer: Buffer.concat([])
},{
}, {
useTempFiles: false

@@ -37,51 +39,20 @@ }), null);

describe('Properties', function() {
it('contains the name property', function() {
assert.equal(fileFactory({
name: 'basketball.png',
buffer: mockBuffer
}).name, 'basketball.png');
it('contains the name property', () => {
assert.equal(fileFactory(mockFileOpts).name, mockFileName);
});
it('contains the data property', function() {
assert.ok(fileFactory({
name: 'basketball.png',
buffer: mockBuffer
}).data);
it('contains the data property', () => assert.ok(fileFactory(mockFileOpts).data));
it('contains the encoding property', () => {
assert.equal(fileFactory(mockFileOpts).encoding, 'utf-8');
});
it('contains the encoding property', function() {
assert.equal(fileFactory({
name: 'basketball.png',
buffer: mockBuffer,
encoding: 'utf-8'
}).encoding, 'utf-8');
it('contains the mimetype property', () => {
assert.equal(fileFactory(mockFileOpts).mimetype, 'image/png');
});
it('contains the mimetype property', function() {
assert.equal(fileFactory({
name: 'basketball.png',
buffer: mockBuffer,
mimetype: 'image/png'
}).mimetype, 'image/png');
});
it('contains the md5 property', function() {
const mockMd5 = md5(mockBuffer);
assert.equal(fileFactory({
name: 'basketball.png',
buffer: mockBuffer,
hash: mockMd5
}).md5, mockMd5);
});
it('contains the mv method', function() {
assert.equal(isFunc(fileFactory({
name: 'basketball.png',
buffer: mockBuffer
}).mv), true);
});
it('contains the md5 property', () => assert.equal(fileFactory(mockFileOpts).md5, mockMd5));
it('contains the mv method', () => assert.equal(isFunc(fileFactory(mockFileOpts).mv), true));
});
describe('File object behavior for in memory upload', function() {
const file = fileFactory({
name: 'basketball.png',
buffer: mockBuffer
});
it('move the file to the specified folder', function(done) {
file.mv(path.join(server.uploadDir, 'basketball.png'), function(err) {
const file = fileFactory(mockFileOpts);
it('move the file to the specified folder', (done) => {
file.mv(path.join(server.uploadDir, mockFileName), (err) => {
assert.ifError(err);

@@ -91,4 +62,4 @@ done();

});
it('reject the mv if the destination does not exists', function(done) {
file.mv(path.join(server.uploadDir, 'unknown', 'basketball.png'), function(err) {
it('reject the mv if the destination does not exists', (done) => {
file.mv(path.join(server.uploadDir, 'unknown', mockFileName), (err) => {
assert.ok(err);

@@ -101,19 +72,13 @@ done();

describe('File object behavior for upload into temporary file', function() {
const file = fileFactory({
name: 'basketball.png',
buffer: mockBuffer,
tempFilePath: mockFile
});
it('move the file to the specified folder', function(done) {
file.mv(path.join(server.uploadDir, 'basketball.png'), function(err) {
if (!err){
//Place back moved file
fs.renameSync(path.join(server.uploadDir, 'basketball.png'), mockFile);
}
const file = fileFactory(mockFileOpts, { useTempFiles: true });
it('move the file to the specified folder', (done) => {
file.mv(path.join(server.uploadDir, mockFileName), (err) => {
assert.ifError(err);
// Place back moved file.
fs.renameSync(path.join(server.uploadDir, mockFileName), mockFile);
done();
});
});
it('reject the mv if the destination does not exists', function(done) {
file.mv(path.join(server.uploadDir, 'unknown', 'basketball.png'), function(err) {
it('reject the mv if the destination does not exists', (done) => {
file.mv(path.join(server.uploadDir, 'unknown', mockFileName), (err) => {
assert.ok(err);

@@ -120,0 +85,0 @@ done();

'use strict';
const assert = require('assert');
const processNested = require('../lib').processNested;
const processNested = require('../lib/processNested');
describe('Test Convert Flatten object to Nested object', function() {
it('With no nested data', function(){
it('With no nested data', () => {
const data = {

@@ -13,3 +13,3 @@ 'firstname': 'John',

},
excerpt= { firstname: 'John', lastname: 'Doe', age: 22 },
excerpt = { firstname: 'John', lastname: 'Doe', age: 22 },
processed = processNested(data);

@@ -20,3 +20,3 @@

it('With nested data', function(){
it('With nested data', () => {
const data = {

@@ -23,0 +23,0 @@ 'firstname': 'John',

@@ -177,2 +177,8 @@ 'use strict';

it('Returns a temporary file name if name argument is empty.', () => {
const opts = {safeFileNames: false};
const result = parseFileName(opts);
assert.equal(typeof result, 'string');
});
});

@@ -179,0 +185,0 @@ //buildOptions tests

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc