diff --git a/README.md b/README.md
index 0f6e3a6..e87fbbe 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,7 @@ Pass in non-Busboy options directly to the middleware. These are express-fileupl
Option | Acceptable Values | Details
--- | --- | ---
safeFileNames |
false
**(default)**true
- regex
| Strips characters from the upload's filename. You can use custom regex to determine what to strip. If set to `true`, non-alphanumeric characters _except_ dashes and underscores will be stripped. This option is off by default.
**Example #1 (strip slashes from file names):** `app.use(fileUpload({ safeFileNames: /\\/g }))`
**Example #2:** `app.use(fileUpload({ safeFileNames: true }))`
-preserveExtension | false
**(default)**true
*Number*
| Preserves filename extension when using safeFileNames
option. If set to true
, will default to an extension length of 3. If set to *Number*
, this will be the max allowable extension length. If an extension is smaller than the extension length, it remains untouched. If the extension is longer, it is shifted.
**Example #1 (true):**
app.use(fileUpload({ safeFileNames: true, preserveExtension: true }));
*myFileName.ext* --> *myFileName.ext*
**Example #2 (max extension length 2, extension truncated):**
app.use(fileUpload({ safeFileNames: true, preserveExtension: 2 }));
*myFileName.ext* --> *myFileNamee.xt*
+preserveExtension | false
**(default)**true
*Number*
| Preserves filename extension when using safeFileNames
option. If set to true
, will default to an extension length of 3. If set to *Number*
, this will be the max allowable extension length. If an extension is smaller than the extension length, it remains untouched. If the extension is longer, it is shifted.
**Example #1 (true):**
app.use(fileUpload({ safeFileNames: true, preserveExtension: true }));
*myFileName.ext* --> *myFileName.ext*
**Example #2 (max extension length 2, extension shifted):**
app.use(fileUpload({ safeFileNames: true, preserveExtension: 2 }));
*myFileName.ext* --> *myFileNamee.xt*
# Help Wanted
Pull Requests are welcomed!
diff --git a/package.json b/package.json
index cb8731a..a620ca3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "express-fileupload",
- "version": "0.1.2",
+ "version": "0.1.3",
"author": "Richard Girges ",
"description": "Simple express file upload middleware that wraps around Busboy",
"main": "./lib/index",
diff --git a/test/files/basket.ball.bp b/test/files/basket.ball.bp
new file mode 100644
index 0000000..a2a1571
Binary files /dev/null and b/test/files/basket.ball.bp differ
diff --git a/test/files/my$Invalid#fileName.png123 b/test/files/my$Invalid#fileName.png123
new file mode 100644
index 0000000..510b859
Binary files /dev/null and b/test/files/my$Invalid#fileName.png123 differ
diff --git a/test/multipartFields.spec.js b/test/multipartFields.spec.js
index 034164e..bbddfe6 100644
--- a/test/multipartFields.spec.js
+++ b/test/multipartFields.spec.js
@@ -2,7 +2,7 @@
const request = require('supertest');
const server = require('./server');
-const app = server.app;
+const app = server.setup();
let mockUser = {
firstName: 'Joe',
diff --git a/test/multipartUploads.spec.js b/test/multipartUploads.spec.js
index 0dc1e1c..4e69f5b 100644
--- a/test/multipartUploads.spec.js
+++ b/test/multipartUploads.spec.js
@@ -4,7 +4,7 @@ const fs = require('fs');
const path = require('path');
const request = require('supertest');
const server = require('./server');
-const app = server.app;
+const app = server.setup();
const clearUploadsDir = server.clearUploadsDir;
const fileDir = server.fileDir;
const uploadDir = server.uploadDir;
@@ -212,4 +212,4 @@ describe('Test Upload With Fields', function() {
});
});
}
-});
+});
\ No newline at end of file
diff --git a/test/options.spec.js b/test/options.spec.js
new file mode 100644
index 0000000..32e49c5
--- /dev/null
+++ b/test/options.spec.js
@@ -0,0 +1,151 @@
+const fs = require('fs');
+const path = require('path');
+const request = require('supertest');
+const server = require('./server');
+// const clearUploadsDir = server.clearUploadsDir;
+const fileDir = server.fileDir;
+const uploadDir = server.uploadDir;
+
+describe('SafeFileNames', function() {
+ it(`Does nothing to your filename when disabled.`, function(done) {
+ const app = server.setup({safeFileNames: false});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'my$Invalid#fileName.png123'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'my$Invalid#fileName.png123');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+
+ it(`Strips away all illegal characters (including spaces) when enabled.`, function(done) {
+ const app = server.setup({safeFileNames: true});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'my$Invalid#fileName.png123'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'myInvalidfileNamepng123');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+
+ it(`Respects a regex for stripping 'invalid' characters from filename.`, function(done) {
+ const app = server.setup({safeFileNames: /[\$#]/g});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'my$Invalid#fileName.png123'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'myInvalidfileName.png123');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+});
+
+describe(`preserveExtension`, function() {
+ it(`Does nothing to your filename when disabled.`, function(done) {
+ const app = server.setup({safeFileNames: true, preserveExtension: false});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'my$Invalid#fileName.png123'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'myInvalidfileNamepng123');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+
+ it(`Shortens your extension to the default(3) when enabled, if the extension found is larger`,
+ function(done) {
+ const app = server.setup({safeFileNames: true, preserveExtension: true});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'my$Invalid#fileName.png123'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'myInvalidfileNamepng.123');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+
+ it(`Leaves your extension alone when enabled, if the extension found is <= default(3) length`,
+ function(done) {
+ const app = server.setup({safeFileNames: true, preserveExtension: true});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'car.png'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'car.png');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+
+ it(`Leaves your extension alone when set to a number >= the extension length.`,
+ function(done) {
+ const app = server.setup({safeFileNames: true, preserveExtension: 7});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'my$Invalid#fileName.png123'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'myInvalidfileName.png123');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+
+ it(`Only considers the last dotted part the extension.`,
+ function(done) {
+ const app = server.setup({safeFileNames: true, preserveExtension: true});
+
+ request(app)
+ .post('/upload/single')
+ .attach('testFile', path.join(fileDir, 'basket.ball.bp'))
+ .expect(200)
+ .end(function(err, res) {
+ if (err)
+ return done(err);
+
+ let uploadedFilePath = path.join(uploadDir, 'basketball.bp');
+
+ fs.stat(uploadedFilePath, done);
+ });
+ });
+});
diff --git a/test/server.js b/test/server.js
index 41a80b7..7d014fe 100644
--- a/test/server.js
+++ b/test/server.js
@@ -1,14 +1,8 @@
'use strict';
-
-const fs = require('fs-extra');
const path = require('path');
-const express = require('express');
-const expressFileupload = require('../lib/index');
-
const fileDir = path.join(__dirname, 'files');
const uploadDir = path.join(__dirname, 'uploads');
-
-const app = express();
+const fs = require('fs-extra');
const clearUploadsDir = function() {
if (!fs.existsSync(uploadDir)) {
@@ -18,157 +12,166 @@ const clearUploadsDir = function() {
}
};
-app.use(expressFileupload());
+var setup = function(fileUploadOptions) {
+ const express = require('express');
+ const expressFileupload = require('../lib/index');
-app.all('/upload/single', function(req, res) {
- if (!req.files)
- return res.status(400).send('No files were uploaded.');
+ const app = express();
- let testFile = req.files.testFile;
- let uploadPath = path.join(uploadDir, testFile.name);
+ fileUploadOptions = fileUploadOptions || {};
+ app.use(expressFileupload(fileUploadOptions));
- testFile.mv(uploadPath, function(err) {
- if (err)
- return res.status(500).send(err);
+ app.all('/upload/single', function(req, res) {
+ if (!req.files)
+ return res.status(400).send('No files were uploaded.');
+
+ let testFile = req.files.testFile;
+ let uploadPath = path.join(uploadDir, testFile.name);
+
+ testFile.mv(uploadPath, function (err) {
+ if (err)
+ return res.status(500).send(err);
- res.send('File uploaded to ' + uploadPath);
+ res.send('File uploaded to ' + uploadPath);
+ });
});
-});
-app.all('/upload/single/withfields', function(req, res) {
- if (!req.files)
- return res.status(400).send('No files were uploaded.');
+ app.all('/upload/single/withfields', function(req, res) {
+ if (!req.files)
+ return res.status(400).send('No files were uploaded.');
- if (!req.body)
- return res.status(400).send('No request body found');
+ if (!req.body)
+ return res.status(400).send('No request body found');
- if (!req.body.firstName || !req.body.firstName.trim())
- return res.status(400).send('Invalid first name');
+ if (!req.body.firstName || !req.body.firstName.trim())
+ return res.status(400).send('Invalid first name');
- if (!req.body.lastName || !req.body.lastName.trim())
- return res.status(400).send('Invalid last name');
+ if (!req.body.lastName || !req.body.lastName.trim())
+ return res.status(400).send('Invalid last name');
- if (!req.body.email || !req.body.email.trim())
- return res.status(400).send('Invalid email');
+ if (!req.body.email || !req.body.email.trim())
+ return res.status(400).send('Invalid email');
- let testFile = req.files.testFile;
- let uploadPath = path.join(uploadDir, testFile.name);
+ let testFile = req.files.testFile;
+ let uploadPath = path.join(uploadDir, testFile.name);
- testFile.mv(uploadPath, function(err) {
- if (err)
- return res.status(500).send(err);
+ testFile.mv(uploadPath, function (err) {
+ if (err)
+ return res.status(500).send(err);
- res.json({
- firstName: req.body.firstName,
- lastName: req.body.lastName,
- email: req.body.email
+ res.json({
+ firstName: req.body.firstName,
+ lastName: req.body.lastName,
+ email: req.body.email
+ });
});
});
-});
-app.all('/upload/multiple', function(req, res) {
- if (!req.files)
- return res.status(400).send('No files were uploaded.');
+ app.all('/upload/multiple', function(req, res) {
+ if (!req.files)
+ return res.status(400).send('No files were uploaded.');
- let testFile1 = req.files.testFile1;
- let testFile2 = req.files.testFile2;
- let testFile3 = req.files.testFile3;
- let uploadPath1 = path.join(uploadDir, testFile1.name);
- let uploadPath2 = path.join(uploadDir, testFile2.name);
- let uploadPath3 = path.join(uploadDir, testFile3.name);
+ let testFile1 = req.files.testFile1;
+ let testFile2 = req.files.testFile2;
+ let testFile3 = req.files.testFile3;
+ let uploadPath1 = path.join(uploadDir, testFile1.name);
+ let uploadPath2 = path.join(uploadDir, testFile2.name);
+ let uploadPath3 = path.join(uploadDir, testFile3.name);
- if (!testFile1)
- return res.status(400).send('testFile1 was not uploaded');
+ if (!testFile1)
+ return res.status(400).send('testFile1 was not uploaded');
- if (!testFile2)
- return res.status(400).send('testFile2 was not uploaded');
+ if (!testFile2)
+ return res.status(400).send('testFile2 was not uploaded');
- if (!testFile3)
- return res.status(400).send('testFile3 was not uploaded');
+ if (!testFile3)
+ return res.status(400).send('testFile3 was not uploaded');
- testFile1.mv(uploadPath1, function(err) {
- if (err)
- return res.status(500).send(err);
-
- testFile2.mv(uploadPath2, function(err) {
+ testFile1.mv(uploadPath1, function (err) {
if (err)
return res.status(500).send(err);
- testFile3.mv(uploadPath3, function(err) {
+ testFile2.mv(uploadPath2, function (err) {
if (err)
return res.status(500).send(err);
- res.send('Files uploaded to ' + uploadDir);
+ testFile3.mv(uploadPath3, function (err) {
+ if (err)
+ return res.status(500).send(err);
+
+ res.send('Files uploaded to ' + uploadDir);
+ });
});
});
});
-});
-app.all('/upload/array', function(req, res) {
- if (!req.files)
- return res.status(400).send('No files were uploaded.');
+ app.all('/upload/array', function(req, res) {
+ if (!req.files)
+ return res.status(400).send('No files were uploaded.');
- let testFiles = req.files.testFiles;
+ let testFiles = req.files.testFiles;
- if (!testFiles)
- return res.status(400).send('No files were uploaded');
+ if (!testFiles)
+ return res.status(400).send('No files were uploaded');
- if (!Array.isArray(testFiles))
- return res.status(400).send('Files were not uploaded as an array');
+ if (!Array.isArray(testFiles))
+ return res.status(400).send('Files were not uploaded as an array');
- if (!testFiles.length)
- return res.status(400).send('Files array is empty');
+ if (!testFiles.length)
+ return res.status(400).send('Files array is empty');
- let filesUploaded = 0;
- for (let i = 0; i < testFiles.length; i++) {
- let uploadPath = path.join(uploadDir, testFiles[i].name);
+ let filesUploaded = 0;
+ for (let i = 0; i < testFiles.length; i++) {
+ let uploadPath = path.join(uploadDir, testFiles[i].name);
- testFiles[i].mv(uploadPath, function(err) {
- if (err)
- return res.status(500).send(err);
+ testFiles[i].mv(uploadPath, function (err) {
+ if (err)
+ return res.status(500).send(err);
- if (++filesUploaded === testFiles.length)
- res.send('File uploaded to ' + uploadPath);
- });
- }
-});
+ if (++filesUploaded === testFiles.length)
+ res.send('File uploaded to ' + uploadPath);
+ });
+ }
+ });
-app.all('/fields/user', function(req, res) {
- if (!req.body)
- return res.status(400).send('No request body found');
+ app.all('/fields/user', function(req, res) {
+ if (!req.body)
+ return res.status(400).send('No request body found');
- if (!req.body.firstName || !req.body.firstName.trim())
- return res.status(400).send('Invalid first name');
+ if (!req.body.firstName || !req.body.firstName.trim())
+ return res.status(400).send('Invalid first name');
- if (!req.body.lastName || !req.body.lastName.trim())
- return res.status(400).send('Invalid last name');
+ if (!req.body.lastName || !req.body.lastName.trim())
+ return res.status(400).send('Invalid last name');
- if (!req.body.email || !req.body.email.trim())
- return res.status(400).send('Invalid email');
+ if (!req.body.email || !req.body.email.trim())
+ return res.status(400).send('Invalid email');
- res.json({
- firstName: req.body.firstName,
- lastName: req.body.lastName,
- email: req.body.email
+ res.json({
+ firstName: req.body.firstName,
+ lastName: req.body.lastName,
+ email: req.body.email
+ });
});
-});
-app.all('/fields/array', function(req, res) {
- if (!req.body)
- return res.status(400).send('No request body found');
+ app.all('/fields/array', function(req, res) {
+ if (!req.body)
+ return res.status(400).send('No request body found');
- if (!req.body.testField)
- return res.status(400).send('Invalid field');
+ if (!req.body.testField)
+ return res.status(400).send('Invalid field');
- if (!Array.isArray(req.body.testField))
- return res.status(400).send('Field is not an array');
+ if (!Array.isArray(req.body.testField))
+ return res.status(400).send('Field is not an array');
- res.json(req.body.testField);
-});
+ res.json(req.body.testField);
+ });
+ return app;
+};
module.exports = {
- app,
+ setup,
fileDir,
uploadDir,
clearUploadsDir