Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

express-fileupload

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-fileupload - npm Package Compare versions

Comparing version 1.1.1-alpha.3 to 1.1.2-alpha.1

151

lib/fileFactory.js

@@ -6,6 +6,65 @@ 'use strict';

const streamifier = require('streamifier');
const md5 = require('md5');
/**
* Returns true if argument is function.
*/
const isFunc = func => func && func.constructor && func.call && func.apply;
/**
* Creates a folder for file specified in the path variable
* @param {Object} fileUploadOptions
* @param {String} filePath
*/
const checkAndMakeDir = function(fileUploadOptions, filePath){
if (fileUploadOptions && fileUploadOptions.createParentPath) {
const parentPath = path.dirname(filePath);
if (!fs.existsSync(parentPath)) {
fs.mkdirSync(parentPath);
}
}
};
/**
* Returns Local function that moves the file to a different location on the filesystem
* which takes two function arguments to make it compatible w/ Promise or Callback APIs
* @param {String} filePath
* @param {Object} options
*/
const moveFromTemp = function(filePath, options) {
return function(successFunc, errorFunc){
// Set errorFunc to the same value as successFunc for callback mode.
errorFunc = isFunc(errorFunc) ? errorFunc : successFunc;
fs.rename(options.tempFilePath, filePath, function(err){
if (err) {
errorFunc(err);
} else {
successFunc();
}
});
};
};
/**
* Returns Local function that moves the file from buffer to a different location on the filesystem
* which takes two function arguments to make it compatible w/ Promise or Callback APIs
* @param {String} filePath
* @param {Object} options
*/
const moveFromBuffer = function(filePath, options) {
return function(successFunc, errorFunc){
// Set errorFunc to the same value as successFunc for callback mode.
errorFunc = isFunc(errorFunc) ? errorFunc : successFunc;
const fstream = fs.createWriteStream(filePath);
streamifier.createReadStream(options.buffer).pipe(fstream);
fstream.on('error', function(error) {
errorFunc(error);
});
fstream.on('close', function() {
successFunc();
});
};
};
module.exports = function(options, fileUploadOptions = null) {
const output = {
return {
name: options.name,

@@ -18,82 +77,16 @@ data: options.buffer,

mimetype: options.mimetype,
md5: () => md5(options.buffer),
md5: options.hash,
mv: function(filePath, callback) {
// Callback is passed in, use the callback API
if (callback) {
if (options.buffer.length && !options.tempFilePath) {
moveFromBuffer(
() => {
callback(null);
},
error => {
callback(error);
}
);
} else {
moveFromTemp(
() => {
callback(null);
},
error => {
callback(error);
}
);
}
// Otherwise, return a promise
} else {
return new Promise((resolve, reject) => {
if (options.buffer) {
moveFromBuffer(resolve, reject);
} else {
moveFromTemp(resolve, reject);
}
});
}
function checkAndMakeDir(){
if (fileUploadOptions && fileUploadOptions.createParentPath) {
const parentPath = path.dirname(filePath);
if (!fs.existsSync(parentPath)) {
fs.mkdirSync(parentPath);
}
}
}
/**
* Local function that moves the file to a different location on the filesystem
* Takes two function arguments to make it compatible w/ Promise or Callback APIs
* @param {Function} successFunc
* @param {Function} errorFunc
*/
function moveFromTemp(successFunc, errorFunc) {
checkAndMakeDir();
fs.rename(options.tempFilePath, filePath, function(err){
if (err) {
errorFunc(err);
} else {
successFunc();
}
});
}
function moveFromBuffer(successFunc, errorFunc) {
checkAndMakeDir();
const fstream = fs.createWriteStream(filePath);
streamifier.createReadStream(options.buffer).pipe(fstream);
fstream.on('error', function(error) {
errorFunc(error);
});
fstream.on('close', function() {
successFunc();
});
}
// Determine propper move function.
let moveFunc = (options.buffer.length && !options.tempFilePath)
? moveFromBuffer(filePath, options)
: moveFromTemp(filePath, options);
// Create a folder for file.
checkAndMakeDir(fileUploadOptions, filePath);
// If callback is passed in, use the callback API, otherwise return a promise.
return isFunc(callback)
? moveFunc(callback)
: new Promise((resolve, reject) => moveFunc(resolve, reject));
}
};
return output;
};

@@ -0,1 +1,2 @@

const crypto = require('crypto');

@@ -11,2 +12,3 @@ /**

let fileSize = 0; // eslint-disable-line
let hash = crypto.createHash('md5');

@@ -16,2 +18,3 @@ return {

buffers.push(data);
hash.update(data);
fileSize += data.length;

@@ -31,2 +34,5 @@ if (options.debug) {

},
getHash: function(){
return hash.digest('hex');
},
complete: function(){

@@ -33,0 +39,0 @@ return Buffer.concat(buffers);

@@ -56,3 +56,3 @@ const Busboy = require('busboy');

const {dataHandler, getFilePath, getFileSize, complete, cleanup} = options.useTempFiles
const {dataHandler, getFilePath, getFileSize, getHash, complete, cleanup} = options.useTempFiles
? tempFileHandler(options, fieldname, filename)

@@ -131,2 +131,3 @@ : memHandler(options, fieldname, filename);

size: getFileSize(),
hash: getHash(),
encoding,

@@ -133,0 +134,0 @@ truncated: file.truncated,

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
module.exports = function(options, fieldname, filename) {
const dir = path.normalize(options.tempFileDir || process.cwd() + '/tmp/');
let hash = crypto.createHash('md5');

@@ -17,2 +19,3 @@ if (!fs.existsSync(dir)) {

writeStream.write(data);
hash.update(data);
fileSize += data.length;

@@ -33,2 +36,10 @@ if (options.debug) {

},
getHash: function(){
return hash.digest('hex');
},
complete: function(){
writeStream.end();
//return empty buffer since data has been uploaded to the temporary file.
return Buffer.concat([]);
},
cleanup: function(){

@@ -40,8 +51,4 @@ writeStream.end();

});
},
complete: function(){
writeStream.end();
return Buffer.concat([]); //return empty buffer since uploaded to the temporary file.
}
};
};
{
"name": "express-fileupload",
"version": "1.1.1-alpha.3",
"version": "1.1.2-alpha.1",
"author": "Richard Girges <richardgirges@gmail.com>",

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

"busboy": "^0.2.14",
"md5": "^2.2.1",
"streamifier": "^0.1.1"

@@ -34,2 +33,3 @@ },

"devDependencies": {
"md5": "^2.2.1",
"body-parser": "^1.18.3",

@@ -36,0 +36,0 @@ "coveralls": "^3.0.2",

@@ -9,2 +9,7 @@ # express-fileupload

# Version 1.1.1 Breaking Changes
Breaking change to `md5` handling.
md5 again returns a hash value instead of function which compute the hash.
md5 hashes now can be used with tempFiles.
# Version 1.0.0 Breaking Changes

@@ -41,3 +46,4 @@ Breaking change to `md5` handling. [Read about it here.](https://github.com/richardgirges/express-fileupload/releases/tag/v1.0.0-alpha.1)

* `req.files.foo.truncated`: A boolean that represents if the file is over the size limit
* `req.files.foo.md5`: A function that returns an MD5 checksum of the uploaded file
* `req.files.foo.size`: Uploaded size in bytes
* `req.files.foo.md5`: MD5 checksum of the uploaded file

@@ -60,3 +66,3 @@ ### Examples

Use temp files instead of memory for managing the upload process.
Please note: md5 hashes will not be generated when using tempFiles
```javascript

@@ -63,0 +69,0 @@ app.use(fileUpload({

@@ -12,2 +12,7 @@ 'use strict';

/**
* Returns true if argument is function.
*/
const isFunc = func => (func && func.constructor && func.call && func.apply) ? true : false;
describe('Test of the fileFactory factory', function() {

@@ -75,6 +80,13 @@ beforeEach(function() {

name: 'basketball.png',
buffer: mockBuffer,
hash: mockMd5
}).md5, mockMd5);
});
it('contains the mv method', function() {
assert.equal(isFunc(fileFactory({
name: 'basketball.png',
buffer: mockBuffer
}).md5(), mockMd5);
}).mv), true);
});
});
});
'use strict';
const fs = require('fs');
const md5 = require('md5');
const path = require('path');

@@ -40,2 +41,5 @@ const request = require('supertest');

let filePath = path.join(fileDir, fileName);
let fileBuffer = fs.readFileSync(filePath);
let fileHash = md5(fileBuffer);
let fileStat = fs.statSync(filePath);
let uploadedFilePath = path.join(uploadDir, fileName);

@@ -48,3 +52,13 @@

.attach('testFile', filePath)
.expect(200)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
name: fileName,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
})
.end(function(err) {

@@ -61,2 +75,5 @@ if (err) {

let filePath = path.join(fileDir, fileName);
let fileBuffer = fs.readFileSync(filePath);
let fileHash = md5(fileBuffer);
let fileStat = fs.statSync(filePath);
let uploadedFilePath = path.join(uploadDir, fileName);

@@ -69,3 +86,13 @@

.attach('testFile', filePath)
.expect(200)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
name: fileName,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
})
.end(function(err) {

@@ -115,2 +142,5 @@ if (err) {

let filePath = path.join(fileDir, fileName);
let fileBuffer = fs.readFileSync(filePath);
let fileHash = md5(fileBuffer);
let fileStat = fs.statSync(filePath);
let uploadedFilePath = path.join(uploadDir, fileName);

@@ -123,3 +153,13 @@

.attach('testFile', filePath)
.expect(200)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
name: fileName,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
})
.end(function(err) {

@@ -136,2 +176,5 @@ if (err) {

let filePath = path.join(fileDir, fileName);
let fileBuffer = fs.readFileSync(filePath);
let fileHash = md5(fileBuffer);
let fileStat = fs.statSync(filePath);
let uploadedFilePath = path.join(uploadDir, fileName);

@@ -144,3 +187,13 @@

.attach('testFile', filePath)
.expect(200)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
name: fileName,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
})
.end(function(err) {

@@ -186,14 +239,33 @@ if (err) {

it('upload multiple files with POST', function(done) {
let upload1 = path.join(fileDir, mockFiles[0]);
let upload2 = path.join(fileDir, mockFiles[1]);
let upload3 = path.join(fileDir, mockFiles[2]);
let req = request(app).post('/upload/multiple');
clearUploadsDir();
request(app)
.post('/upload/multiple')
.attach('testFile1', upload1)
.attach('testFile2', upload2)
.attach('testFile3', upload3)
.expect(200)
let expectedResult = [];
let expectedResultSorted = [];
let uploadedFilesPath = [];
mockFiles.forEach((fileName, index) => {
let filePath = path.join(fileDir, fileName);
let fileStat = fs.statSync(filePath);
uploadedFilesPath.push(path.join(uploadDir, fileName));
expectedResult.push({
name:fileName,
md5: md5(fs.readFileSync(filePath)),
size: fileStat.size,
uploadDir: '',
uploadPath: ''
});
req.attach(`testFile${index+1}`, filePath);
});
req
.expect((res)=>{
res.body.forEach(fileInfo => {
fileInfo.uploadDir = '';
fileInfo.uploadPath = '';
let index = mockFiles.indexOf(fileInfo.name);
expectedResultSorted.push(expectedResult[index]);
});
})
.expect(200, expectedResultSorted)
.end(function(err) {

@@ -204,3 +276,3 @@ if (err) {

fs.stat(upload1, function(err) {
fs.stat(uploadedFilesPath[0], function(err) {
if (err) {

@@ -210,3 +282,3 @@ return done(err);

fs.stat(upload2, function(err) {
fs.stat(uploadedFilesPath[1], function(err) {
if (err) {

@@ -216,3 +288,3 @@ return done(err);

fs.stat(upload3, done);
fs.stat(uploadedFilesPath[2], done);
});

@@ -230,8 +302,29 @@ });

for (let i = 0; i < mockFiles.length; i++) {
req.attach('testFiles', path.join(fileDir, mockFiles[i]));
}
let expectedResult = [];
let expectedResultSorted = [];
let uploadedFilesPath = [];
mockFiles.forEach((fileName) => {
let filePath = path.join(fileDir, fileName);
let fileStat = fs.statSync(filePath);
uploadedFilesPath.push(path.join(uploadDir, fileName));
expectedResult.push({
name:fileName,
md5: md5(fs.readFileSync(filePath)),
size: fileStat.size,
uploadDir: '',
uploadPath: ''
});
req.attach('testFiles', filePath);
});
req
.expect(200)
.expect((res)=>{
res.body.forEach(fileInfo => {
fileInfo.uploadDir = '';
fileInfo.uploadPath = '';
let index = mockFiles.indexOf(fileInfo.name);
expectedResultSorted.push(expectedResult[index]);
});
})
.expect(200, expectedResultSorted)
.end(function(err) {

@@ -242,5 +335,5 @@ if (err) {

for (let i = 0; i < mockFiles.length; i++) {
fs.statSync(path.join(uploadDir, mockFiles[i]));
}
uploadedFilesPath.forEach(function(uploadedFilePath){
fs.statSync(uploadedFilePath);
});

@@ -258,2 +351,5 @@ done();

let filePath = path.join(fileDir, fileName);
let fileBuffer = fs.readFileSync(filePath);
let fileHash = md5(fileBuffer);
let fileStat = fs.statSync(filePath);
let uploadedFilePath = path.join(uploadDir, fileName);

@@ -269,6 +365,15 @@

.field('email', mockUser.email)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
firstName: mockUser.firstName,
lastName: mockUser.lastName,
email: mockUser.email
email: mockUser.email,
name: fileName,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
},

@@ -286,2 +391,6 @@ function(err) {

let filePath = path.join(fileDir, fileName);
let fileBuffer = fs.readFileSync(filePath);
let fileStat = fs.statSync(filePath);
let fileHash = md5(fileBuffer);
let uploadedFilePath = path.join(uploadDir, fileName);

@@ -297,6 +406,15 @@

.field('email', mockUser.email)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
firstName: mockUser.firstName,
lastName: mockUser.lastName,
email: mockUser.email
email: mockUser.email,
name: fileName,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
},

@@ -303,0 +421,0 @@ function(err) {

@@ -41,3 +41,10 @@ 'use strict';

res.send('File uploaded to ' + uploadPath);
//res.send('File uploaded to ' + uploadPath);
res.json({
name: testFile.name,
uploadDir: uploadDir,
uploadPath: uploadPath,
md5: testFile.md5,
size: testFile.size
});
});

@@ -57,3 +64,9 @@ });

.then(() => {
res.send('File uploaded to ' + uploadPath);
res.json({
name: testFile.name,
uploadDir: uploadDir,
uploadPath: uploadPath,
md5: testFile.md5,
size: testFile.size
});
})

@@ -97,3 +110,8 @@ .catch(err => {

lastName: req.body.lastName,
email: req.body.email
email: req.body.email,
name: testFile.name,
uploadDir: uploadDir,
uploadPath: uploadPath,
md5: testFile.md5,
size: testFile.size
});

@@ -155,3 +173,26 @@ });

res.send('Files uploaded to ' + uploadDir);
//res.send('Files uploaded to ' + uploadDir);
res.json([
{
name: testFile1.name,
uploadDir: uploadDir,
uploadPath: uploadPath1,
md5: testFile1.md5,
size: testFile1.size
},
{
name: testFile2.name,
uploadDir: uploadDir,
uploadPath: uploadPath2,
md5: testFile2.md5,
size: testFile2.size
},
{
name: testFile2.name,
uploadDir: uploadDir,
uploadPath: uploadPath2,
md5: testFile2.md5,
size: testFile2.size
}
]);
});

@@ -181,3 +222,3 @@ });

let filesUploaded = 0;
let uploadResults = [];
for (let i = 0; i < testFiles.length; i++) {

@@ -191,4 +232,12 @@ let uploadPath = path.join(uploadDir, testFiles[i].name);

if (++filesUploaded === testFiles.length) {
res.send('File uploaded to ' + uploadPath);
uploadResults.push({
name: testFiles[i].name,
uploadDir: uploadDir,
uploadPath: uploadPath,
md5: testFiles[i].md5,
size: testFiles[i].size
});
if (uploadResults.length === testFiles.length) {
res.json(uploadResults);
}

@@ -195,0 +244,0 @@ });

const fs = require('fs');
const md5 = require('md5');
const path = require('path');

@@ -29,2 +30,9 @@ const request = require('supertest');

) {
let filePath = path.join(fileDir, actualFileNameToUpload);
let fileBuffer = fs.readFileSync(filePath);
let fileHash = md5(fileBuffer);
let fileStat = fs.statSync(filePath);
let uploadedFilePath = path.join(uploadDir, expectedFileNameOnFileSystem);
request(

@@ -34,10 +42,14 @@ server.setup(options)

.post('/upload/single')
.attach(
'testFile',
path.join(
fileDir,
actualFileNameToUpload
)
)
.expect(200)
.attach('testFile', filePath)
.expect((res)=>{
res.body.uploadDir = '';
res.body.uploadPath = '';
})
.expect(200, {
name: expectedFileNameOnFileSystem,
md5: fileHash,
size: fileStat.size,
uploadDir: '',
uploadPath: ''
})
.end(function(err) {

@@ -47,10 +59,4 @@ if (err) {

}
const uploadedFilePath = path.join(
uploadDir,
expectedFileNameOnFileSystem
);
fs.stat(
uploadedFilePath,
done
);
fs.stat(uploadedFilePath, done);
});

@@ -57,0 +63,0 @@ }

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc