From fc800407c0f45352ee533769fe96a8c339501a34 Mon Sep 17 00:00:00 2001 From: cel Date: Mon, 1 Oct 2018 22:02:29 -1000 Subject: Decrypt message with unbox key query parameter --- lib/app.js | 25 +++++++++++++++++++++++-- lib/render.js | 8 ++++++-- lib/serve.js | 12 ++++++++++-- package.json | 1 + 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/lib/app.js b/lib/app.js index 6bfa00a..2ded278 100644 --- a/lib/app.js +++ b/lib/app.js @@ -7,6 +7,7 @@ var pull = require('pull-stream') var multicb = require('multicb') var paramap = require('pull-paramap') var Contacts = require('ssb-contact') +var PrivateBox = require('private-box') var About = require('./about') var Follows = require('./follows') var Serve = require('./serve') @@ -104,11 +105,27 @@ var logPrefix = '[' + pkg.name + ']' App.prototype.log = console.log.bind(console, logPrefix) App.prototype.error = console.error.bind(console, logPrefix) -App.prototype.unboxMsg = function (msg, cb) { +App.prototype.unboxContentWithKey = function (content, key, cb) { + if (!key) return this.unboxContent(content, cb) + var data + try { + var contentBuf = new Buffer(content.replace(/\.box.*$/, ''), 'base64') + var keyBuf = new Buffer(key, 'base64') + console.error(key, keyBuf.length) + data = PrivateBox.multibox_open_body(contentBuf, keyBuf) + if (!data) return cb(new Error('failed to decrypt')) + data = JSON.parse(data.toString('utf8')) + } catch(e) { + return cb(new Error(e.stack || e)) + } + cb(null, data) +} + +App.prototype.unboxMsgWithKey = function (msg, key, cb) { var self = this var c = msg && msg.value && msg.value.content if (typeof c !== 'string') cb(null, msg) - else self.unboxContent(c, function (err, content) { + else self.unboxContentWithKey(c, key, function (err, content) { if (err) { self.error('unbox:', err) return cb(null, msg) @@ -125,6 +142,10 @@ App.prototype.unboxMsg = function (msg, cb) { }) } +App.prototype.unboxMsg = function (msg, cb) { + return this.unboxMsgWithKey(msg, null, cb) +} + App.prototype.search = function (opts) { var fsearch = this.sbot.fulltext && this.sbot.fulltext.search if (fsearch) return fsearch(opts) diff --git a/lib/render.js b/lib/render.js index 15d7783..afb181f 100644 --- a/lib/render.js +++ b/lib/render.js @@ -222,9 +222,13 @@ Render.prototype.toUrl = function (href) { } switch (href[0]) { case '%': - if (!u.isRef(href)) return false + var parts = href.split('?') + var hash = parts.shift() + var query = parts.join('?') + if (!u.isRef(hash)) return false return this.opts.base + - (this.opts.encode_msgids ? encodeURIComponent(href) : href) + (this.opts.encode_msgids ? encodeURIComponent(hash) : hash) + + (query ? '?' + query : '') case '@': if (!u.isRef(href.replace(/\?.*/, ''))) return false return this.opts.base + href diff --git a/lib/serve.js b/lib/serve.js index f825ed7..c51a331 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -3627,8 +3627,16 @@ Serve.prototype.getBuiltinEmojiLink = function (name) { } Serve.prototype.getMsgDecryptedMaybeOoo = function (key, cb) { - if (this.useOoo) this.app.getMsgDecryptedOoo(key, cb) - else this.app.getMsgDecrypted(key, cb) + var self = this + if (this.useOoo) this.app.getMsgDecryptedOoo(key, next) + else this.app.getMsgDecrypted(key, next) + function next(err, msg) { + if (err) return cb(err) + var c = msg && msg.value && msg.value.content + if (typeof c === 'string' && self.query.unbox) + self.app.unboxMsgWithKey(msg, String(self.query.unbox).replace(/ /g, '+'), cb) + else cb(null, msg) + } } Serve.prototype.emojis = function (path) { diff --git a/package.json b/package.json index ec379a9..3226e19 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "jpeg-autorotate": "^3.0.0", "mime-types": "^2.1.12", "multicb": "^1.2.1", + "private-box": "^0.3.0", "pull-box-stream": "^1.0.12", "pull-cat": "^1.1.11", "pull-catch": "^1.0.0", -- cgit v1.2.3