UNPKG

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
/*jslint node: true*/ "use strict"; /** * 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 }); } }); }