blueimp-file-uploader-express
Version:
This is a File Uploader for Node.js, the project is based on Blueimp jQuery File Upload developed by Sebastian Tschan.
240 lines (205 loc) • 7.61 kB
JavaScript
/*jslint node: true*/
;
/**
* Required Modules
*/
var fs = require("fs"),
AWS = require("aws-sdk"),
FileInfo = require("../fileinfo.js")
;
/**
* AWS transport
*
* @param {Object} opts
* @param {Object} opts.storage
* @param {Object} opts.storage.aws
* @param {string} opts.storage.aws.accessKeyId
* @param {string} opts.storage.aws.secretAccessKey
* @param {string} opts.storage.aws.region
* @param {string} opts.storage.aws.bucketName
* @param {string} opts.storage.aws.acl
* @param {string} [opts.storage.aws.cacheControl] - Sets the S3 CacheControl param.
* @param {Number} [opts.storage.aws.expiresInMilliseconds] - Sets the S3
* Expires param with expiresInMilliseconds from the current time
* @param {boolean} [opts.storage.aws.getSignedUrl=true] - If set to true, the
* upload callback will pass a signed URL of the file, that will expire in
* signedUrlExpiresSeconds if set (default 900s = 15m). If set to false, the
* callback will pass the actual URL. More info about the signed URL here:
* http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
* @param {boolean} [opts.storage.aws.signedUrlExpiresSeconds=900] - For use
* with getSignedUrl=true.
* @param {string} [opts.storage.aws.path] - Path on bucket to store uploads
*
* @example
* awsTransport({
* storage: {
* type: "aws",
* aws: {
* accessKeyId: "...",
* secretAccessKey: "...",
* region: "us-west-2",
* bucketName: "...",
* acl: "public-read",
* cacheControl: "max-age=630720000, public",
* expiresInMilliseconds: 63072000000,
* getSignedUrl: false,
* path: "uploads/"
* }
* }
* });
*/
module.exports = function(opts) {
var configs = opts.storage.aws;
// init aws
AWS.config.update({
accessKeyId: configs.accessKeyId,
secretAccessKey: configs.secretAccessKey
});
if (configs.region) {
AWS.config.region = configs.region;
}
var api = {
s3: new AWS.S3({ computeChecksums: true }),
configs: configs,
options: opts,
upload: function(fileName, filePath, callback) {
uploadFile(this.s3, fileName, filePath, this.configs, callback);
},
/**
* get files
*/
get: function(callback) {
var params = {
Bucket: api.configs.bucketName // required
//Delimiter: "STRING_VALUE",
//EncodingType: "url",
//Marker: "STRING_VALUE",
//MaxKeys: 0,
//Prefix: "STRING_VALUE",
},
files = [],
options = this.options
;
api.s3.listObjects(params, function(err, data) {
if (err) {
console.log(err, err.stack);
return callback(err);
}
data.Contents.forEach(function(o) {
var awsFileObj = {
url: (options.useSSL ? "https:" : "http:") + "//s3.amazonaws.com/" + configs.bucketName + "/" + o.Key
};
/**
* In order to get the filename without the hash, eg: image.png just use this variable instead of o.Key:
* var fileName = options.UUIDRegex.test(o.Key) ? o.Key.split("__")[1] : o.Key;
*/
var fileInfo = new FileInfo({
name: o.Key,
size: o.Size,
awsFile: awsFileObj
}, options);
fileInfo.initUrls();
files.push(fileInfo);
});
callback(null, { files: files });
});
},
post: function(fileInfo, file, finish) {
this.upload(fileInfo.name, file.path, function(error, awsFile) {
if (!error) {
fileInfo.awsFile = awsFile;
fileInfo.proccessed = true;
fileInfo.initUrls();
}
finish(error, fileInfo);
});
},
delete: function(req, res, callback) {
var keyVal;
if (req.params.directory) {
keyVal = req.params.directory + "/" + req.params.name;
} else {
keyVal = req.params.name;
}
var params = {
Bucket: api.options.storage.aws.bucketName, // required
Key: keyVal // required
};
api.s3.deleteObject(params, function(err, data) {
if (err) {
console.log(err, err.stack);
return callback(err);
}
console.log(data); // successful response
callback(null, data);
});
}
};
return api;
};
/**
* AWS Random UUID
* https://gist.github.com/jed/982883#file-index-js
*/
function getRandomUUID(a) {
return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, getRandomUUID);
}
function getContentTypeByFile(fileName) {
var rc = "application/octet-stream";
var fn = fileName.toLowerCase();
if (fn.indexOf(".html") >= 0) {
rc = "text/html";
} else if (fn.indexOf(".css") >= 0) {
rc = "text/css";
} else if (fn.indexOf(".json") >= 0) {
rc = "application/json";
} else if (fn.indexOf(".js") >= 0) {
rc = "application/x-javascript";
} else if (fn.indexOf(".png") >= 0) {
rc = "image/png";
} else if (fn.indexOf(".jpg") >= 0) {
rc = "image/jpg";
}
return rc;
}
function uploadFile(s3, fileName, filePath, opts, callback) {
var fileBuffer = fs.readFileSync(filePath),
metaData = getContentTypeByFile(fileName),
remoteFilename = getRandomUUID() + "__" + fileName,
params = {
ACL: opts.acl,
Bucket: opts.bucketName,
Key: (opts.path || "") + remoteFilename,
Body: fileBuffer,
ContentType: metaData
},
url,
_url
;
// consider setting params.CacheControl by default to 'max-age=630720000, public'
if (typeof opts.cacheControl !== "undefined") {
params.CacheControl = opts.cacheControl;
}
// consider setting params.Expires by default to new Date(Date.now() + 63072000000)
if (typeof opts.expiresInMilliseconds !== "undefined") {
params.Expires = new Date(Date.now() + opts.expiresInMilliseconds);
}
s3.putObject(params, function(error) {
if (typeof opts.getSignedUrl === "undefined") {
/**
* Documentation for: getSignedUrl
* https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
*/
url = s3.getSignedUrl("getObject", {
Bucket: opts.bucketName,
Key: (opts.path || "") + remoteFilename,
Expires: opts.signedUrlExpires || 900
});
_url = url.split("?")[0];
callback(error, { url: _url });
} else {
url = s3.endpoint.href + opts.bucketName + "/" + opts.path + remoteFilename;
callback(error, { url: url });
}
});
}