New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

express-form-post

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-form-post - npm Package Compare versions

Comparing version 1.0.29 to 1.0.30

lib/attachListeners.js

226

index.js
"use strict";
const path = require("path");
const Busboy = require("busboy");
const hasha = require("hasha");
const fileHandler = require("./lib/fileHandler");
const attachListeners = require("./lib/attachListeners");

@@ -22,5 +23,3 @@ const ExpressFormPost = function(user_options = {}) {

if(user_options.validateBody) {
if(typeof user_options.validateBody != "function") {
throw new Error("option validateBody must be a function.");
}
if(typeof user_options.validateBody != "function") throw new Error("option validateBody must be a function.");
} else {

@@ -31,8 +30,6 @@ user_options.validateBody = (handlePromise) => handlePromise();

// max file size
if(user_options.maxfileSize) {
if(!Number.isInteger(user_options.maxfileSize)) {
throw new Error("option 'maxfileSize' must be an integer (Measured in bytes).");
}
if(user_options.maxfileSize && !Number.isInteger(user_options.maxfileSize)) {
throw new Error("option 'maxfileSize' must be an integer.");
}
// Available storage methods

@@ -43,3 +40,4 @@ if(!["disk", "aws-s3", "dropbox"].includes(user_options.store)) {

} else {
throw new Error("storage " + user_options.store + " is not supported by express-form-post");
throw new Error("storage " + user_options.store + " is not supported by express-form-post.\n"
+ "\tCurrently available: ['disk', 'aws-s3', 'dropbox']");
}

@@ -63,3 +61,2 @@ }

};
} else {

@@ -69,3 +66,3 @@ switch(user_options.filename) {

case "":
user_options.filename = (originalname) => { return hasha(originalname); };
user_options.filename = (originalname) => { return hasha(Date.now() + originalname); };
break;

@@ -78,3 +75,3 @@ default:

this.options = {
this.opts = {
store: user_options.store,

@@ -90,11 +87,11 @@ directory: user_options.directory,

this.storeMethod = require(path.join(__dirname, "lib", this.options.store));
this.storeMethod = require(path.join(__dirname, "lib/store", this.opts.store));
// set up abi objects here so we won't have to recreate upon sending buffer to store handler
switch(this.options.store){
switch(this.opts.store){
case "aws-s3":{
let aws = require("aws-sdk");
aws.config.update({
accessKeyId: this.options.api.accessKeyId,
secretAccessKey: this.options.api.secretAccessKey,
accessKeyId: this.opts.api.accessKeyId,
secretAccessKey: this.opts.api.secretAccessKey,
});

@@ -107,5 +104,5 @@ this.apiObject = new aws.S3();

this.apiObject = new Dropbox({
accessToken: this.options.api.accessToken,
clientId: this.options.api.clientId,
selectUser: this.options.api.selectUser,
accessToken: this.opts.api.accessToken,
clientId: this.opts.api.clientId,
selectUser: this.opts.api.selectUser,
});

@@ -119,190 +116,5 @@ break;

ExpressFormPost.prototype._attachListeners = function(busboy, req) {
ExpressFormPost.prototype._fileHandler = fileHandler;
ExpressFormPost.prototype._attachListeners = attachListeners;
busboy.on("file", (fieldname, file, originalname, encoding, mimetype) => {
// emit 'end' event on file skip attaching listeners
if(originalname == "" || req.efp._finished || req.efp._data[fieldname] != undefined) return file.resume();
// Busboy emits limit event before my file listeners can reach it
file.on("limit", () => {
!req.efp._finished ? (
this.removeUploads(),
this.handleError(new Error("File limit reached on file"))
): "";
});
new Promise((resolve, reject) => {
// handlePromise is cb in function declaration
const handlePromise = (valid) => {
valid == false ? reject((new Error("Validation error by custom validateFile function"))) : (
resolve()
);
};
this.options.validateFile(handlePromise, fieldname, mimetype);
})
.then(() => {
// user may use filename function but incorrectly return nothing. no warning supplied. defaults to hash
let save_filename = this.options.filename(originalname, fieldname, mimetype);
typeof save_filename == "string" && save_filename.length > 0 ? "" : save_filename = hasha(originalname);
save_filename.includes("/") ? (
this.options.directory = path.join(this.options.directory, save_filename, ".."),
save_filename = path.basename(path.resolve(...(save_filename.split("/"))))
): "";
let uploadInfo = {
directory: this.options.directory,
filename: save_filename,
mimetype: mimetype,
fieldname: fieldname,
file: file,
encoding: encoding,
api: this.options.api,
apiObject: this.apiObject
};
// init duplex stream (read/writable) or concat-stream depending on store method
this.storeMethod(uploadInfo, req, this.finished, this.handleError)
.then((file_contents) => {
req.efp.streams[fieldname] = file_contents;
req.efp._data[fieldname] = 0; // initialize the stream size tracker
file.on("data", (data) => {
if(!req.efp._finished) {
req.efp._data[fieldname] += data.length;
file_contents.write(data);
}
});
})
.catch((err) => {
this.handleError(err);
})
})
.catch((err) => {
this.removeUploads();
this.handleError(err);
return file.resume(); // emit 'end' event on file for busboy 'finish' prevents infinite piping for req
});
});
busboy.on("field", (fieldname, val, fieldnameTruncated, valTruncated) => {
// Possibly should add some handler for if a certain value was truncated
!req.efp._finished && !valTruncated && !fieldnameTruncated ? req.body[fieldname] = val : "";
});
busboy.on("finish", () => {
req.efp.busboy._finished = true;
if(req.efp._finished) return;
new Promise((resolve, reject) => {
const handlePromise = (flag) => {
flag == false ? reject(new Error("Validation failed on validateBody function")) : resolve();
};
this.options.validateBody(handlePromise, req.body);
})
.then(() => {
// streams and _data use the same keys and map to different info of same file
for(var key in req.efp.streams) {
if(this.options.minfileSize > req.efp._data[key]) {
this.removeUploads();
return this.handleError(new Error("Uploaded file was smaller than minfileSize"));
}
req.efp.streams[key].end();
}
return this.finished(); // If there was no files this triggers properly, otherwise it is called when ending streams
})
.catch((err) => {
this.removeUploads();
return this.handleError(err);
});
});
};
ExpressFormPost.prototype._fileHandler = function(req, res, cb) {
if(req.method == "POST") {
if(req._body) return cb();
/*
* _validFile defaults to true and becomes false if the file being uploaded is not valid
* _finished is false by default and set to true if efp has "finished". Usually this just means that
* the next middleware has been called already and further calls to finished and handleError does nothing
* efp.busboy._finished is false by default and true if busboy is done parsing
* _data tracks if a file field has transmitted data (or has contents).
* ^^ this is set to avoid errors with concat-stream empty buffers
*/
req.efp = { _validFile: true, _finished: false, _data: {}, busboy: { _finished: false }, streams: {}};
req.body = {};
req._body = true; // prevent multiple multipart middleware and body-parser from colliding
req.files = {};
/*
* In middleware, this.finished passes on to next middleware
* Validation checking in this.finished because of upload function cb not next param in middleware
* In upload function, this.finished will be the callback with an err parameter. (err be undefined)
* this.finished will be called when finished with parsing the request to pass on to the cb action
* buffers array holds file contents that should be sent to the store if the body is valid
*/
this.next = cb; // for middleware usage
this.finished = function(err) {
if(req.efp._finished) return;
if(err) {
req.efp._finished = true;
return cb(err); // only gets called when upload is being used and as handleError
}
if(Object.keys(req.files).length == Object.keys(req.efp._data).length && req.efp.busboy._finished) {
// all files that were sent to the store have been uploaded and busboy is done parsing
req.efp._finished = true;
return cb();
}
};
// make sure this is called before handleError call
this.removeUploads = function() {
if(req.efp._finished) return;
req.body = {};
for(var key in req.efp.streams) {
req.efp.streams[key].emit("destroy");
}
};
/*
* A call to this.handleError will nullify any subsequent calls to this.finished and this.handleError
* 1st expr resolves to middleware and 2nd to upload
*/
this.handleError ? (
// User input based handle Error assignment - handleError could resolve to something not
// a function if the user input is incorrect. ignore if so
typeof this.middleware.handleError == "function" ? (
this.handleError = (err) => {
!req.efp._finished? (
req.efp._finished = true,
this.middleware.handleError(err),
this.next()
) : "";
}
) : (
this.handleError = () => {
!req.efp._finished ? (
req.efp._finished = true,
this.next()
): "";
}
)
) : this.handleError = this.finished;
try {
var busboy = new Busboy({
headers: req.headers,
limits: {
fileSize: this.options.maxfileSize
}
});
this._attachListeners(busboy, req);
req.pipe(busboy);
} catch(err) {
this.handleError(err);
}
} else {
return cb();
}
};
ExpressFormPost.prototype.fields = function() {

@@ -309,0 +121,0 @@ return require("./lib/fields").bind(this);

{
"name": "express-form-post",
"version": "1.0.29",
"version": "1.0.30",
"description": "Simple, reliable express http file and post body handler.",

@@ -5,0 +5,0 @@ "main": "index.js",

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