From 85c493e18f9a752e15cd11eeb9c80789a7780ea2 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 6 Oct 2020 14:35:54 -0400 Subject: [PATCH] support encryption --- services/gunDB/rpc.js | 51 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/services/gunDB/rpc.js b/services/gunDB/rpc.js index 4257ef3b..66213000 100644 --- a/services/gunDB/rpc.js +++ b/services/gunDB/rpc.js @@ -2,12 +2,51 @@ * @format */ // @ts-check -const { makePromise, Constants } = require('shock-common') +const { makePromise, Constants, Schema } = require('shock-common') +const mapValues = require('lodash/mapValues') +const Bluebird = require('bluebird') + +const { pubToEpub } = require('./contact-api/utils') +const { getGun, getUser, mySEA: SEA, getMySecret } = require('./Mediator') /** * @typedef {import('./contact-api/SimpleGUN').ValidDataValue} ValidDataValue */ -const { getGun, getUser } = require('./Mediator') +/** + * @param {ValidDataValue} value + * @returns {Promise} + */ +const deepEncryptIfNeeded = async value => { + const u = getUser() + + if (!u.is) { + throw new Error(Constants.ErrorCode.NOT_AUTH) + } + + if (!Schema.isObj(value)) { + return value + } + + const pk = /** @type {string|undefined} */ (value.$$__ENCRYPT__FOR) + + if (!pk) { + return Bluebird.props(mapValues(value, deepEncryptIfNeeded)) + } + + const actualValue = /** @type {string} */ (value.value) + + let encryptedValue = '' + + if (pk === u.is.pub) { + encryptedValue = await SEA.encrypt(actualValue, getMySecret()) + } else { + const sec = await SEA.secret(await pubToEpub(pk), u._.sea) + + encryptedValue = await SEA.encrypt(actualValue, sec) + } + + return encryptedValue +} /** * @param {string} rawPath @@ -44,8 +83,10 @@ const put = async (rawPath, value) => { return _node })() + const encryptedIfNeededValue = await deepEncryptIfNeeded(value) + await makePromise((res, rej) => { - node.put(value, ack => { + node.put(encryptedIfNeededValue, ack => { if (ack.err && typeof ack.err !== 'number') { rej(new Error(ack.err)) } else { @@ -90,8 +131,10 @@ const set = async (rawPath, value) => { return _node })() + const encryptedIfNeededValue = await deepEncryptIfNeeded(value) + const id = await makePromise((res, rej) => { - const subNode = node.set(value, ack => { + const subNode = node.set(encryptedIfNeededValue, ack => { if (ack.err && typeof ack.err !== 'number') { rej(new Error(ack.err)) } else {