diff options
-rw-r--r-- | gossip.js | 83 | ||||
-rw-r--r-- | package-lock.json | 23 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | render.js | 53 | ||||
-rw-r--r-- | server.js | 58 |
5 files changed, 206 insertions, 12 deletions
@@ -1,3 +1,86 @@ +function blobSync (blob, author, keys, needs) { + console.log(needs) + + var wsServers + + // duplicate code, we should abstract this + localforage.getItem('securepubs').then(function (servers) { + if (servers) { + wsServers = servers + } else { + servers = ['ws://bogbook.com', 'ws://localhost:8080'] + var pubs = [] + servers.forEach(server => { + var ws = new WebSocket(server) + ws.onopen = function () { + ws.send(JSON.stringify({requester: keys.publicKey, sendpub: true})) + } + ws.onmessage = function (message) { + pubs.push(server + '/~' + message.data) + localforage.setItem('securepubs', pubs) + } + }) + wsServers = pubs + } + }).then(function () { + wsServers.forEach(function (server, index) { + setTimeout(function () { + var split = server.split('~') + var serverurl = split[0] + var serverpub = split[1] + var ws = new WebSocket(serverurl) + + console.log('requesting ' + blob + ' from ' + server) + ws.onopen = function () { + var req = { + blob: blob, + needs: needs + } + + box(JSON.stringify(req), serverpub, keys).then(boxed => { + var obj = { + requester: keys.publicKey, + box: boxed + } + ws.send(JSON.stringify(obj)) + }) + } + ws.onmessage = function (message) { + var serverreq = JSON.parse(message.data) + unbox(serverreq.box, serverreq.requester, keys).then(unboxed => { + + var unboxedreq = JSON.parse(nacl.util.encodeUTF8(unboxed)) + //console.log(unboxedreq) + if (unboxedreq.blobFile) { + var openedimg = nacl.sign.open(nacl.util.decodeBase64(unboxedreq.blobFile), nacl.util.decodeBase64(author.substring(1))) + if (openedimg) { + localforage.setItem(unboxedreq.blob, unboxedreq.blobFile) + } + } else { + localforage.getItem(unboxedreq.blob).then(blob => { + if (blob) { + var nextreq = { + author: author, + blob: unboxedreq.blob, + blobFile: blob + } + box(JSON.stringify(nextreq), serverreq.requester, keys).then(boxed => { + var obj = { + requester: keys.publicKey, + box: boxed + } + ws.send(JSON.stringify(obj)) + }) + } + }) + } + }) + } + }, index * 10000) + }) + }) +} + function sync (subs, keys) { var wsServers diff --git a/package-lock.json b/package-lock.json index c2de81e..799f9d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bogbook", - "version": "1.4.0", + "version": "1.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -83,6 +83,22 @@ "is-wsl": "^1.1.0" } }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, "tweetnacl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", @@ -98,6 +114,11 @@ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=" }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" + }, "ws": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", diff --git a/package.json b/package.json index e80e800..5632bad 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "ecstatic": "^4.1.2", "ed2curve": "^0.2.1", "open": "^6.2.0", + "sanitize-filename": "^1.6.3", "tweetnacl": "^1.0.1", "tweetnacl-util": "^0.15.0", "ws": "^6.2.1" @@ -5,9 +5,34 @@ function addButton (post, message, keys) { var fr = new FileReader() fr.addEventListener("load", function(e) { + var image = e.target.result - document.getElementById("img").src = image - }); + var signed = nacl.sign(nacl.util.decodeUTF8(image), nacl.util.decodeBase64(keys.privateKey)) + var signed64 = nacl.util.encodeBase64(signed) + var hash64 = nacl.util.encodeBase64(nacl.hash(signed)) + // we should probably throw out blobs that are too big! + localforage.setItem(hash64, signed64).then(function () { + console.log('saved image to localforage') + var obj = { + type: 'blob', + blobbed: post.key, + hash: hash64 + } + publish(obj, keys).then(published => { + var getPost = document.getElementById(post.key) + open(published).then(opened => { + localforage.getItem(opened.hash).then(signed => { + var openedImg = nacl.sign.open(nacl.util.decodeBase64(signed), nacl.util.decodeBase64(post.author.substring(1))) + console.log(openedImg) + var image = h('img', {src: nacl.util.encodeUTF8(openedImg)}) + getPost.appendChild(image) + message.appendChild(render(published)) + }) + }) + }) + }) + + }) fr.readAsDataURL( this.files[0] ) } @@ -20,7 +45,6 @@ function addButton (post, message, keys) { h('img', {id: 'img'}) ]) - var locInput = h('input', {placeholder: 'New location'}) var locDiv = h('div', [ locInput, @@ -64,7 +88,7 @@ function addButton (post, message, keys) { }, ['Publish']) ]) - var button = h('button', {classList: 'right', + var button = h('button', {/*classList: 'right',*/ onclick: function () { message.appendChild(h('button', {classList: 'right', onclick: function () { @@ -143,6 +167,20 @@ function render (msg, keys, preview) { message.appendChild(located) } + if (nextPost.blobbed == msg.key) { + localforage.getItem(nextPost.hash).then(signed => { + if (signed) { + var openedImg = nacl.sign.open(nacl.util.decodeBase64(signed), nacl.util.decodeBase64(nextPost.author.substring(1))) + var image = h('img', {src: nacl.util.encodeUTF8(openedImg)}) + blobSync(nextPost.hash, nextPost.author, keys, false ) + message.appendChild(image) + } else { + console.log('we don\'t have the blob') + blobSync(nextPost.hash, nextPost.author, keys, true ) + } + }) + } + if (nextPost.valuated == msg.key) { var valuatedExists = document.getElementById('valuated:' + msg.key) var valuated = h('div', {id: 'valuated:' + msg.key}, [h('strong', ['Price: ' ]), nextPost.value + ' ' + nextPost.currency]) @@ -267,6 +305,13 @@ function render (msg, keys, preview) { } else if (msg.type == 'value') { message.appendChild(getHeader(msg, keys)) message.appendChild(h('span', [h('a', {href: '#' + msg.valuated}, [msg.valuated.substring(0, 10) + '...']), ' is worth: ' + msg.value + ' ' + msg.currency])) + } else if (msg.type == 'blob') { + message.appendChild(getHeader(msg, keys)) + localforage.getItem(msg.hash).then(signed => { + var openedImg = nacl.sign.open(nacl.util.decodeBase64(signed), nacl.util.decodeBase64(msg.author.substring(1))) + var image = h('img', {src: nacl.util.encodeUTF8(openedImg)}) + message.appendChild(image) + }) } messageDiv.appendChild(message) @@ -18,16 +18,15 @@ var fs = require('fs') var nacl = require('tweetnacl') nacl.util = require('tweetnacl-util') var homedir = require('os').homedir() +var sanitize = require('sanitize-filename') -var bogdir = homedir + '/.bogbook/bogs/' -if (!fs.existsSync(homedir + '/.bogbook/')) { - fs.mkdirSync(homedir + '/.bogbook/') -} +var bogdir = homedir + '/.bogbook/bogs/' +var blobdir = homedir + '/.bogbook/blobs/' -if (!fs.existsSync(bogdir)){ - fs.mkdirSync(bogdir) -} +if (!fs.existsSync(homedir + '/.bogbook/')) {fs.mkdirSync(homedir + '/.bogbook/')} +if (!fs.existsSync(bogdir)){fs.mkdirSync(bogdir)} +if (!fs.existsSync(blobdir)){fs.mkdirSync(blobdir)} var wserve = new WS.Server({ port: 8080 }) @@ -41,6 +40,51 @@ bog.keys().then(key => { else { bog.unbox(req.box, req.requester, key).then(unboxed => { var unboxedreq = JSON.parse(nacl.util.encodeUTF8(unboxed)) + //console.log(unboxedreq) + if (unboxedreq.blobFile) { + var openedimg = nacl.sign.open(nacl.util.decodeBase64(unboxedreq.blobFile), nacl.util.decodeBase64(unboxedreq.author.substring(1))) + if (openedimg) { + //console.log(openedimg) + fs.writeFileSync(blobdir + '/' + sanitize(unboxedreq.blob), unboxedreq.blobFile, 'UTF-8') + console.log('received blob ' + unboxedreq.blob + ' from ' + req.requester + ' and saved to blobs folder') + } + } + if (unboxedreq.blob) { + console.log(req.requester + ' has requested the blob ' + unboxedreq.blob) + var blobExists = fs.existsSync(blobdir + '/' + sanitize(unboxedreq.blob)) + if (unboxedreq.needs) { + console.log(req.requester + ' needs ' + unboxedreq.blob + ' do we have it?') + if (blobExists) { + console.log('We have it, so send it to the client') + var blobToSend = fs.readFileSync(blobdir + '/' + sanitize(unboxedreq.blob), 'UTF-8') + var sendblob = { + blob: unboxedreq.blob, + blobFile: blobToSend + } + console.log(sendblob) + bog.box(JSON.stringify(sendblob), req.requester, key).then(boxed => { + var obj = { + requester: key.publicKey, + box: boxed + } + ws.send(JSON.stringify(obj)) + }) + } + } else { + console.log(req.requester + ' has ' + unboxedreq.blob + ' do we need it?') + if (!blobExists) { + console.log('We need it, so request it from the client') + var blobreq = { blob: unboxedreq.blob, needs: true } + bog.box(JSON.stringify(blobreq), req.requester, key).then(boxed => { + var obj = { + requester: key.publicKey, + box: boxed + } + ws.send(JSON.stringify(obj)) + }) + } + } + } if (unboxedreq.seq === 0) { console.log(req.requester + ' asked the full log of ' + unboxedreq.author) fs.readFile(bogdir + unboxedreq.author, 'UTF-8', function (err, data) { |