From 37a466f9f38475be746c3e5d88dc15a12c00a448 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 8 Jun 2021 15:57:22 -0400 Subject: [PATCH] Allows client to provide epub for faster decrypt --- .vscode/settings.json | 7 +-- services/gunDB/rpc/index.js | 13 +++- services/gunDB/sockets/index.js | 19 ++++-- src/routes.js | 107 +++++++++++--------------------- 4 files changed, 62 insertions(+), 84 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f11f2b7c..f7a45822 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,10 +4,5 @@ "debug.node.autoAttach": "on", "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", - "cSpell.words": [ - "Epub", - "ISEA", - "PUBKEY", - "Reqs" - ] + "cSpell.words": ["Epub", "GUNRPC", "ISEA", "PUBKEY", "Reqs", "uuidv"] } diff --git a/services/gunDB/rpc/index.js b/services/gunDB/rpc/index.js index b3cca30a..b9ef24a1 100644 --- a/services/gunDB/rpc/index.js +++ b/services/gunDB/rpc/index.js @@ -27,9 +27,10 @@ const PATH_SEPARATOR = '>' /** * @param {ValidDataValue} value * @param {string} publicKey + * @param {string=} epubForDecryption * @returns {Promise} */ -const deepDecryptIfNeeded = async (value, publicKey) => { +const deepDecryptIfNeeded = async (value, publicKey, epubForDecryption) => { if (Schema.isObj(value)) { return Bluebird.props( mapValues(value, o => deepDecryptIfNeeded(o, publicKey)) @@ -49,7 +50,15 @@ const deepDecryptIfNeeded = async (value, publicKey) => { if (user.is.pub === publicKey || 'me' === publicKey) { sec = getMySecret() } else { - sec = await SEA.secret(await pubToEpub(publicKey), user._.sea) + sec = await SEA.secret( + await (() => { + if (epubForDecryption) { + return epubForDecryption + } + return pubToEpub(publicKey) + })(), + user._.sea + ) } const decrypted = SEA.decrypt(value, sec) diff --git a/services/gunDB/sockets/index.js b/services/gunDB/sockets/index.js index a1427703..f4a2eee7 100644 --- a/services/gunDB/sockets/index.js +++ b/services/gunDB/sockets/index.js @@ -121,13 +121,15 @@ const executeGunQuery = (query, method, listener) => { * @param {string} queryData.publicKeyForDecryption * @param {string} queryData.subscriptionId * @param {string} queryData.deviceId + * @param {string=} queryData.epubForDecryption * @returns {GunListener} */ const queryListenerCallback = ({ emit, publicKeyForDecryption, subscriptionId, - deviceId + deviceId, + epubForDecryption }) => async (data, key, _msg, event) => { try { const subscription = Subscriptions.get({ @@ -142,8 +144,13 @@ const queryListenerCallback = ({ }) } const eventName = `query:data` - if (publicKeyForDecryption) { - const decData = await deepDecryptIfNeeded(data, publicKeyForDecryption) + + if (publicKeyForDecryption?.length > 15) { + const decData = await deepDecryptIfNeeded( + data, + publicKeyForDecryption, + epubForDecryption + ) emit(eventName, { subscriptionId, response: { data: decData, key } }) return } @@ -250,7 +257,8 @@ const startSocket = socket => { }) } - on('subscribe:query', ({ $shock, publicKey }, response) => { + on('subscribe:query', (query, response) => { + const { $shock, publicKey, epubForDecryption } = query const subscriptionId = uuidv4() try { if (!isAuthenticated()) { @@ -277,7 +285,8 @@ const startSocket = socket => { emit, publicKeyForDecryption: publicKey, subscriptionId, - deviceId: encryptionId + deviceId: encryptionId, + epubForDecryption }) socketCallback(null, { diff --git a/src/routes.js b/src/routes.js index d0b3525c..e5b8acfb 100644 --- a/src/routes.js +++ b/src/routes.js @@ -3112,6 +3112,7 @@ module.exports = async ( * @prop {string} path * @prop {string=} publicKey * @prop {string=} publicKeyForDecryption + * @prop {string=} epubForDecryption */ /** * @param {HandleGunFetchParams} args0 @@ -3122,7 +3123,8 @@ module.exports = async ( startFromUserGraph, path, publicKey, - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption }) => { const keys = path.split('>') const { tryAndWait } = require('../services/gunDB/contact-api/utils') @@ -3141,7 +3143,8 @@ module.exports = async ( res( await GunWriteRPC.deepDecryptIfNeeded( data, - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption ) ) } else { @@ -3159,114 +3162,75 @@ module.exports = async ( * Used decryption of incoming data. */ const PUBKEY_FOR_DECRYPT_HEADER = 'public-key-for-decryption' + /** + * Used decryption of incoming data. + */ + const EPUB_FOR_DECRYPT_HEADER = 'epub-for-decryption' ap.get('/api/gun/once/:path', async (req, res) => { const publicKeyForDecryption = req.header(PUBKEY_FOR_DECRYPT_HEADER) + const epubForDecryption = req.header(EPUB_FOR_DECRYPT_HEADER) const { path } = req.params - try { - const data = await handleGunFetch({ + res.status(200).json({ + data: await handleGunFetch({ path, startFromUserGraph: false, type: 'once', - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption }) - res.status(200).json({ - data - }) - } catch (err) { - logger.error('error in rpc once') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: err.message - }) - } + }) }) ap.get('/api/gun/load/:path', async (req, res) => { const publicKeyForDecryption = req.header(PUBKEY_FOR_DECRYPT_HEADER) + const epubForDecryption = req.header(EPUB_FOR_DECRYPT_HEADER) const { path } = req.params - try { - const data = await handleGunFetch({ + res.status(200).json({ + data: await handleGunFetch({ path, startFromUserGraph: false, type: 'load', - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption }) - res.status(200).json({ - data - }) - } catch (err) { - logger.error('error in rpc load') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: err.message - }) - } + }) }) ap.get('/api/gun/user/once/:path', async (req, res) => { const publicKeyForDecryption = req.header(PUBKEY_FOR_DECRYPT_HEADER) + const epubForDecryption = req.header(EPUB_FOR_DECRYPT_HEADER) const { path } = req.params - try { - const data = await handleGunFetch({ + res.status(200).json({ + data: await handleGunFetch({ path, startFromUserGraph: true, type: 'once', - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption }) - res.status(200).json({ - data - }) - } catch (err) { - logger.error('error in rpc once user') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: err.message - }) - } + }) }) ap.get('/api/gun/user/load/:path', async (req, res) => { const publicKeyForDecryption = req.header(PUBKEY_FOR_DECRYPT_HEADER) + const epubForDecryption = req.header(EPUB_FOR_DECRYPT_HEADER) const { path } = req.params - try { - const data = await handleGunFetch({ + res.status(200).json({ + data: await handleGunFetch({ path, startFromUserGraph: true, type: 'load', - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption }) - res.status(200).json({ - data - }) - } catch (err) { - logger.error('error in rpc load user') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: err.message - }) - } + }) }) ap.get('/api/gun/otheruser/:publicKey/:type/:path', async (req, res) => { const allowedTypes = ['once', 'load', 'open'] const publicKeyForDecryption = req.header(PUBKEY_FOR_DECRYPT_HEADER) + const epubForDecryption = req.header(EPUB_FOR_DECRYPT_HEADER) const { path /*:rawPath*/, publicKey, type } = req.params console.log(path) // const path = decodeURI(rawPath) @@ -3290,7 +3254,8 @@ module.exports = async ( startFromUserGraph: false, type, publicKey, - publicKeyForDecryption + publicKeyForDecryption, + epubForDecryption }) }) } catch (err) {