From af4edfef1642f6febb736ea112769c63374604cd Mon Sep 17 00:00:00 2001 From: Abhinav Adduri Date: Tue, 6 Jun 2017 10:24:58 -0700 Subject: [PATCH] working s3 integration, commented out load credentials from json --- frontend/src/fileReceiver.js | 3 - frontend/src/fileSender.js | 5 +- frontend/src/upload.js | 3 +- package.json | 5 +- server/config.js | 30 ++++--- server/portal_server.js | 156 ++++++++++++++++++++--------------- 6 files changed, 116 insertions(+), 86 deletions(-) diff --git a/frontend/src/fileReceiver.js b/frontend/src/fileReceiver.js index 14a539ea..a1a50457 100644 --- a/frontend/src/fileReceiver.js +++ b/frontend/src/fileReceiver.js @@ -5,7 +5,6 @@ class FileReceiver extends EventEmitter { constructor() { super(); this.salt = strToIv(location.pathname.slice(10, -1)); - window.salt = this.salt; } download() { @@ -31,8 +30,6 @@ class FileReceiver extends EventEmitter { let blob = new Blob([this.response]); let fileReader = new FileReader(); fileReader.onload = function() { - window.data = this.result; - console.log(this.result); resolve({ data: this.result, fname: xhr diff --git a/frontend/src/fileSender.js b/frontend/src/fileSender.js index 776bddb0..69fe597a 100644 --- a/frontend/src/fileSender.js +++ b/frontend/src/fileSender.js @@ -85,10 +85,13 @@ class FileSender extends EventEmitter { xhr.onreadystatechange = () => { if (xhr.readyState == XMLHttpRequest.DONE) { + // uuid field and url field + let responseObj = JSON.parse(xhr.responseText); resolve({ + url: responseObj.url, fileId: fileId, secretKey: keydata.k, - deleteToken: xhr.responseText + deleteToken: responseObj.uuid }); } }; diff --git a/frontend/src/upload.js b/frontend/src/upload.js index 2c478610..40ee4b90 100644 --- a/frontend/src/upload.js +++ b/frontend/src/upload.js @@ -58,8 +58,7 @@ $(document).ready(function() { progress.innerText = `Progress: ${percentComplete}%`; }); fileSender.upload().then(info => { - const url = `${window.location - .origin}/download/${info.fileId}/#${info.secretKey}`; + const url = info.url.trim() + `#${info.secretKey}`.trim(); $('#link').attr('value', url); link.innerHTML = url; localStorage.setItem(info.fileId, info.deleteToken); diff --git a/package.json b/package.json index 229f13e7..885f6213 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ "convict": "^3.0.0", "express": "^4.15.3", "fs-extra": "^3.0.1", + "node-fetch": "^1.7.1", "path": "^0.12.7", "redis": "^2.7.1" }, "devDependencies": { "browserify": "^14.4.0", + "cross-env": "^5.0.0", "prettier": "^1.3.1", "watchify": "^3.9.0" }, @@ -22,7 +24,8 @@ "repository": "mozilla/something-awesome", "scripts": { "format": "prettier --single-quote --write 'frontend/src/*.js' 'server/*.js'", - "start": "watchify frontend/src/main.js -o public/bundle.js -d | node server/portal_server.js", + "dev": "watchify frontend/src/main.js -o public/bundle.js -d | node server/portal_server.js", + "start": "watchify frontend/src/main.js -o public/bundle.js -d | cross-env NODE_ENV=production node server/portal_server.js", "test": "echo \"Error: no test specified\" && exit 1" } } diff --git a/server/config.js b/server/config.js index 43860f77..92095fb4 100644 --- a/server/config.js +++ b/server/config.js @@ -1,16 +1,22 @@ const convict = require('convict'); +let api_key = 'INSERT API KEY HERE'; let conf = convict({ - aws_credentials: { - region: 'us-west-2', - bucketName: 'testpilot-p2p' - } -}) + aws_credentials: { + region: 'us-west-2', + bucketName: 'testpilot-p2p' + }, + bitly_credentials: { + api_key: api_key + }, + env: { + format: ['production', 'development'], + default: 'development', + env: 'NODE_ENV' + } +}); -// var env = conf.get('env'); -// conf.loadFile('./config/' + env + '.json'); - -// Perform validation -conf.validate({allowed: 'strict'}); - -module.exports = conf; \ No newline at end of file +// Perform validation +conf.validate({ allowed: 'strict' }); + +module.exports = conf.getProperties(); diff --git a/server/portal_server.js b/server/portal_server.js index ca1a1bbf..e47e3222 100644 --- a/server/portal_server.js +++ b/server/portal_server.js @@ -1,24 +1,25 @@ -const express = require("express") -const busboy = require("connect-busboy"); -const path = require("path"); -const fs = require("fs-extra"); -const bodyParser = require("body-parser"); -const crypto = require("crypto"); +const express = require('express'); +const busboy = require('connect-busboy'); +const path = require('path'); +const fs = require('fs-extra'); +const bodyParser = require('body-parser'); +const crypto = require('crypto'); const conf = require('./config.js'); const stream = require('stream'); +const fetch = require('node-fetch'); -let aws_credentials = conf.get('aws_credentials'); +let aws_credentials = conf.aws_credentials; +let bitly_credentials = conf.bitly_credentials; +let isProduction = conf.env === 'production'; const AWS = require('aws-sdk'); -AWS.config.loadFromPath('../../.aws/credentials'); const s3 = new AWS.S3(); +const app = express(); +const redis = require('redis'); +const redis_client = redis.createClient(); -const app = express() -const redis = require("redis"), - redis_client = redis.createClient(); - -redis_client.on("error", (err) => { +redis_client.on('error', err => { console.log(err); }); @@ -33,24 +34,26 @@ app.get('/download/:id', (req, res) => { app.get('/assets/download/:id', (req, res) => { let id = req.params.id; if (!validateID(id)) { - res.send(404); + res.sendStatus(404); return; } - redis_client.hget(id, "filename", (err, reply) => { // maybe some expiration logic too + redis_client.hget(id, 'filename', (err, reply) => { + // maybe some expiration logic too if (!reply) { res.sendStatus(404); } else { - let params = { Bucket: aws_credentials.bucketName, Key: id - } + }; s3.headObject(params, function(err, data) { - res.writeHead(200, {"Content-Disposition": "attachment; filename=" + reply, - "Content-Type": "application/octet-stream", - "Content-Length": data.ContentLength}); + res.writeHead(200, { + 'Content-Disposition': 'attachment; filename=' + reply, + 'Content-Type': 'application/octet-stream', + 'Content-Length': data.ContentLength + }); let file_stream = s3.getObject(params).createReadStream(); file_stream.on('finish', () => { @@ -59,26 +62,13 @@ app.get('/assets/download/:id', (req, res) => { if (!err) { console.log('Deleted off s3.'); } - }) + }); }); file_stream.pipe(res); }); - - // s3.getObject(params, function(err, data) { - // if (err) { - // console.log(err, err.stack); // an error occurred - // res.sendStatus(404); - // } - // else { - - - - // } - // }) - } - }) + }); }); app.post('/delete/:id', (req, res) => { @@ -95,66 +85,98 @@ app.post('/delete/:id', (req, res) => { res.sendStatus(404); } - redis_client.hget(id, "delete", (err, reply) => { - if (!reply || (delete_token !== reply)) { + redis_client.hget(id, 'delete', (err, reply) => { + if (!reply || delete_token !== reply) { res.sendStatus(404); } else { redis_client.del(id); let params = { Bucket: aws_credentials.bucketName, Key: id - } + }; s3.deleteObject(params, function(err, data) { if (!err) { console.log('Deleted off s3.'); } - }) + }); res.sendStatus(200); } }); }); -app.post("/upload/:id", (req, res, next) => { +app.post('/upload/:id', (req, res, next) => { + if (!validateID(req.params.id)) { + res.send(404); + return; + } - if (!validateID(req.params.id)){ - res.send(404); - return; - } + req.pipe(req.busboy); + req.busboy.on('file', (fieldname, file, filename) => { + console.log('Uploading: ' + filename); - req.pipe(req.busboy); - req.busboy.on("file", (fieldname, file, filename) => { - console.log("Uploading: " + filename); + let params = { + Bucket: aws_credentials.bucketName, + Key: req.params.id, + Body: file + }; - let params = { - Bucket: aws_credentials.bucketName, - Key: req.params.id, - Body: file + s3.upload(params, function(err, data) { + if (err) { + console.log(err, err.stack); // an error occurred + } else { + let id = req.params.id; + let uuid = crypto.randomBytes(10).toString('hex'); + + redis_client.hmset([id, 'filename', filename, 'delete', uuid]); + + redis_client.expire(id, 86400000); + console.log('Upload Finished of ' + filename); + + if (isProduction) { + let url = + req.protocol + + `://` + + req.get('host') + + '/download/' + + req.params.id + + '/'; + fetch( + 'https://api-ssl.bitly.com/v3/shorten?access_token=' + + bitly_credentials.api_key + + '&longUrl=' + + encodeURIComponent(url) + + '&format=txt' + ) + .then(res => { + return res.text(); + }) + .then(body => { + res.json({ + uuid: uuid, + url: body + }); + }); + } else { + res.json({ + uuid: uuid, + url: url + }); } - - s3.upload(params, function(err, data) { - if (err) { - console.log(err, err.stack); // an error occurred - } else { - let id = req.params.id; - let uuid = crypto.randomBytes(10).toString('hex'); - - redis_client.hmset([id, "filename", filename, "delete", uuid]); - - redis_client.expire(id, 86400000); - console.log("Upload Finished of " + filename); - res.send(uuid); - } - }) + } }); }); }); -app.listen(3000, () => { +let server = app.listen(3000, () => { console.log('Portal app listening on port 3000!'); }); let validateID = route_id => { return route_id.match(/^[0-9a-fA-F]{32}$/) !== null; }; + +if (bitly_credentials.api_key === 'INSERT API KEY HERE') { + throw new Error('Copy paste a bitly API key into server/config.js'); +}