diff --git a/app.js b/app.js index 6f2670b4..7b3a881a 100644 --- a/app.js +++ b/app.js @@ -1,9 +1,11 @@ const express = require("express") -var busboy = require("connect-busboy"); //middleware for form/file upload -var path = require("path"); //used for file path -var fs = require("fs-extra"); //File System - for file manipulation +const busboy = require("connect-busboy"); +const path = require("path"); +const fs = require("fs-extra"); +const bodyParser = require('body-parser'); + const app = express() -var redis = require("redis"), +const redis = require("redis"), client = redis.createClient(); client.on("error", function(err) { @@ -11,12 +13,9 @@ client.on("error", function(err) { }) app.use(busboy()); +app.use(bodyParser.json()); app.use(express.static(path.join(__dirname, "public"))); -app.get("/", function (req, res) { - res.send("Hello World!") -}) - app.get("/download/:id", function(req, res) { res.sendFile(path.join(__dirname + "/public/download.html")); }); @@ -25,7 +24,7 @@ app.get("/assets/download/:id", function(req, res) { let id = req.params.id; client.hget(id, "filename", function(err, reply) { // maybe some expiration logic too - if (!reply) { + if (!reply) { res.sendStatus(404); } else { res.setHeader("Content-Disposition", "attachment; filename=" + reply); @@ -42,8 +41,26 @@ app.get("/assets/download/:id", function(req, res) { }); -app.route("/upload/:id") - .post(function (req, res, next) { +app.post("/delete/:id", function(req, res) { + let id = req.params.id; + let delete_token = req.body.delete_token; + + if (!delete_token){ + res.sendStatus(404); + } + + client.hget(id, "delete", function(err, reply) { + if (!reply) { + res.sendStatus(404); + } else { + client.del(id); + fs.unlinkSync(__dirname + "/static/" + id); + res.sendStatus(200); + } + }) +}); + +app.post("/upload/:id", function (req, res, next) { var fstream; req.pipe(req.busboy); @@ -55,17 +72,26 @@ app.route("/upload/:id") file.pipe(fstream); fstream.on("close", function () { let id = req.params.id; - client.hset(id, "filename", filename, redis.print); - client.hset(id, "expiration", 0, redis.print); + let uuid = Math.floor(Math.random() * 10000000).toString() + + Math.floor(Math.random() * 10000000).toString() + + Math.floor(Math.random() * 10000000).toString(); + + client.hset(id, "filename", filename); + client.hset(id, "expiration", 0); + client.hset(id, "delete", uuid); + + // delete the file off the server in 24 hours + setTimeout(function() { + fs.unlinkSync(__dirname + "/static/" + id); + }, 86400000); + client.expire(id, 86400000); - console.log("Upload Finished of " + filename); - res.send(id); + console.log("Upload Finished of " + filename); + res.send(uuid); }); }); }); - - app.listen(3000, function () { console.log("Portal app listening on port 3000!") }) diff --git a/package.json b/package.json index ebfba011..db0b4a6a 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "author": "", "license": "ISC", "dependencies": { + "body-parser": "^1.17.2", "connect-busboy": "0.0.2", "express": "^4.15.3", "fs-extra": "^3.0.1", diff --git a/public/download.js b/public/download.js index 93fc5f3e..93a210df 100644 --- a/public/download.js +++ b/public/download.js @@ -50,7 +50,7 @@ function download() { a.click(); }) .catch(function(err){ - alert("This link is either invalid or has expired."); + alert("This link is either invalid or has expired, or the uploader has deleted the file."); console.error(err); }); }) @@ -60,7 +60,7 @@ function download() { }; fileReader.readAsArrayBuffer(blob); } else { - alert("Unable to download excel.") + alert("This link is either invalid or has expired, or the uploader has deleted the file.") } }; xhr.send(); diff --git a/public/index.html b/public/index.html index d49ae997..f8d8a43c 100644 --- a/public/index.html +++ b/public/index.html @@ -12,6 +12,9 @@

+ + diff --git a/public/upload.js b/public/upload.js index f3f015b5..32fabbcc 100644 --- a/public/upload.js +++ b/public/upload.js @@ -31,12 +31,40 @@ function onChange(event) { var xhr = new XMLHttpRequest(); var hex = ivToStr(random_iv); xhr.open("post", "/upload/" + hex, true); - xhr.addEventListener("progress", updateProgress); - xhr.upload.addEventListener("progress", updateProgress); + + var li = document.createElement("li"); + var name = document.createElement("p"); + name.innerHTML = file.name; + li.appendChild(name); + + var link = document.createElement("a"); + li.appendChild(link); + + var progress = document.createElement("p"); + li.appendChild(progress); + document.getElementById("uploaded_files").appendChild(li); + + + xhr.upload.addEventListener("progress", returnBindedLI(progress, name, link, li)); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { window.crypto.subtle.exportKey("jwk", key).then(function(keydata) { + var curr_name = localStorage.getItem(file.name); + + localStorage.setItem(hex, xhr.responseText); + + link.innerHTML = "http://localhost:3000/download/" + hex + "/#" + keydata.k; + link.setAttribute("href", "http://localhost:3000/download/" + hex + "/#" + keydata.k); + + // if (curr_name) { + // localStorage.setItem(file.name, curr_name + "," + hex); + // } else { + // localStorage.setItem(file.name, hex) + // } + + + console.log("Share this link with a friend: http://localhost:3000/download/" + hex + "/#" + keydata.k); alert("Share this link with a friend: http://localhost:3000/download/" + hex + "/#" + keydata.k); }) @@ -80,9 +108,42 @@ function strToIv(str) { return iv; } -function updateProgress(e) { - if (e.lengthComputable) { - var percentComplete = Math.floor((e.loaded / e.total) * 100); - document.getElementById("downloadProgress").innerHTML = "Progress: " + percentComplete + "%"; - } -} \ No newline at end of file +function returnBindedLI(a_element, name, link, li) { + return function updateProgress(e) { + if (e.lengthComputable) { + var percentComplete = Math.floor((e.loaded / e.total) * 100); + a_element.innerHTML = "Progress: " + percentComplete + "%"; + + if (percentComplete === 100) { + var btn = document.createElement("button"); + btn.innerHTML = "Delete from server"; + btn.addEventListener("click", function() { + var segments = link.innerHTML.split("/"); + var key = segments[segments.length - 2]; + + var xhr = new XMLHttpRequest(); + xhr.open("post", "/delete/" + key, true); + xhr.setRequestHeader("Content-Type", "application/json"); + if (!localStorage.getItem(key)) return; + + xhr.send(JSON.stringify({delete_token: localStorage.getItem(key)})); + + xhr.onreadystatechange = function() { + if (xhr.readyState === XMLHttpRequest.DONE) { + document.getElementById("uploaded_files").removeChild(li); + } + + if (xhr.status === 200) { + console.log("The file was successfully deleted."); + } else { + console.log("The file has expired, or has already been deleted."); + } + } + + }); + li.appendChild(btn); + } + } + } +} +