From 5d3ff351b0a9270f2983143057b11652f13837a0 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 18 Jul 2020 14:39:46 -0400 Subject: [PATCH 01/26] remove excessive log --- services/gunDB/contact-api/events/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/events/index.js b/services/gunDB/contact-api/events/index.js index 9d2fa01e..3fbaddf8 100644 --- a/services/gunDB/contact-api/events/index.js +++ b/services/gunDB/contact-api/events/index.js @@ -452,7 +452,7 @@ const getChats = () => currentChats const chatsListeners = new Set() chatsListeners.add(c => { - logger.info(`new Chats: ${JSON.stringify(c, null, 4)}`) + logger.info(`Chats: ${c.length}`) }) const notifyChatsListeners = () => { From 8a647dd380acbf765a9cb9008692c0c7a7399062 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 18 Jul 2020 14:44:37 -0400 Subject: [PATCH 02/26] remove excessive log --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 22e163e7..2e9d50b9 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1772,7 +1772,7 @@ module.exports = async ( try { const user = require('../services/gunDB/Mediator').getUser() const data = await timeout5(user.get(Key.PROFILE).get(Key.AVATAR).then()) - logger.info(`avatar poll:${data}`) + logger.info(`avatar poll:${data.length} chars`) res.json({ data }) From ab3d5a8ee8fef92b1dee10d22bcce70eec38cef8 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 18 Jul 2020 14:59:54 -0400 Subject: [PATCH 03/26] compress log size --- services/gunDB/contact-api/events/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/events/index.js b/services/gunDB/contact-api/events/index.js index 3fbaddf8..24f66a0b 100644 --- a/services/gunDB/contact-api/events/index.js +++ b/services/gunDB/contact-api/events/index.js @@ -329,7 +329,11 @@ const getCurrentOutgoings = () => currentOutgoings const outgoingsListeners = new Set() outgoingsListeners.add(o => { - logger.info(`new outgoings: ${JSON.stringify(o, null, 4)}`) + const values = Object.values(o) + const nulls = values.filter(x => x === null).length + const nonNulls = values.length - nulls + + logger.info(`new outgoings, ${nulls} nulls and ${nonNulls} nonNulls`) }) const notifyOutgoingsListeners = () => { From 8c5173b154d2b6a3cd1fc45845f658efeac4ec24 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 20 Jul 2020 13:10:31 -0400 Subject: [PATCH 04/26] remove excessive log --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 2e9d50b9..00bf57f5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1755,7 +1755,7 @@ module.exports = async ( // spinup Events.onChats(() => {})() const data = Events.getChats() - logger.info(`Chats polled: ${JSON.stringify(data, null, 4)}`) + logger.info(`Chats polled: ${data.length}`) res.json({ data }) From c7715a8f3b02ce5f75814d6070932ae877b19223 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 20 Jul 2020 15:12:56 -0400 Subject: [PATCH 05/26] contact actions and reads through HTTP --- src/routes.js | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/src/routes.js b/src/routes.js index 00bf57f5..bc4554a2 100644 --- a/src/routes.js +++ b/src/routes.js @@ -2054,6 +2054,175 @@ module.exports = async ( ap.get(`/api/gun/me`, apiGunMeGet) ap.put(`/api/gun/me`, apiGunMePut) + /** + * @typedef {object} ChatsRouteParams + * @prop {(string|undefined)=} publicKey + */ + + /** + * @type {RequestHandler} + */ + const apiGunChatsPost = async (req, res) => { + const { publicKey } = req.params + const { body } = req.body + + if (!publicKey) { + return res.status(400).json({ + errorMessage: `Must specify a publicKey route param for POSTing a message` + }) + } + + try { + const user = GunDB.getUser() + const SEA = GunDB.mySEA + + await GunActions.sendMessage(publicKey,body, user, SEA) + + return res.status(200).json({ + ok: true + }) + } catch (err) { + logger.error(err) + return res.status(500).json({ + errorMessage: err.message + }) + } + } + + ap.post(`/api/gun/chats/:publicKey?`, apiGunChatsPost) + + /** + * @typedef {object} RequestsRouteParams + * @prop {(string|undefined)=} requestID + */ + + /** + * @type {RequestHandler<{}>} + */ + const apiGunRequestsReceivedGet = (_, res) => { + try { + // spinup + Events.onSimplerReceivedRequests(() => {})() + const data = Events.getCurrentReceivedReqs() + + return res.status(200).json({ + data + }) + } catch (err) { + logger.error(err) + return res.status(500).json({ + errorMessage: err.message + }) + } + } + + /** + * @type {RequestHandler<{}>} + */ + const apiGunRequestsSentGet = (_, res) => { + try { + // spinup + Events.onSimplerSentRequests(() => {})() + const data = Events.getCurrentSentReqs() + + return res.status(200).json({ + data + }) + } catch (err) { + logger.error(err) + return res.status(500).json({ + errorMessage: err.message + }) + } + } + + /** + * @typedef {object} RequestsRoutePOSTBody + * @prop {string=} initialMsg + * @prop {string} publicKey + */ + + /** + * @type {RequestHandler<{}>} + */ + const apiGunRequestsPost = async (req, res) => { + const { initialMsg, publicKey } = /** @type {RequestsRoutePOSTBody} */(req.body) + + if (!publicKey) { + return res.status(400).json({ + errorMessage: `Must specify a publicKey route param for POSTing a message` + }) + } + + try { + const gun = require('../services/gunDB/Mediator').getGun() + const user = require('../services/gunDB/Mediator').getUser() + const SEA = require('../services/gunDB/Mediator').mySEA + + if (initialMsg) { + await GunActions.sendHRWithInitialMsg(initialMsg, publicKey, gun, user, SEA) + } else { + await GunActions.sendHandshakeRequest(publicKey, gun, user, SEA) + } + + return res.status(200).json({ + ok: true + }) + } catch (err) { + logger.error(err); + return res.status(500).json({ + errorMessage: err.message + }) + } + } + + /** + * @typedef {object} RequestsRoutePUTBody + * @prop {boolean=} accept + */ + + /** + * @type {RequestHandler} + */ + const apiGunRequestsPut = async (req, res) => { + const { requestID } = req.params + const { accept } = /** @type {RequestsRoutePUTBody} */(req.body) + + if (!requestID) { + return res.status(400).json({ + errorMessage: `Must specify a requestID route param for accepting a request` + }) + } + + if (!accept) { + return res.status(200).json({ + ok: true + }) + } + + try { + const gun = require('../services/gunDB/Mediator').getGun() + const user = require('../services/gunDB/Mediator').getUser() + const SEA = require('../services/gunDB/Mediator').mySEA + + await GunActions.acceptRequest(requestID, gun, user, SEA) + + return res.status(200).json({ + ok: true + }) + } catch (err) { + logger.error(err); + return res.status(500).json({ + errorMessage: err.message + }) + } + } + + ap.get(`/api/gun/requests/received`, apiGunRequestsReceivedGet) + ap.get(`/api/gun/requests/sent`, apiGunRequestsSentGet) + ap.post('/api/gun/requests/', apiGunRequestsPost) + ap.put(`/api/gun/requests/:requestID?`, apiGunRequestsPut) + /** * Return app so that it can be used by express. */ From ae5d713a51b8fa4de95c2ecba6bd1c39d0950600 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 20 Jul 2020 17:11:15 -0400 Subject: [PATCH 06/26] dev endpoints --- src/routes.js | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/src/routes.js b/src/routes.js index bc4554a2..7d7510ea 100644 --- a/src/routes.js +++ b/src/routes.js @@ -23,6 +23,7 @@ const GunDB = require("../services/gunDB/Mediator"); const { unprotectedRoutes, nonEncryptedRoutes } = require("../utils/protectedRoutes"); const GunActions = require("../services/gunDB/contact-api/actions") const GunGetters = require('../services/gunDB/contact-api/getters') +const GunKey = require('../services/gunDB/contact-api/key') const DEFAULT_MAX_NUM_ROUTES_TO_QUERY = 10; const SESSION_ID = uuid(); @@ -2223,6 +2224,129 @@ module.exports = async ( ap.post('/api/gun/requests/', apiGunRequestsPost) ap.put(`/api/gun/requests/:requestID?`, apiGunRequestsPut) + + + ap.get(`/api/gun/dev/userToIncoming`, async (_, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((_, u) => new Promise(res => { + u.get(GunKey.USER_TO_INCOMING).load(data => { + res(data) + }) + })) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) + + ap.get(`/api/gun/dev/recipientToOutgoing`, async (_, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((_, u) => new Promise(res => { + u.get(GunKey.RECIPIENT_TO_OUTGOING).load(data => { + res(data) + }) + })) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) + + ap.get(`/api/gun/dev/outgoings`, async (_, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((_, u) => new Promise(res => { + u.get(GunKey.OUTGOINGS).load(data => { + res(data) + }) + })) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) + + + ap.get(`/api/gun/dev/currentHandshakeAddress`, async (_, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((_, u) => u.get(GunKey.CURRENT_HANDSHAKE_ADDRESS).then()) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) + + ap.get(`/api/gun/dev/handshakeNodes/:handshakeAddress`, async (req, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((g) => + new Promise((res) => { + g.get(GunKey.HANDSHAKE_NODES).get(req.params.handshakeAddress).load(data => { + res(data) + }) + }) + ) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) + + ap.get(`/api/gun/dev/user/:publicKey`, async (req, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((g) => + new Promise((res) => { + g.user(req.params.publicKey).load(data => { + res(data) + }) + }) + ) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) + /** * Return app so that it can be used by express. */ From f84c1d1c9331216c26b349773782cc2ddc517b1b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 20 Jul 2020 19:41:01 -0400 Subject: [PATCH 07/26] disconnect route --- src/routes.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/routes.js b/src/routes.js index 7d7510ea..ecd8786a 100644 --- a/src/routes.js +++ b/src/routes.js @@ -2090,7 +2090,34 @@ module.exports = async ( } } + /** + * @type {RequestHandler} + */ + const apiGunChatsDelete = async (req, res) => { + const { publicKey } = req.params + + if (!publicKey) { + return res.status(400).json({ + errorMessage: `Must specify a publicKey route param for DELETING a chat` + }) + } + + try { + await GunActions.disconnect(publicKey) + + return res.status(200).json({ + ok: true + }) + } catch (err) { + logger.error(err) + return res.status(500).json({ + errorMessage: err.message + }) + } + } + ap.post(`/api/gun/chats/:publicKey?`, apiGunChatsPost) + ap.delete(`/api/gun/chats/:publicKey?`, apiGunChatsDelete) /** * @typedef {object} RequestsRouteParams From 5daf69788841ac40d928c67f2a1169b05681690e Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 20 Jul 2020 20:03:18 -0400 Subject: [PATCH 08/26] filter new received reqs if requestor is in disconnected state --- services/gunDB/contact-api/events/onReceivedReqs.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/events/onReceivedReqs.js b/services/gunDB/contact-api/events/onReceivedReqs.js index 0398d688..6f7aaab7 100644 --- a/services/gunDB/contact-api/events/onReceivedReqs.js +++ b/services/gunDB/contact-api/events/onReceivedReqs.js @@ -50,6 +50,7 @@ const react = debounce(() => { for (const [id, req] of Object.entries(currAddressData)) { const inContact = Array.isArray(pubToFeed[req.from]) + const isDisconnected = pubToFeed[req.from] === 'disconnected' if (typeof pubToAvatar[req.from] === 'undefined') { // eslint-disable-next-line no-empty-function @@ -60,7 +61,7 @@ const react = debounce(() => { Streams.onDisplayName(() => {}, req.from)() } - if (!inContact) { + if (!inContact && !isDisconnected) { newReceivedReqsMap[req.from] = { id, requestorAvatar: pubToAvatar[req.from] || null, From e1e6b8798138c2fff7a63cf18d0a281ba199083b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 21 Jul 2020 13:34:53 -0400 Subject: [PATCH 09/26] wait for listeners to proccess one tick before fetching --- src/routes.js | 52 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/routes.js b/src/routes.js index ecd8786a..e562c2b7 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1720,9 +1720,12 @@ module.exports = async ( try { // spinup Events.onSimplerReceivedRequests(() => {})() - const data = Events.getCurrentReceivedReqs() - res.json({ - data, + // ensure event data gets updated before fetching it + process.nextTick(() => { + const data = Events.getCurrentReceivedReqs() + res.json({ + data, + }) }) } catch (err) { logger.info('Error in Received Requests poll:') @@ -1737,10 +1740,14 @@ module.exports = async ( try { // spinup Events.onSimplerSentRequests(() => {})() - const data = Events.getCurrentSentReqs() - logger.info(`Sent requests poll: ${JSON.stringify(data, null, 4)}`) - res.json({ - data, + + // ensure event data gets updated before fetching it + process.nextTick(() => { + const data = Events.getCurrentSentReqs() + logger.info(`Sent requests poll: ${JSON.stringify(data, null, 4)}`) + res.json({ + data, + }) }) } catch (err) { logger.info('Error in sentRequests poll:') @@ -1755,10 +1762,14 @@ module.exports = async ( try { // spinup Events.onChats(() => {})() - const data = Events.getChats() - logger.info(`Chats polled: ${data.length}`) - res.json({ - data + + // ensure event data gets updated before fetching it + process.nextTick(() => { + const data = Events.getChats() + logger.info(`Chats polled: ${data.length}`) + res.json({ + data, + }) }) } catch (err) { logger.info('Error in Chats poll:') @@ -2131,10 +2142,13 @@ module.exports = async ( try { // spinup Events.onSimplerReceivedRequests(() => {})() - const data = Events.getCurrentReceivedReqs() - return res.status(200).json({ - data + // ensure event data gets updated before fetching it + process.nextTick(() => { + const data = Events.getCurrentReceivedReqs() + res.json({ + data, + }) }) } catch (err) { logger.error(err) @@ -2151,10 +2165,14 @@ module.exports = async ( try { // spinup Events.onSimplerSentRequests(() => {})() - const data = Events.getCurrentSentReqs() + - return res.status(200).json({ - data + // ensure event data gets updated before fetching it + process.nextTick(() => { + const data = Events.getCurrentSentReqs() + res.json({ + data, + }) }) } catch (err) { logger.error(err) From ef31b0c3756198edd43153d8b9a479c02f6d90f1 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 22 Jul 2020 17:34:01 -0400 Subject: [PATCH 10/26] spin up events at login --- services/gunDB/Mediator/index.js | 23 ++++++++++++ src/routes.js | 64 +++++++++----------------------- 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index bfd8764b..83a34643 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -324,6 +324,18 @@ const authenticate = async (alias, pass, __user) => { API.Jobs.onAcceptedRequests(_user, mySEA) API.Jobs.onOrders(_user, gun, mySEA) API.Jobs.lastSeenNode(_user) + + API.Events.onAvatar(() => {}, user)() + API.Events.onBio(() => {}, user) + API.Events.onBlacklist(() => {}, user) + API.Events.onChats(() => {})() + API.Events.onCurrentHandshakeAddress(() => {}, user)() + API.Events.onDisplayName(() => {}, user)() + API.Events.onOutgoing(() => {})() + API.Events.onSeedBackup(() => {}, user, mySEA) + API.Events.onSimplerReceivedRequests(() => {})() + API.Events.onSimplerSentRequests(() => {})() + return _user._.sea.pub } @@ -372,6 +384,17 @@ const authenticate = async (alias, pass, __user) => { API.Jobs.onOrders(_user, gun, mySEA) API.Jobs.lastSeenNode(_user) + API.Events.onAvatar(() => {}, user)() + API.Events.onBio(() => {}, user) + API.Events.onBlacklist(() => {}, user) + API.Events.onChats(() => {})() + API.Events.onCurrentHandshakeAddress(() => {}, user)() + API.Events.onDisplayName(() => {}, user)() + API.Events.onOutgoing(() => {})() + API.Events.onSeedBackup(() => {}, user, mySEA) + API.Events.onSimplerReceivedRequests(() => {})() + API.Events.onSimplerSentRequests(() => {})() + return ack.sea.pub } else { logger.error( diff --git a/src/routes.js b/src/routes.js index e562c2b7..15a785b7 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1718,14 +1718,9 @@ module.exports = async ( app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { try { - // spinup - Events.onSimplerReceivedRequests(() => {})() - // ensure event data gets updated before fetching it - process.nextTick(() => { - const data = Events.getCurrentReceivedReqs() - res.json({ - data, - }) + const data = Events.getCurrentReceivedReqs() + res.json({ + data, }) } catch (err) { logger.info('Error in Received Requests poll:') @@ -1738,16 +1733,10 @@ module.exports = async ( app.get(`/api/gun/${GunEvent.ON_SENT_REQUESTS}`, (_, res) => { try { - // spinup - Events.onSimplerSentRequests(() => {})() - - // ensure event data gets updated before fetching it - process.nextTick(() => { - const data = Events.getCurrentSentReqs() - logger.info(`Sent requests poll: ${JSON.stringify(data, null, 4)}`) - res.json({ - data, - }) + const data = Events.getCurrentSentReqs() + logger.info(`Sent requests poll: ${JSON.stringify(data, null, 4)}`) + res.json({ + data, }) } catch (err) { logger.info('Error in sentRequests poll:') @@ -1760,16 +1749,10 @@ module.exports = async ( app.get(`/api/gun/${GunEvent.ON_CHATS}`, (_, res) => { try { - // spinup - Events.onChats(() => {})() - - // ensure event data gets updated before fetching it - process.nextTick(() => { - const data = Events.getChats() - logger.info(`Chats polled: ${data.length}`) - res.json({ - data, - }) + const data = Events.getChats() + logger.info(`Chats polled: ${data.length}`) + res.json({ + data, }) } catch (err) { logger.info('Error in Chats poll:') @@ -2140,15 +2123,9 @@ module.exports = async ( */ const apiGunRequestsReceivedGet = (_, res) => { try { - // spinup - Events.onSimplerReceivedRequests(() => {})() - - // ensure event data gets updated before fetching it - process.nextTick(() => { - const data = Events.getCurrentReceivedReqs() - res.json({ - data, - }) + const data = Events.getCurrentReceivedReqs() + res.json({ + data, }) } catch (err) { logger.error(err) @@ -2163,16 +2140,9 @@ module.exports = async ( */ const apiGunRequestsSentGet = (_, res) => { try { - // spinup - Events.onSimplerSentRequests(() => {})() - - - // ensure event data gets updated before fetching it - process.nextTick(() => { - const data = Events.getCurrentSentReqs() - res.json({ - data, - }) + const data = Events.getCurrentSentReqs() + res.json({ + data, }) } catch (err) { logger.error(err) From bb1138579d007d426f2823f91b50a3c17541a8c7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 13:01:43 -0400 Subject: [PATCH 11/26] work around load() bug --- services/gunDB/contact-api/getters/index.js | 14 ++++- services/gunDB/contact-api/getters/user.js | 14 ++++- src/routes.js | 66 +++++++++++++++++++-- 3 files changed, 87 insertions(+), 7 deletions(-) diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 3a82e410..4472ed41 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -9,6 +9,7 @@ const Utils = require('../utils') const Wall = require('./wall') const Feed = require('./feed') const User = require('./user') +const { size } = require('lodash') /** * @param {string} pub @@ -51,7 +52,18 @@ exports.userToIncomingID = async pub => { const getMyUser = async () => { const oldProfile = await Utils.tryAndWait( (_, user) => new Promise(res => user.get(Key.PROFILE).load(res)), - v => typeof v !== 'object' + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + } ) const bio = await Utils.tryAndWait( diff --git a/services/gunDB/contact-api/getters/user.js b/services/gunDB/contact-api/getters/user.js index fb8054e1..52d04e72 100644 --- a/services/gunDB/contact-api/getters/user.js +++ b/services/gunDB/contact-api/getters/user.js @@ -2,6 +2,7 @@ * @format */ const Common = require('shock-common') +const size = require('lodash/size') const Key = require('../key') const Utils = require('../utils') @@ -72,7 +73,18 @@ module.exports.getAnUser = getAnUser const getMyUser = async () => { const oldProfile = await Utils.tryAndWait( (_, user) => new Promise(res => user.get(Key.PROFILE).load(res)), - v => typeof v !== 'object' + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + } ) const bio = await Utils.tryAndWait( diff --git a/src/routes.js b/src/routes.js index 15a785b7..dcffb4cc 100644 --- a/src/routes.js +++ b/src/routes.js @@ -13,6 +13,7 @@ const responseTime = require("response-time"); const uuid = require("uuid/v4"); const Common = require('shock-common') const isARealUsableNumber = require('lodash/isFinite') +const size = require('lodash/size') const getListPage = require("../utils/paginate"); const auth = require("../services/auth/auth"); @@ -2249,7 +2250,18 @@ module.exports = async ( u.get(GunKey.USER_TO_INCOMING).load(data => { res(data) }) - })) + }), v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) return res.status(200).json({ data @@ -2269,7 +2281,18 @@ module.exports = async ( u.get(GunKey.RECIPIENT_TO_OUTGOING).load(data => { res(data) }) - })) + }), v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) return res.status(200).json({ data @@ -2289,7 +2312,18 @@ module.exports = async ( u.get(GunKey.OUTGOINGS).load(data => { res(data) }) - })) + }), v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) return res.status(200).json({ data @@ -2328,7 +2362,18 @@ module.exports = async ( res(data) }) }) - ) + , v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) return res.status(200).json({ data @@ -2350,7 +2395,18 @@ module.exports = async ( res(data) }) }) - ) + , v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) return res.status(200).json({ data From 1eb4c59ab60ecfa45b9575ef5ee09a5bcc2c73a2 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 13:12:37 -0400 Subject: [PATCH 12/26] commenting --- services/gunDB/contact-api/getters/follows.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/gunDB/contact-api/getters/follows.js b/services/gunDB/contact-api/getters/follows.js index 22a49333..55ed47f8 100644 --- a/services/gunDB/contact-api/getters/follows.js +++ b/services/gunDB/contact-api/getters/follows.js @@ -28,6 +28,7 @@ exports.currentFollows = async () => { return true } + // load sometimes returns an empty set on the first try if (size(v) === 0) { return true } From 2a68ff87434fade5c81a34459690b6245aca5d86 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 17:43:40 -0400 Subject: [PATCH 13/26] less extraneous data logs --- services/gunDB/contact-api/events/onReceivedReqs.js | 3 ++- services/gunDB/contact-api/events/onSentReqs.js | 7 +++---- services/gunDB/contact-api/streams/pubToFeed.js | 3 ++- services/gunDB/contact-api/streams/pubToIncoming.js | 5 ++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/gunDB/contact-api/events/onReceivedReqs.js b/services/gunDB/contact-api/events/onReceivedReqs.js index 6f7aaab7..9a18a29b 100644 --- a/services/gunDB/contact-api/events/onReceivedReqs.js +++ b/services/gunDB/contact-api/events/onReceivedReqs.js @@ -2,6 +2,7 @@ const debounce = require('lodash/debounce') const logger = require('winston') const { Schema } = require('shock-common') +const size = require('lodash/size') const Key = require('../key') const Streams = require('../streams') @@ -96,7 +97,7 @@ const listenerForAddr = addr => data => { } } - logger.info('data for address: ' + addr) + logger.info('data for address length: ' + size(addr)) logger.info(JSON.stringify(data, null, 4)) react() diff --git a/services/gunDB/contact-api/events/onSentReqs.js b/services/gunDB/contact-api/events/onSentReqs.js index 03686a2d..87c40dc1 100644 --- a/services/gunDB/contact-api/events/onSentReqs.js +++ b/services/gunDB/contact-api/events/onSentReqs.js @@ -1,6 +1,7 @@ /** @format */ const debounce = require('lodash/debounce') const logger = require('winston') +const size = require('lodash/size') const Streams = require('../streams') /** @@ -29,7 +30,7 @@ const listeners = new Set() let currentReqs = [] listeners.add(() => { - logger.info(`new sent reqs: ${JSON.stringify(currentReqs)}`) + logger.info(`new sent reqs length: ${currentReqs}`) }) const getCurrentSentReqs = () => currentReqs @@ -55,9 +56,7 @@ const react = debounce(() => { // pk to display name const pubToDN = Streams.getPubToDn() - logger.info( - `pubToLastSentREqID: ${JSON.stringify(pubToLastSentReqID, null, 4)}` - ) + logger.info(`pubToLastSentREqID length: ${size(pubToLastSentReqID)}`) for (const storedReq of storedReqs) { const { handshakeAddress, recipientPub, sentReqID, timestamp } = storedReq diff --git a/services/gunDB/contact-api/streams/pubToFeed.js b/services/gunDB/contact-api/streams/pubToFeed.js index 30e49394..f6f96cc4 100644 --- a/services/gunDB/contact-api/streams/pubToFeed.js +++ b/services/gunDB/contact-api/streams/pubToFeed.js @@ -3,6 +3,7 @@ const uuidv1 = require('uuid/v1') const logger = require('winston') const debounce = require('lodash/debounce') const { Schema, Utils: CommonUtils } = require('shock-common') +const size = require('lodash/size') const Key = require('../key') const Utils = require('../utils') @@ -29,7 +30,7 @@ let pubToFeed = {} const getPubToFeed = () => pubToFeed feedsListeners.add(() => { - logger.info(`new pubToFeed: ${JSON.stringify(getPubToFeed())}`) + logger.info(`new pubToFeed length: ${size(getPubToFeed())}`) }) /** @param {Feeds} ptf */ diff --git a/services/gunDB/contact-api/streams/pubToIncoming.js b/services/gunDB/contact-api/streams/pubToIncoming.js index 72b18b9d..2834ca79 100644 --- a/services/gunDB/contact-api/streams/pubToIncoming.js +++ b/services/gunDB/contact-api/streams/pubToIncoming.js @@ -3,6 +3,7 @@ const uuidv1 = require('uuid/v1') const debounce = require('lodash/debounce') const logger = require('winston') const { Utils: CommonUtils } = require('shock-common') +const size = require('lodash/size') const { USER_TO_INCOMING } = require('../key') /** @typedef {import('../SimpleGUN').OpenListenerData} OpenListenerData */ @@ -30,9 +31,7 @@ const setPubToIncoming = pti => { let latestUpdate = uuidv1() listeners.add(() => { - logger.info( - `new pubToIncoming: ${JSON.stringify(getPubToIncoming(), null, 4)}` - ) + logger.info(`new pubToIncoming length: ${size(getPubToIncoming())}`) }) const onOpen = debounce(async uti => { From 0088b7d8cf6b4affcd4711caae3adbda995a3570 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 20:16:10 -0400 Subject: [PATCH 14/26] sendMessageNew(), returns the created RES --- services/gunDB/contact-api/actions.js | 25 ++++++++++++++++--- .../contact-api/events/onReceivedReqs.js | 1 - 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index a0ae6171..699d3c62 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -631,9 +631,9 @@ const sendHandshakeRequest = async (recipientPublicKey, gun, user, SEA) => { * @param {string} body * @param {UserGUNNode} user * @param {ISEA} SEA - * @returns {Promise} The message id. + * @returns {Promise} The message id. */ -const sendMessage = async (recipientPublicKey, body, user, SEA) => { +const sendMessageNew = async (recipientPublicKey, body, user, SEA) => { if (!user.is) { throw new Error(ErrorCode.NOT_AUTH) } @@ -691,12 +691,28 @@ const sendMessage = async (recipientPublicKey, body, user, SEA) => { if (ack.err) { rej(new Error(ack.err)) } else { - res(msgNode._.get) + res({ + body, + id: msgNode._.get, + outgoing: true, + timestamp: newMessage.timestamp + }) } }) }) } +/** + * Returns the message id. + * @param {string} recipientPublicKey + * @param {string} body + * @param {UserGUNNode} user + * @param {ISEA} SEA + * @returns {Promise} The message id. + */ +const sendMessage = async (recipientPublicKey, body, user, SEA) => + (await sendMessageNew(recipientPublicKey, body, user, SEA)).id + /** * @param {string} recipientPub * @param {string} msgID @@ -1589,5 +1605,6 @@ module.exports = { deletePost, follow, unfollow, - initWall + initWall, + sendMessageNew } diff --git a/services/gunDB/contact-api/events/onReceivedReqs.js b/services/gunDB/contact-api/events/onReceivedReqs.js index 9a18a29b..a0b74e30 100644 --- a/services/gunDB/contact-api/events/onReceivedReqs.js +++ b/services/gunDB/contact-api/events/onReceivedReqs.js @@ -98,7 +98,6 @@ const listenerForAddr = addr => data => { } logger.info('data for address length: ' + size(addr)) - logger.info(JSON.stringify(data, null, 4)) react() } From 41649c7bceb9c21f0dda4946ac3ef0bc9d09a9fc Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 23:04:11 -0400 Subject: [PATCH 15/26] use same handler --- src/routes.js | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/routes.js b/src/routes.js index dcffb4cc..39c035d9 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1717,37 +1717,6 @@ module.exports = async ( const Events = require('../services/gunDB/contact-api/events') - app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { - try { - const data = Events.getCurrentReceivedReqs() - res.json({ - data, - }) - } catch (err) { - logger.info('Error in Received Requests poll:') - logger.error(err) - res.status(err.message === 'NON_AUTH' ? 401 : 500).json({ - errorMessage: typeof err === 'string' ? err : err.message - }) - } - }) - - app.get(`/api/gun/${GunEvent.ON_SENT_REQUESTS}`, (_, res) => { - try { - const data = Events.getCurrentSentReqs() - logger.info(`Sent requests poll: ${JSON.stringify(data, null, 4)}`) - res.json({ - data, - }) - } catch (err) { - logger.info('Error in sentRequests poll:') - logger.error(err) - res.status(err.message === 'NON_AUTH' ? 401 : 500).json({ - errorMessage: typeof err === 'string' ? err : err.message - }) - } - }) - app.get(`/api/gun/${GunEvent.ON_CHATS}`, (_, res) => { try { const data = Events.getChats() @@ -2235,6 +2204,8 @@ module.exports = async ( } } + ap.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, apiGunRequestsReceivedGet) + ap.get(`/api/gun/${GunEvent.ON_SENT_REQUESTS}`, apiGunRequestsSentGet) ap.get(`/api/gun/requests/received`, apiGunRequestsReceivedGet) ap.get(`/api/gun/requests/sent`, apiGunRequestsSentGet) ap.post('/api/gun/requests/', apiGunRequestsPost) From fc32cf39965786fd7ca145202cb4f3cb8d9d3113 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 23:04:22 -0400 Subject: [PATCH 16/26] null check --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 39c035d9..ef3d0bba 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1737,7 +1737,7 @@ module.exports = async ( try { const user = require('../services/gunDB/Mediator').getUser() const data = await timeout5(user.get(Key.PROFILE).get(Key.AVATAR).then()) - logger.info(`avatar poll:${data.length} chars`) + logger.info(`avatar poll:${(data || '').length} chars`) res.json({ data }) From 55fb361c5c7f9890fc25ff5497523493cac80412 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 23 Jul 2020 23:04:37 -0400 Subject: [PATCH 17/26] send back created resource --- src/routes.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/routes.js b/src/routes.js index ef3d0bba..4e0dce0e 100644 --- a/src/routes.js +++ b/src/routes.js @@ -2041,11 +2041,9 @@ module.exports = async ( const user = GunDB.getUser() const SEA = GunDB.mySEA - await GunActions.sendMessage(publicKey,body, user, SEA) - - return res.status(200).json({ - ok: true - }) + return res.status(200).json( + await GunActions.sendMessageNew(publicKey,body, user, SEA) + ) } catch (err) { logger.error(err) return res.status(500).json({ From 18844d2c55c9ed1974393c2805fc6c9912d31b3f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 24 Jul 2020 10:52:22 -0400 Subject: [PATCH 18/26] remove debug code --- src/routes.js | 70 --------------------------------------------------- 1 file changed, 70 deletions(-) diff --git a/src/routes.js b/src/routes.js index 4e0dce0e..c0b613c1 100644 --- a/src/routes.js +++ b/src/routes.js @@ -439,76 +439,6 @@ module.exports = async ( }); - /* - const feedObj = { - feed: [ - { - id:'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', - paragraphs:[ - "SOme text and stuff 12" - "SOme text and stuff" - ], - profilePic:"", - username:"bobni", - media:[ - { - type:'VIDEO', - ratio_x: 1024, - ratio_y: 436, - magnetUri:'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent', - }, - ] - }, - { - id:'3ac68afc-c605-48d3-a4f8-fbd91aa97f63', - paragraphs:[ - "SOme text and stuff" - ], - profilePic:"", - username:"bobni", - media:[ - { - type:'VIDEO', - ratio_x: 1920, - ratio_y: 804, - magnetUri:'magnet:?xt=urn:btih:c9e15763f722f23e98a29decdfae341b98d53056&dn=Cosmos+Laundromat&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fcosmos-laundromat.torrent', - }, - ] - }, - { - id:'58694a0f-3da1-471f-bd96-145571e29d72', - paragraphs:[ - "SOme text and stuff" - ], - profilePic:"", - username:"bobni", - media:[ - { - type:'VIDEO', - ratio_x: 1920, - ratio_y: 1080, - magnetUri:'magnet:?xt=urn:btih:dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c&dn=Big+Buck+Bunny&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fbig-buck-bunny.torrent', - }, - ] - } - ] - } - user.get("FEED_POC").put(JSON.stringify(feedObj), ack => { - if (ack.err) { - //rej(new Error(ack.err)) - }*/ - const feedObj = { - feed :{} - } - user.get("FEED_POC").put(feedObj, ack => { - if (ack.err) { - //rej(ack.err) - logger.log(ack.err) - } else { - logger.log(ack.err) - } - }) - //register to listen for channel backups const onNewChannelBackup = () => { logger.warn("Subscribing to channel backup ...") From cd9c7983c884e75992c7e9c2842316b0cf0aef92 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 24 Jul 2020 12:15:07 -0400 Subject: [PATCH 19/26] run disconnect-related writes in parallel --- services/gunDB/contact-api/actions.js | 100 ++++++++++++++------------ 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 699d3c62..8bd27958 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -372,50 +372,13 @@ const cleanup = async pub => { const outGoingID = await Utils.recipientToOutgoingID(pub) - await new Promise((res, rej) => { - user - .get(Key.USER_TO_INCOMING) - .get(pub) - .put(null, ack => { - if (ack.err) { - rej(new Error(ack.err)) - } else { - res() - } - }) - }) + const promises = [] - await new Promise((res, rej) => { - user - .get(Key.RECIPIENT_TO_OUTGOING) - .get(pub) - .put(null, ack => { - if (ack.err) { - rej(new Error(ack.err)) - } else { - res() - } - }) - }) - - await new Promise((res, rej) => { - user - .get(Key.USER_TO_LAST_REQUEST_SENT) - .get(pub) - .put(null, ack => { - if (ack.err) { - rej(new Error(ack.err)) - } else { - res() - } - }) - }) - - if (outGoingID) { - await new Promise((res, rej) => { + promises.push( + new Promise((res, rej) => { user - .get(Key.OUTGOINGS) - .get(outGoingID) + .get(Key.USER_TO_INCOMING) + .get(pub) .put(null, ack => { if (ack.err) { rej(new Error(ack.err)) @@ -424,7 +387,56 @@ const cleanup = async pub => { } }) }) + ) + + promises.push( + new Promise((res, rej) => { + user + .get(Key.RECIPIENT_TO_OUTGOING) + .get(pub) + .put(null, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + ) + + promises.push( + new Promise((res, rej) => { + user + .get(Key.USER_TO_LAST_REQUEST_SENT) + .get(pub) + .put(null, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + ) + + if (outGoingID) { + promises.push( + new Promise((res, rej) => { + user + .get(Key.OUTGOINGS) + .get(outGoingID) + .put(null, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + ) } + + await Promise.all(promises) } /** @@ -1227,9 +1239,7 @@ const disconnect = async pub => { throw new Error('No handshake exists for this pub') } - await cleanup(pub) - - await generateHandshakeAddress() + await Promise.all([cleanup(pub), generateHandshakeAddress()]) } /** From b7ad45f1d5a15b0c2da4033fcf401d9893f26dfc Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 24 Jul 2020 12:16:17 -0400 Subject: [PATCH 20/26] storedReqs dev endpoint --- src/routes.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/routes.js b/src/routes.js index c0b613c1..fde63091 100644 --- a/src/routes.js +++ b/src/routes.js @@ -2317,6 +2317,35 @@ module.exports = async ( } }) + + ap.get(`/api/gun/dev/storedReqs`, async (req, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((_, u) => + new Promise((res) => u.get(Key.STORED_REQS).load(res)) + , v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) /** * Return app so that it can be used by express. */ From 89b1263e8087c35c8fb482adde1b455482167aec Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 24 Jul 2020 12:43:16 -0400 Subject: [PATCH 21/26] handshake address regen through HTTP --- src/routes.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index fde63091..5b783321 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1920,8 +1920,13 @@ module.exports = async ( * @type {RequestHandler<{}>} */ const apiGunMePut = async (req, res) => { + /** + * @typedef {Omit} UserWithoutPK + * @typedef {{ handshakeAddress: boolean }} HasHandshakeAddress + * @typedef {UserWithoutPK & HasHandshakeAddress} MePutBody + */ try { - const { avatar, bio , displayName} = /** @type {Partial>} */ (req.body) + const { avatar, bio , displayName, handshakeAddress } = /** @type {Partial} */ (req.body) if (avatar) { await GunActions.setAvatar(avatar, require('../services/gunDB/Mediator').getUser()) @@ -1935,6 +1940,10 @@ module.exports = async ( await GunActions.setDisplayName(displayName, require('../services/gunDB/Mediator').getUser()) } + if (handshakeAddress) { + await GunActions.generateHandshakeAddress(); + } + return res.status(200).json({ ok: true }) From 3c52eb26e32119f97a7b640d54e30ec19af9b248 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 24 Jul 2020 12:44:21 -0400 Subject: [PATCH 22/26] user to last request sent dev endpoint --- src/routes.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/routes.js b/src/routes.js index 5b783321..cb9d9438 100644 --- a/src/routes.js +++ b/src/routes.js @@ -2355,6 +2355,35 @@ module.exports = async ( }) } }) + + ap.get(`/api/gun/dev/userToLastReqSent`, async (req, res) => { + try { + const {tryAndWait} = require('../services/gunDB/contact-api/utils') + + const data = await tryAndWait((_, u) => + new Promise((res) => u.get(Key.USER_TO_LAST_REQUEST_SENT).load(res)) + , v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 + }) + + return res.status(200).json({ + data + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) /** * Return app so that it can be used by express. */ From 7b0d3892d5db9e7b07c6d8310c898567648ed395 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 25 Jul 2020 08:51:42 -0400 Subject: [PATCH 23/26] better logs --- services/gunDB/contact-api/events/onSentReqs.js | 2 +- services/gunDB/contact-api/streams/addresses.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/events/onSentReqs.js b/services/gunDB/contact-api/events/onSentReqs.js index 87c40dc1..93e0740d 100644 --- a/services/gunDB/contact-api/events/onSentReqs.js +++ b/services/gunDB/contact-api/events/onSentReqs.js @@ -30,7 +30,7 @@ const listeners = new Set() let currentReqs = [] listeners.add(() => { - logger.info(`new sent reqs length: ${currentReqs}`) + logger.info(`new sent reqs length: ${size(currentReqs)}`) }) const getCurrentSentReqs = () => currentReqs diff --git a/services/gunDB/contact-api/streams/addresses.js b/services/gunDB/contact-api/streams/addresses.js index d35513dd..705e8b4c 100644 --- a/services/gunDB/contact-api/streams/addresses.js +++ b/services/gunDB/contact-api/streams/addresses.js @@ -1,5 +1,6 @@ /** @format */ const logger = require('winston') +const size = require('lodash/size') const Key = require('../key') /** @@ -13,7 +14,7 @@ const pubToAddress = {} const listeners = new Set() listeners.add(() => { - logger.info(`pubToAddress: ${JSON.stringify(pubToAddress, null, 4)}`) + logger.info(`pubToAddress length: ${size(pubToAddress)}`) }) const notify = () => listeners.forEach(l => l()) From 788e871392e62e8070b12b754f5dc013ed63328a Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 25 Jul 2020 10:14:41 -0400 Subject: [PATCH 24/26] size() as catch-all --- services/gunDB/contact-api/jobs/onAcceptedRequests.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/jobs/onAcceptedRequests.js b/services/gunDB/contact-api/jobs/onAcceptedRequests.js index 55568679..51f82bff 100644 --- a/services/gunDB/contact-api/jobs/onAcceptedRequests.js +++ b/services/gunDB/contact-api/jobs/onAcceptedRequests.js @@ -6,6 +6,7 @@ const { Constants: { ErrorCode }, Schema } = require('shock-common') +const size = require('lodash/size') const Key = require('../key') const Utils = require('../utils') @@ -126,8 +127,8 @@ const onAcceptedRequests = (user, SEA) => { res(feed) }) }), - // retry on undefined, might be a false negative - v => typeof v === 'undefined' + // @ts-expect-error + v => size(v) === 0 ) const feedIDExistsOnRecipientsOutgoings = From d12656d1545ca95b56cbd5a7b69ccdad2b853800 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 25 Jul 2020 10:15:53 -0400 Subject: [PATCH 25/26] throw instead of log --- services/gunDB/contact-api/jobs/onAcceptedRequests.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/jobs/onAcceptedRequests.js b/services/gunDB/contact-api/jobs/onAcceptedRequests.js index 51f82bff..dbbd6215 100644 --- a/services/gunDB/contact-api/jobs/onAcceptedRequests.js +++ b/services/gunDB/contact-api/jobs/onAcceptedRequests.js @@ -40,15 +40,16 @@ const onAcceptedRequests = (user, SEA) => { logger.info( `------------------------------------\nPROCID:${procid} (used for debugging memory leaks in jobs)\n---------------------------------------` ) + const mySecret = require('../../Mediator').getMySecret() + try { if (!Schema.isStoredRequest(storedReq)) { - logger.warn( + throw new Error( 'Stored request not an StoredRequest, instead got: ' + JSON.stringify(storedReq) + ' this can be due to nulling out an old request (if null) or something else happened (please look at the output)' ) - return } const recipientPub = await SEA.decrypt(storedReq.recipientPub, mySecret) From 7ca39103b2c53a387baca78fca0253c73ce3d516 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 25 Jul 2020 10:16:18 -0400 Subject: [PATCH 26/26] comments/messages --- .../gunDB/contact-api/jobs/onAcceptedRequests.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/services/gunDB/contact-api/jobs/onAcceptedRequests.js b/services/gunDB/contact-api/jobs/onAcceptedRequests.js index dbbd6215..5408b469 100644 --- a/services/gunDB/contact-api/jobs/onAcceptedRequests.js +++ b/services/gunDB/contact-api/jobs/onAcceptedRequests.js @@ -51,14 +51,20 @@ const onAcceptedRequests = (user, SEA) => { ' this can be due to nulling out an old request (if null) or something else happened (please look at the output)' ) } + // get the recipient pub from the stored request to avoid an attacker + // overwriting the handshake request in the root graph const recipientPub = await SEA.decrypt(storedReq.recipientPub, mySecret) if (typeof recipientPub !== 'string') { - throw new TypeError() + throw new TypeError( + `Expected storedReq.recipientPub to be an string, instead got: ${recipientPub}` + ) } + if (await Utils.successfulHandshakeAlreadyExists(recipientPub)) { return } + const requestAddress = await SEA.decrypt( storedReq.handshakeAddress, mySecret @@ -101,9 +107,9 @@ const onAcceptedRequests = (user, SEA) => { return } - // The response can be decrypted with the same secret regardless of who - // wrote to it last (see HandshakeRequest definition). - // This could be our feed ID for the recipient, or the recipient's feed + // The response can be decrypted with the same secret regardless + // of who wrote to it last (see HandshakeRequest definition). This + // could be our feed ID for the recipient, or the recipient's feed // id if he accepted the request. const feedID = await SEA.decrypt(sentReq.response, ourSecret)