diff --git a/package.json b/package.json
index fb53173c..1a2c0418 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"scripts": {
"format": "prettier --single-quote --write 'public/*.js' 'app.js'",
"test": "echo \"Error: no test specified\" && exit 1",
- "start": "node app.js"
+ "start": "node server/portal_server.js"
},
"author": "",
"license": "ISC",
diff --git a/public/file.js b/public/file.js
new file mode 100644
index 00000000..ce680be4
--- /dev/null
+++ b/public/file.js
@@ -0,0 +1,10 @@
+function ProgressEmitter(name, uuid, type) {
+ this.name = name;
+ this.uuid = uuid;
+ this.type = type;
+ this.link = null;
+
+ this.emit = () => {
+
+ };
+}
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index c6b31826..aa77f317 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,9 +1,9 @@
-Firefox Fileshare
-
-
+ Firefox Fileshare
+
+
@@ -13,6 +13,6 @@
-
+
diff --git a/public/upload.js b/public/upload.js
index 2d890a4f..f213490f 100644
--- a/public/upload.js
+++ b/public/upload.js
@@ -1,101 +1,105 @@
function onChange(event) {
+
var file = event.target.files[0];
var reader = new FileReader();
+ reader.readAsArrayBuffer(file);
+
+ let random_iv = window.crypto.getRandomValues(new Uint8Array(16));
+ var hex = ivToStr(random_iv);
+
reader.onload = function(event) {
let self = this;
- window.crypto.subtle
- .generateKey(
- {
- name: 'AES-CBC',
- length: 128
- },
- true,
- ['encrypt', 'decrypt']
- )
- .then(function(key) {
- var arrayBuffer = self.result;
- var array = new Uint8Array(arrayBuffer);
+ window.crypto.subtle.generateKey({
+ name: "AES-CBC",
+ length: 128
+ },
+ true,
+ ["encrypt", "decrypt"])
+ .then((key) => {
+ let arrayBuffer = self.result;
+ let array = new Uint8Array(arrayBuffer);
- var random_iv = window.crypto.getRandomValues(new Uint8Array(16));
+ window.crypto.subtle.encrypt({
+ name: "AES-CBC",
+ iv: random_iv },
+ key,
+ array)
+ .then(uploadFile.bind(null, file, hex, key))
+ .catch((err) => console.error(err));
- window.crypto.subtle
- .encrypt(
- {
- name: 'AES-CBC',
- iv: random_iv
- },
- key,
- array
- )
- .then(function(encrypted) {
- var dataView = new DataView(encrypted);
- var blob = new Blob([dataView], { type: file.type });
-
- var fd = new FormData();
- fd.append('fname', file.name);
- fd.append('data', blob, file.name);
-
- var xhr = new XMLHttpRequest();
- var hex = ivToStr(random_iv);
- xhr.open('post', '/upload/' + hex, true);
-
- 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
- );
-
- console.log(
- 'Share this link with a friend: http://localhost:3000/download/' +
- hex +
- '/#' +
- keydata.k
- );
- });
- }
- };
-
- xhr.send(fd);
- })
- .catch(function(err) {
- console.error(err);
- });
- })
- .catch(function(err) {
- console.error(err);
- });
+ }).catch((err) => console.error(err));
};
- reader.readAsArrayBuffer(file);
+}
+
+let uploadFile = (file, hex, key, encrypted) => {
+ var dataView = new DataView(encrypted);
+ var blob = new Blob([dataView], { type: file.type });
+
+ var fd = new FormData();
+ fd.append("fname", file.name);
+ fd.append("data", blob, file.name);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open("post", "/upload/" + hex, true);
+
+ let prog = new window.ProgressEmitter(file.name, hex, file.type);
+
+ 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);
+
+ prog.link = "http://localhost:3000/download/" + hex + "/#" + keydata.k;
+ prog.emit();
+
+ link.innerHTML = "http://localhost:3000/download/" + hex + "/#" + keydata.k;
+ link.setAttribute("href", "http://localhost:3000/download/" + hex + "/#" + keydata.k);
+
+ console.log("Share this link with a friend: http://localhost:3000/download/" + hex + "/#" + keydata.k);
+ })
+ }
+ };
+
+ xhr.send(fd);
+ // setupLI(file.name);
+
+}
+
+function setupLI(emitter) {
+ var li = document.createElement("li");
+ var name = document.createElement("p");
+ name.innerHTML = emitter;
+ li.appendChild(name);
+
+ var link = document.createElement("a");
+ link.addEventListener('NotifyProgress', (progress_event) => {
+ console.log(progress_event);
+ });
+ li.appendChild(link);
+
+ var progress = document.createElement("p");
+ li.appendChild(progress);
+ document.getElementById("uploaded_files").appendChild(li);
}
function ivToStr(iv) {
diff --git a/server/portal_server.js b/server/portal_server.js
new file mode 100644
index 00000000..4cc91688
--- /dev/null
+++ b/server/portal_server.js
@@ -0,0 +1,116 @@
+
+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 app = express()
+const redis = require("redis"),
+ client = redis.createClient();
+
+client.on("error", function(err) {
+ console.log(err);
+})
+
+app.use(busboy());
+app.use(bodyParser.json());
+app.use(express.static(path.join(__dirname, "../public")));
+
+app.get("/download/:id", function(req, res) {
+ res.sendFile(path.join(__dirname + "/../public/download.html"));
+});
+
+app.get("/assets/download/:id", function(req, res) {
+
+ let id = req.params.id;
+ if (!validateID(id)){
+ res.send(404);
+ return;
+ }
+
+
+ client.hget(id, "filename", function(err, reply) { // maybe some expiration logic too
+ if (!reply) {
+ res.sendStatus(404);
+ } else {
+ res.setHeader("Content-Disposition", "attachment; filename=" + reply);
+ res.setHeader("Content-Type", "application/octet-stream");
+
+ res.download(__dirname + "/../static/" + id, reply, function(err) {
+ if (!err) {
+ client.del(id);
+ fs.unlinkSync(__dirname + "/../static/" + id);
+ }
+ });
+ }
+ })
+
+});
+
+app.post("/delete/:id", function(req, res) {
+ let id = req.params.id;
+
+ if (!validateID(id)){
+ res.send(404);
+ return;
+ }
+
+ 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) {
+
+ if (!validateID(req.params.id)){
+ res.send(404);
+ return;
+ }
+
+ var fstream;
+ req.pipe(req.busboy);
+ req.busboy.on("file", function (fieldname, file, filename) {
+ console.log("Uploading: " + filename);
+
+ //Path where image will be uploaded
+ fstream = fs.createWriteStream(__dirname + "/../static/" + req.params.id);
+ file.pipe(fstream);
+ fstream.on("close", function () {
+ let id = req.params.id;
+ let uuid = crypto.randomBytes(10).toString('hex');
+
+ client.hmset([id, "filename", filename, "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(uuid);
+ });
+ });
+});
+
+app.listen(3000, function () {
+ console.log("Portal app listening on port 3000!")
+})
+
+function validateID(route_id) {
+ return route_id.match(/^[0-9a-fA-F]{32}$/) !== null;
+}
\ No newline at end of file