From 460ccb8383f0f12065456fc2d52edd7f4d8d4f9f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 13:13:54 -0400 Subject: [PATCH 001/124] upgrade shock-common --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 59984e1e..52b8992c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "request-promise": "^4.2.2", "response-time": "^2.3.2", "shelljs": "^0.8.2", - "shock-common": "^0.0.1", + "shock-common": "0.x.x", "socket.io": "2.1.1", "text-encoding": "^0.7.0", "tingodb": "^0.6.1", diff --git a/yarn.lock b/yarn.lock index 343ee681..6221484f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5876,10 +5876,10 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -shock-common@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.0.1.tgz#72092c565ab65198da13656b5027fbd44881bf72" - integrity sha512-LV2WiJDr1E6TEWel095oLN6gxpGTmsg6CUeGB6DdLHbYEz0qSpcDG4MYp2mZGpj/DejNKwYg1EiX2qf7ArpIkQ== +shock-common@0.x.x: + version "0.2.0" + resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.2.0.tgz#b942d4b8730890aaf192eb873957c235333eddca" + integrity sha512-K9UysxR4LnArhljK3kRNdRM2yeI52YxPe0dZ62SNvsHO5oJgE6wDV0qGy9UZYS5FoAprF5QRzzADxgqmGWin+Q== dependencies: lodash "^4.17.15" normalizr "^3.6.0" From 9f131db7e343fd60810daea9cada19934b4ee237 Mon Sep 17 00:00:00 2001 From: emad-salah Date: Sun, 31 May 2020 18:39:40 +0100 Subject: [PATCH 002/124] Added support for disabling encryption via .env --- .env.example | 1 + src/routes.js | 5 ++--- src/server.js | 13 ++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..8a042b30 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +DISABLE_SHOCK_ENCRYPTION=false \ No newline at end of file diff --git a/src/routes.js b/src/routes.js index 06762f2f..6d697007 100644 --- a/src/routes.js +++ b/src/routes.js @@ -227,7 +227,7 @@ module.exports = async ( const deviceId = req.headers["x-shockwallet-device-id"]; logger.debug("Decrypting route...") try { - if (nonEncryptedRoutes.includes(req.path)) { + if (nonEncryptedRoutes.includes(req.path) || process.env.DISABLE_SHOCK_ENCRYPTION) { return next(); } @@ -1617,6 +1617,7 @@ module.exports = async ( const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') + const { timeout5 } = require('../services/gunDB/contact-api/utils') app.get("/api/gun/lndchanbackups", async (req,res) => { try{ const user = require('../services/gunDB/Mediator').getUser() @@ -1633,8 +1634,6 @@ module.exports = async ( }) const Events = require('../services/gunDB/contact-api/events') - - const {timeout5} = require('../services/gunDB/contact-api/utils') app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { try { diff --git a/src/server.js b/src/server.js index c55393d6..acd92cf2 100644 --- a/src/server.js +++ b/src/server.js @@ -9,6 +9,7 @@ const server = program => { const Http = require('http') const Express = require('express') const Crypto = require('crypto') + const Dotenv = require('dotenv') const LightningServices = require('../utils/lightningServices') const Encryption = require('../utils/encryptionStore') const app = Express() @@ -25,6 +26,7 @@ const server = program => { // load app default configuration data const defaults = require('../config/defaults')(program.mainnet) // define useful global variables ====================================== + Dotenv.config() module.useTLS = program.usetls module.serverPort = program.serverport || defaults.serverPort module.httpsPort = module.serverPort @@ -41,6 +43,12 @@ const server = program => { logger.info('Mainnet Mode:', !!program.mainnet) + if (process.env.DISABLE_SHOCK_ENCRYPTION) { + logger.error('Encryption Mode: false') + } else { + logger.info('Encryption Mode: true') + } + const stringifyData = data => { if (typeof data === 'object') { const stringifiedData = JSON.stringify(data) @@ -64,7 +72,10 @@ const server = program => { const deviceId = req.headers['x-shockwallet-device-id'] const oldSend = res.send - if (!nonEncryptedRoutes.includes(req.path)) { + if ( + !nonEncryptedRoutes.includes(req.path) && + !process.env.DISABLE_SHOCK_ENCRYPTION + ) { res.send = (...args) => { if (args[0] && args[0].encryptedData && args[0].encryptionKey) { logger.warn('Response loop detected!') From b6a680d550c4c699acd590bee66d6dcebf24da82 Mon Sep 17 00:00:00 2001 From: emad-salah Date: Fri, 5 Jun 2020 18:48:28 +0100 Subject: [PATCH 003/124] Fixed error when sending empty body responses and fixed eslint error --- src/routes.js | 6 +++--- src/server.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes.js b/src/routes.js index 06762f2f..ceb17e18 100644 --- a/src/routes.js +++ b/src/routes.js @@ -249,7 +249,7 @@ module.exports = async ( return res.status(401).json(error); } - if (req.method === "GET") { + if (req.method === "GET" || req.method === "DELETE" || !req.body.encryptionKey && !req.body.iv) { return next(); } @@ -1617,6 +1617,8 @@ module.exports = async ( const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') + const { timeout5 } = require('../services/gunDB/contact-api/utils') + app.get("/api/gun/lndchanbackups", async (req,res) => { try{ const user = require('../services/gunDB/Mediator').getUser() @@ -1633,8 +1635,6 @@ module.exports = async ( }) const Events = require('../services/gunDB/contact-api/events') - - const {timeout5} = require('../services/gunDB/contact-api/utils') app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { try { diff --git a/src/server.js b/src/server.js index c55393d6..c92b9b83 100644 --- a/src/server.js +++ b/src/server.js @@ -89,7 +89,7 @@ const server = program => { const authorized = Encryption.isAuthorizedDevice({ deviceId }) const encryptedMessage = authorized ? Encryption.encryptMessage({ - message: args[0], + message: args[0] ? args[0] : {}, deviceId, metadata: { hash: dataHash From 8d1aae0ac37f29e758951e72036e63c89e1e67ce Mon Sep 17 00:00:00 2001 From: boufni95 Date: Fri, 12 Jun 2020 19:03:43 +0200 Subject: [PATCH 004/124] wall add and delete --- services/gunDB/contact-api/actions.js | 85 ++++++++++++++++++++++++++- services/gunDB/contact-api/key.js | 6 ++ src/routes.js | 23 +++++++- 3 files changed, 112 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index b4fe5bed..ef145e1b 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1217,6 +1217,87 @@ const setLastSeenApp = () => } }) }) +const maxPostPerPage = 10 +/** + * @param {string} tags + * @param {string} title + * @param {Record} content + * @returns {Promise} + */ +const createPost = async (tags, title, content) => { + const user = require('../Mediator').getUser() + const wall = user.get(Key.WALL) + if (!wall) { + throw new Error('wall not found') + } + let lastPageNum = await wall.get(Key.NUM_OF_PAGES).then() + if (typeof lastPageNum !== 'number') { + throw new Error('page not found') + } + const lastPage = await new Promise(res => { + if (typeof lastPageNum !== 'number') { + throw new Error('page not found') + } + wall + .get(Key.PAGES) + .get(lastPageNum.toString()) + //@ts-ignore + .load(res) + }) + + const numPosts = Object.keys(lastPage).length + if (numPosts === maxPostPerPage) { + lastPageNum++ + await new Promise((res, rej) => { + if (typeof lastPageNum !== 'number') { + throw new Error('page not found') + } + wall.get(Key.NUM_OF_PAGES).put(lastPageNum, ack => { + if (ack.err) { + rej(ack.err) + } else { + res() + } + }) + }) + } + /** + * @type {import('shock-common').Schema.Post} + */ + const post = { + contentItems: content, + date: +Date(), + status: 'publish', + tags, + title + } + //** @type {string} */ + /*const newPostID = */ await new Promise((res, rej) => { + if (typeof lastPageNum !== 'number') { + throw new Error('page not found') + } + const _wallNode = wall + .get(Key.PAGES) + .get(lastPageNum.toString()) + //@ts-ignore + .set(post, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res(_wallNode._.get) + } + }) + }) +} +/** + * @param {string} postId + * @returns {Promise} + */ +const deletePost = async postId => { + await new Promise(res => { + res(postId) + }) +} module.exports = { __createOutgoingFeed, @@ -1236,5 +1317,7 @@ module.exports = { saveSeedBackup, saveChannelsBackup, disconnect, - setLastSeenApp + setLastSeenApp, + createPost, + deletePost } diff --git a/services/gunDB/contact-api/key.js b/services/gunDB/contact-api/key.js index be14b788..4e7e3115 100644 --- a/services/gunDB/contact-api/key.js +++ b/services/gunDB/contact-api/key.js @@ -42,3 +42,9 @@ exports.CHANNELS_BACKUP = 'channelsBackup' exports.LAST_SEEN_APP = 'lastSeenApp' exports.LAST_SEEN_NODE = 'lastSeenNode' + +exports.WALL = 'wall' + +exports.NUM_OF_PAGES = 'numOfPages' + +exports.PAGES = 'pages' diff --git a/src/routes.js b/src/routes.js index 594f226e..48c08b65 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1616,8 +1616,8 @@ module.exports = async ( }); const GunEvent = Common.Constants.Event + const {timeout5} = require('../services/gunDB/contact-api/utils') const Key = require('../services/gunDB/contact-api/key') - const { timeout5 } = require('../services/gunDB/contact-api/utils') app.get("/api/gun/lndchanbackups", async (req,res) => { try{ @@ -1757,6 +1757,27 @@ module.exports = async ( } }) + app.post(`/api/gun/wall`, async (req,res) => { + try{ + const {tags,title,contentItems} = req.body + res.status(201).json(await GunActions.createPost(title,tags,contentItems)) + } catch(e) { + const {tags,title,contentItems} = req.body + if(!tags || !title || !contentItems) { + res.status(400).json({ + errorMessage: 'missing params' + }) + } + res.status(500).json({ + errorMessage: typeof e === 'string' ? e : e.message + }) + } + }) + + app.delete(`/api/gun/wall/:postID`,async (req,res) => { + //res.status(200).json(await GunActions.deletePost(postID)) + }) + /** * Return app so that it can be used by express. */ From ee7a4e8ed055a3aeffc3e38655bc7769e924485d Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 09:59:11 -0400 Subject: [PATCH 005/124] upgrade shock-common --- package.json | 2 +- yarn.lock | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 52b8992c..03efcc0c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "request-promise": "^4.2.2", "response-time": "^2.3.2", "shelljs": "^0.8.2", - "shock-common": "0.x.x", + "shock-common": "3.0.0", "socket.io": "2.1.1", "text-encoding": "^0.7.0", "tingodb": "^0.6.1", diff --git a/yarn.lock b/yarn.lock index 6221484f..e0091187 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3168,6 +3168,11 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +immer@^6.0.6: + version "6.0.9" + resolved "https://registry.yarnpkg.com/immer/-/immer-6.0.9.tgz#b9dd69b8e69b3a12391e87db1e3ff535d1b26485" + integrity sha512-SyCYnAuiRf67Lvk0VkwFvwtDoEiCMjeamnHvRfnVDyc7re1/rQrNxuL+jJ7lA3WvdC4uznrvbmm+clJ9+XXatg== + import-fresh@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" @@ -5500,6 +5505,19 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== + +redux@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" + integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== + dependencies: + loose-envify "^1.4.0" + symbol-observable "^1.2.0" + regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" @@ -5876,13 +5894,17 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -shock-common@0.x.x: - version "0.2.0" - resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.2.0.tgz#b942d4b8730890aaf192eb873957c235333eddca" - integrity sha512-K9UysxR4LnArhljK3kRNdRM2yeI52YxPe0dZ62SNvsHO5oJgE6wDV0qGy9UZYS5FoAprF5QRzzADxgqmGWin+Q== +shock-common@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-3.0.0.tgz#7ff3c6ea4fc6df9e00edbcdc10315401ff97c381" + integrity sha512-lB7np3289Gedk6xv6Kpm6JE+ABjPWtOzRiOpwegWskcC/cS/CriO4LH0JYrTl312yD7p91sDFVQTs9d40CRIKQ== dependencies: + immer "^6.0.6" lodash "^4.17.15" normalizr "^3.6.0" + redux "^4.0.5" + redux-thunk "^2.3.0" + uuid "3.x.x" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" @@ -6302,6 +6324,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +symbol-observable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -6672,6 +6699,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid@3.x.x: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + uuid@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" From 0b3f7a81413db84c64e8f8e8798a7eebb8e186bc Mon Sep 17 00:00:00 2001 From: boufni95 Date: Mon, 25 May 2020 17:47:30 +0200 Subject: [PATCH 006/124] gun err --- src/routes.js | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/src/routes.js b/src/routes.js index 594f226e..1f835db5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -433,6 +433,70 @@ module.exports = async ( GunActions.saveChannelsBackup(JSON.stringify(channelBackups),user,SEA) }); + /* + const feedObj = { + feed: [ + { + id:'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', + paragraphs:[ + "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', + }, + ] + } + ] + }*/ + 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 = () => { @@ -1614,11 +1678,10 @@ module.exports = async ( res.json(channelBackups); }); }); - + const {timeout5} = require('../services/gunDB/contact-api/utils') const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') - const { timeout5 } = require('../services/gunDB/contact-api/utils') - + app.get("/api/gun/lndchanbackups", async (req,res) => { try{ const user = require('../services/gunDB/Mediator').getUser() @@ -1633,9 +1696,21 @@ module.exports = async ( res.json({ok:"err"}) } }) + app.get("api/gun/feedpoc", async (req,res) =>{ + try{ + logger.warn("FEED POC") + const user = require('../services/gunDB/Mediator').getUser() + const feedObj = await timeout5(user.get("FEED_POC").then()) + logger.warn(feedObj) + + res.json({data:"feedObj"}) + } catch (err) { + //res.json({ok:"err"}) + } + }) const Events = require('../services/gunDB/contact-api/events') - + app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { try { // spinup From c75e0902f8829b52faed4bc308de869ed4031f43 Mon Sep 17 00:00:00 2001 From: boufni95 Date: Mon, 25 May 2020 18:38:43 +0200 Subject: [PATCH 007/124] redux ok gun ok --- src/routes.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/routes.js b/src/routes.js index 1f835db5..cba84101 100644 --- a/src/routes.js +++ b/src/routes.js @@ -433,13 +433,13 @@ module.exports = async ( GunActions.saveChannelsBackup(JSON.stringify(channelBackups),user,SEA) }); - /* + const feedObj = { feed: [ { id:'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', paragraphs:[ - "SOme text and stuff" + "SOme text and stuff 12" ], profilePic:"", username:"bobni", @@ -485,11 +485,8 @@ module.exports = async ( ] } ] - }*/ - const feedObj = { - feed :{} } - user.get("FEED_POC").put(feedObj, ack => { + user.get("FEED_POC").put(JSON.stringify(feedObj), ack => { if (ack.err) { //rej(ack.err) logger.log(ack.err) @@ -1696,14 +1693,14 @@ module.exports = async ( res.json({ok:"err"}) } }) - app.get("api/gun/feedpoc", async (req,res) =>{ + app.get("/api/gun/feedpoc", async (req,res) =>{ try{ logger.warn("FEED POC") const user = require('../services/gunDB/Mediator').getUser() const feedObj = await timeout5(user.get("FEED_POC").then()) logger.warn(feedObj) - res.json({data:"feedObj"}) + res.json({data:feedObj}) } catch (err) { //res.json({ok:"err"}) } From f1e5f3d04a0c18655ee6ceaa0f47113e39886513 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 16:26:57 -0400 Subject: [PATCH 008/124] move import to top --- src/routes.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/routes.js b/src/routes.js index cba84101..cda2e7e3 100644 --- a/src/routes.js +++ b/src/routes.js @@ -33,6 +33,8 @@ module.exports = async ( mySocketsEvents, { serverPort, CA, CA_KEY, usetls } ) => { + const {timeout5} = require('../services/gunDB/contact-api/utils') + const Http = Axios.create({ httpsAgent: new httpsAgent.Agent({ ca: await FS.readFile(CA) @@ -1675,7 +1677,6 @@ module.exports = async ( res.json(channelBackups); }); }); - const {timeout5} = require('../services/gunDB/contact-api/utils') const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') @@ -1707,7 +1708,7 @@ module.exports = async ( }) const Events = require('../services/gunDB/contact-api/events') - + app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { try { // spinup From 254925b0e28e20e0eed9152e566217ba02fd0db5 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 18:52:51 -0400 Subject: [PATCH 009/124] upgrade shock-common --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6221484f..82894a49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5877,9 +5877,9 @@ shellwords@^0.1.1: integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== shock-common@0.x.x: - version "0.2.0" - resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.2.0.tgz#b942d4b8730890aaf192eb873957c235333eddca" - integrity sha512-K9UysxR4LnArhljK3kRNdRM2yeI52YxPe0dZ62SNvsHO5oJgE6wDV0qGy9UZYS5FoAprF5QRzzADxgqmGWin+Q== + version "0.3.0" + resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.3.0.tgz#2e8a9c2cd1eda300a8461ea9648d250237f22f78" + integrity sha512-K0xOKkrOAvD4rlWVQD5WXASiKyfatEX2cj114LC8Wddi3wXpex5yLNdWBXNGFpL6Vc5Wzhza/sEHs4p+Q3xBmw== dependencies: lodash "^4.17.15" normalizr "^3.6.0" From 6e7497eb3973edaedd22514eda69c5c46d3c58b7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 18:55:12 -0400 Subject: [PATCH 010/124] don't lint typescript --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 52b8992c..a1b337c1 100644 --- a/package.json +++ b/package.json @@ -78,9 +78,12 @@ "typescript": "^3.6.3" }, "lint-staged": { - "*.{js,ts}": [ + "*.js": [ "prettier --check", "eslint" + ], + "*.ts": [ + "prettier --check" ] }, "husky": { From 36ca9b438fc42f67382e809c8ffe0a71de6f5154 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 18:55:40 -0400 Subject: [PATCH 011/124] gun.load() typings --- services/gunDB/contact-api/SimpleGUN.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/gunDB/contact-api/SimpleGUN.ts b/services/gunDB/contact-api/SimpleGUN.ts index 25f9e8ba..0929b854 100644 --- a/services/gunDB/contact-api/SimpleGUN.ts +++ b/services/gunDB/contact-api/SimpleGUN.ts @@ -38,6 +38,9 @@ export interface Soul { export type OpenListenerData = Primitive | null | OpenListenerDataObj export type OpenListener = (data: OpenListenerData, key: string) => void +export type LoadListenerData = OpenListenerData +export type LoadListener = (data: LoadListenerData, key: string) => void + export interface GUNNodeBase { _: Soul @@ -48,6 +51,8 @@ export interface GUNNodeBase { open(this: GUNNode, cb?: OpenListener): GUNNode + load(this: GUNNode, cb?: LoadListener): GUNNode + off(): void user(): UserGUNNode user(epub: string): GUNNode From 2d0619b3c57cf4bfc7df5ff6913e2af285bdb05f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 18:56:35 -0400 Subject: [PATCH 012/124] follows key --- services/gunDB/contact-api/key.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/gunDB/contact-api/key.js b/services/gunDB/contact-api/key.js index be14b788..837f38e9 100644 --- a/services/gunDB/contact-api/key.js +++ b/services/gunDB/contact-api/key.js @@ -42,3 +42,5 @@ exports.CHANNELS_BACKUP = 'channelsBackup' exports.LAST_SEEN_APP = 'lastSeenApp' exports.LAST_SEEN_NODE = 'lastSeenNode' + +exports.FOLLOWS = 'follows' From 424f199b4efd9b4d7b0ea10e1822b6dc4d649166 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 18:57:24 -0400 Subject: [PATCH 013/124] follows endpoints --- src/routes.js | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/routes.js b/src/routes.js index cda2e7e3..d2e3621b 100644 --- a/src/routes.js +++ b/src/routes.js @@ -12,6 +12,7 @@ const httpsAgent = require("https"); const responseTime = require("response-time"); const uuid = require("uuid/v4"); const Common = require('shock-common') +const fromPairs = require('lodash/fromPairs') const getListPage = require("../utils/paginate"); @@ -1830,6 +1831,110 @@ module.exports = async ( } }) + ///////////////////////////////// + + /** + * @typedef {import('express-serve-static-core').Application} Application + * @typedef {import('express-serve-static-core').Response} Response + * @typedef {import('shock-common').APISchema.FollowRequest} FollowRequest + * @typedef {import('shock-common').APISchema.UnfollowRequest} UnfollowRequest + * @typedef {import('shock-common').APISchema.GetFollowsResponse} GetFollowsResponse + * @typedef {import('shock-common').Schema.Follow} Follow + */ + + const ap = /** @type {Application} */ (app); + + /** + * @param {*} _ + * @param {Response} res + */ + const apiGunFollowsGet = async (_, res) => { + try { + const user = require('../services/gunDB/Mediator').getUser(); + + /** + * @type {import('../services/gunDB/contact-api/SimpleGUN').OpenListenerData} + */ + const followsData = await timeout5(new Promise(res => { + user.get(Key.FOLLOWS).load(data => { + res(data) + }) + })) + + /** + * @type {GetFollowsResponse} + */ + const response = { + follows: {} + } + + if (Common.Schema.isObj(followsData)) { + response.follows = fromPairs( + Object.entries(followsData) + .filter(([_, f]) => Common.Schema.isFollow(f)) + ) + } else { + logger.warn('followsData not a map, expected for old users'); + } + + return res.status(200).json(response) + } catch (err) { + return res.json(500).json({ + errorMessage: err.message + }) + } + } + + + /** + * @param {{ body: FollowRequest }} req + * @param {Response} res + */ + const apiGunFollowsPost = (req, res) => { + try { + const user = require('../services/gunDB/Mediator').getUser() + const { body: { publicKey }} = req + + /** @type {Follow} */ + const newFollow = { + private: false, + status: 'ok', + user: publicKey + } + + user.get(Key.FOLLOWS).get(publicKey).put(newFollow) + + return res.status(200) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message || 'Unknown error inside /api/gun/follow' + }) + } + } + + /** + * @param {{ body: UnfollowRequest }} req + * @param {Response} res + */ + const apiGunFollowsDelete = (req, res) => { + try { + const user = require('../services/gunDB/Mediator').getUser() + const { body: { publicKey }} = req + + user.get(Key.FOLLOWS).get(publicKey).put(null) + + return res.status(200) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message || 'Unknown error inside /api/gun/follow' + }) + } + } + + ap.get('api/gun/follows', apiGunFollowsGet) + ap.post(`/api/gun/follows`, apiGunFollowsPost) + ap.delete(`api/gun/follows`, apiGunFollowsDelete) + /** * Return app so that it can be used by express. */ From 11c5337e0fe175b4ae7e1dc48ea340cef48068e9 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 19:29:54 -0400 Subject: [PATCH 014/124] use route params for follows delete --- src/routes.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index d2e3621b..aa6f34dd 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1916,10 +1916,13 @@ module.exports = async ( * @param {{ body: UnfollowRequest }} req * @param {Response} res */ - const apiGunFollowsDelete = (req, res) => { + const apiGunFollowsDelete = (req, res) => { try { const user = require('../services/gunDB/Mediator').getUser() - const { body: { publicKey }} = req + /** + * @type {string} + */ + const publicKey = req.params.publickey user.get(Key.FOLLOWS).get(publicKey).put(null) @@ -1933,7 +1936,7 @@ module.exports = async ( ap.get('api/gun/follows', apiGunFollowsGet) ap.post(`/api/gun/follows`, apiGunFollowsPost) - ap.delete(`api/gun/follows`, apiGunFollowsDelete) + ap.delete(`api/gun/follows/:publickey`, apiGunFollowsDelete) /** * Return app so that it can be used by express. From e402ea3a946049819c107c10895719562c6f6982 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 22:10:11 -0400 Subject: [PATCH 015/124] remove dup identifier --- src/routes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes.js b/src/routes.js index aa6f34dd..f0708ac5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1678,6 +1678,7 @@ module.exports = async ( res.json(channelBackups); }); }); + const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') From 6ba6d70a5f811a953e2db2f6ee8b7e40162bad97 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 22:40:48 -0400 Subject: [PATCH 016/124] test code --- src/routes.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index f0708ac5..48327ed3 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1891,7 +1891,7 @@ module.exports = async ( * @param {{ body: FollowRequest }} req * @param {Response} res */ - const apiGunFollowsPost = (req, res) => { + const apiGunFollowsPost = async (req, res) => { try { const user = require('../services/gunDB/Mediator').getUser() const { body: { publicKey }} = req @@ -1903,9 +1903,24 @@ module.exports = async ( user: publicKey } - user.get(Key.FOLLOWS).get(publicKey).put(newFollow) + console.log('NEWFOLLOW WILL POST ' + publicKey) - return res.status(200) + await new Promise((res, rej) => { + user.get(Key.FOLLOWS).get(publicKey).put(newFollow, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + + + console.log('NEWFOLLOW POSTED') + // eslint-disable-next-line no-process-exit + process.exit(1) + + return res.status(200).send() } catch (err) { return res.status(500).json({ errorMessage: err.message || 'Unknown error inside /api/gun/follow' From ea51bef3adfef06edc55605d700db9533e966c05 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 22:46:23 -0400 Subject: [PATCH 017/124] more tst code --- src/routes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes.js b/src/routes.js index 48327ed3..4fc4c494 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1892,6 +1892,7 @@ module.exports = async ( * @param {Response} res */ const apiGunFollowsPost = async (req, res) => { + process.exit(1) try { const user = require('../services/gunDB/Mediator').getUser() const { body: { publicKey }} = req From 0bfd082658f5fc78524cf4c8188af739af9f5759 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 30 May 2020 22:57:38 -0400 Subject: [PATCH 018/124] follows -> follow --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 4fc4c494..95edb09f 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1952,7 +1952,7 @@ module.exports = async ( } ap.get('api/gun/follows', apiGunFollowsGet) - ap.post(`/api/gun/follows`, apiGunFollowsPost) + ap.post(`/api/gun/follow`, apiGunFollowsPost) ap.delete(`api/gun/follows/:publickey`, apiGunFollowsDelete) /** From 720732ba98ea7e9bb0564670e0dab9f3f779b932 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 31 May 2020 10:16:38 -0400 Subject: [PATCH 019/124] add leading dash --- src/routes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes.js b/src/routes.js index 95edb09f..54f428b0 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1951,9 +1951,9 @@ module.exports = async ( } } - ap.get('api/gun/follows', apiGunFollowsGet) + ap.get('/api/gun/follows', apiGunFollowsGet) ap.post(`/api/gun/follow`, apiGunFollowsPost) - ap.delete(`api/gun/follows/:publickey`, apiGunFollowsDelete) + ap.delete(`/api/gun/follows/:publickey`, apiGunFollowsDelete) /** * Return app so that it can be used by express. From 80bb635b7278a93ac268269d8ea12ace6788e3e4 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 31 May 2020 11:03:04 -0400 Subject: [PATCH 020/124] typo --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 54f428b0..e1dfb9b2 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1880,7 +1880,7 @@ module.exports = async ( return res.status(200).json(response) } catch (err) { - return res.json(500).json({ + return res.status(500).json({ errorMessage: err.message }) } From 56f04605092f79bc1251323440b0640cd6750379 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 31 May 2020 11:03:30 -0400 Subject: [PATCH 021/124] remove debug code --- src/routes.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index e1dfb9b2..6df95e30 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1892,7 +1892,6 @@ module.exports = async ( * @param {Response} res */ const apiGunFollowsPost = async (req, res) => { - process.exit(1) try { const user = require('../services/gunDB/Mediator').getUser() const { body: { publicKey }} = req @@ -1918,8 +1917,6 @@ module.exports = async ( console.log('NEWFOLLOW POSTED') - // eslint-disable-next-line no-process-exit - process.exit(1) return res.status(200).send() } catch (err) { From f731474dcef9e4d33ab565c28da8d2cd8f816095 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 31 May 2020 12:02:00 -0400 Subject: [PATCH 022/124] catch the error --- src/routes.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 6df95e30..c6a23875 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1918,8 +1918,10 @@ module.exports = async ( console.log('NEWFOLLOW POSTED') - return res.status(200).send() + return res.status(200) } catch (err) { + console.log(err) + process.exit(1) return res.status(500).json({ errorMessage: err.message || 'Unknown error inside /api/gun/follow' }) From 08216586eda400ae47c6b19a1a9d3a0b22fd298e Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 31 May 2020 12:16:45 -0400 Subject: [PATCH 023/124] remove debug code --- src/routes.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/routes.js b/src/routes.js index c6a23875..0205f35e 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1920,8 +1920,6 @@ module.exports = async ( return res.status(200) } catch (err) { - console.log(err) - process.exit(1) return res.status(500).json({ errorMessage: err.message || 'Unknown error inside /api/gun/follow' }) From 6f87d214ecc9ea5a8374105163e0fb00b6b67717 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 31 May 2020 12:17:22 -0400 Subject: [PATCH 024/124] correct wording --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 0205f35e..f2616535 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1949,7 +1949,7 @@ module.exports = async ( } ap.get('/api/gun/follows', apiGunFollowsGet) - ap.post(`/api/gun/follow`, apiGunFollowsPost) + ap.post(`/api/gun/follows`, apiGunFollowsPost) ap.delete(`/api/gun/follows/:publickey`, apiGunFollowsDelete) /** From e46e79405d933a4bd3f23e0ca07ca657c6e195a6 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 2 Jun 2020 09:42:44 -0400 Subject: [PATCH 025/124] format --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index f2616535..c20dbbec 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1862,7 +1862,7 @@ module.exports = async ( }) })) - /** + /** * @type {GetFollowsResponse} */ const response = { From dba537e9b02eda87b7ae829c4f8766bf4f060468 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 2 Jun 2020 13:06:18 -0400 Subject: [PATCH 026/124] format --- services/gunDB/contact-api/getters.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/services/gunDB/contact-api/getters.js b/services/gunDB/contact-api/getters.js index cc1104f7..ed6d4541 100644 --- a/services/gunDB/contact-api/getters.js +++ b/services/gunDB/contact-api/getters.js @@ -1,3 +1,6 @@ +/** + * @format + */ const Key = require('./key') const Utils = require('./utils') @@ -5,8 +8,13 @@ const Utils = require('./utils') * @param {string} pub * @returns {Promise} */ -exports.currentOrderAddress = async (pub) => { - const currAddr = await Utils.tryAndWait((gun) => gun.user(pub).get(Key.CURRENT_ORDER_ADDRESS).then()) +exports.currentOrderAddress = async pub => { + const currAddr = await Utils.tryAndWait(gun => + gun + .user(pub) + .get(Key.CURRENT_ORDER_ADDRESS) + .then() + ) if (typeof currAddr !== 'string') { throw new TypeError('Expected user.currentOrderAddress to be an string') @@ -19,11 +27,14 @@ exports.currentOrderAddress = async (pub) => { * @param {string} pub * @returns {Promise} */ -exports.userToIncomingID = async (pub) => { - const incomingID = await require('../Mediator').getUser().get(Key.USER_TO_INCOMING).get(pub).then() +exports.userToIncomingID = async pub => { + const incomingID = await require('../Mediator') + .getUser() + .get(Key.USER_TO_INCOMING) + .get(pub) + .then() if (typeof incomingID === 'string') return incomingID return null - -} \ No newline at end of file +} From 154f9e3a10ef7b47b5f9736158da4c2730ea2a0f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 3 Jun 2020 10:19:05 -0400 Subject: [PATCH 027/124] follows getter --- services/gunDB/contact-api/getters.js | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/services/gunDB/contact-api/getters.js b/services/gunDB/contact-api/getters.js index ed6d4541..d71e53f4 100644 --- a/services/gunDB/contact-api/getters.js +++ b/services/gunDB/contact-api/getters.js @@ -1,6 +1,12 @@ /** * @format */ +const Common = require('shock-common') +/** + * @typedef {import('shock-common').Schema.Follow} Follow + */ +const Logger = require('winston') + const Key = require('./key') const Utils = require('./utils') @@ -38,3 +44,45 @@ exports.userToIncomingID = async pub => { return null } + +/** + * @returns {Promise>} + */ +exports.currentFollows = () => { + const user = require('../Mediator').getUser() + + return new Promise(res => { + user.get(Key.FOLLOWS).load(data => { + if (typeof data !== 'object' || data === null) { + Logger.warn( + `GunDb -> getters -> currentFollows() -> Current follows data as fetched from gun is not an object but ${typeof data}. This can happen if Gun lost its cache and it's still retrieving data from the network.` + ) + res({}) + return + } + + const rejected = Object.entries(data).filter( + ([_, follow]) => !Common.Schema.isFollow(follow) + ) + + rejected.forEach(([key, item]) => { + // expected when unfollowed + if (item !== null) { + Logger.warn( + `GunDb -> getters -> currentFollows() -> Item not conforming to schema found inside follows data. Key: ${key}, item: ${JSON.stringify( + item + )}.` + ) + } + }) + + const passed = Object.entries(data).filter(([_, follow]) => + Common.Schema.isFollow(follow) + ) + + const p = /** @type {unknown} */ (passed) + + res(/** @type {Record} */ (p)) + }) + }) +} From 924d2ce25e4e89386b1fe52cff696f371572e43f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 3 Jun 2020 10:30:38 -0400 Subject: [PATCH 028/124] follows-related actions --- services/gunDB/contact-api/actions.js | 52 ++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index b4fe5bed..6522e6fa 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1218,6 +1218,54 @@ const setLastSeenApp = () => }) }) +/** + * @param {string} publicKey + * @param {boolean} isPrivate + * @returns {Promise} + */ +const follow = (publicKey, isPrivate = false) => { + /** @type {import('shock-common').Schema.Follow} */ + const newFollow = { + private: isPrivate, + status: 'ok', + user: publicKey + } + + return new Promise((res, rej) => { + require('../Mediator') + .getUser() + .get(Key.FOLLOWS) + .get(publicKey) + // @ts-ignore + .put(newFollow, ack => { + if (ack.err) { + rej(ack.err) + } else { + res() + } + }) + }) +} + +/** + * @param {string} publicKey + * @returns {Promise} + */ +const unfollow = publicKey => + new Promise((res, rej) => { + require('../Mediator') + .getUser() + .get(Key.FOLLOWS) + .get(publicKey) + .put(null, ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + module.exports = { __createOutgoingFeed, acceptRequest, @@ -1236,5 +1284,7 @@ module.exports = { saveSeedBackup, saveChannelsBackup, disconnect, - setLastSeenApp + setLastSeenApp, + follow, + unfollow } From c7acbbdfb1f441f5494d5b2d92d6fb53bcc5f2c7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 3 Jun 2020 10:40:09 -0400 Subject: [PATCH 029/124] follows-related-routes --- src/routes.js | 113 +++++++++++++++++--------------------------------- 1 file changed, 38 insertions(+), 75 deletions(-) diff --git a/src/routes.js b/src/routes.js index c20dbbec..c9e00672 100644 --- a/src/routes.js +++ b/src/routes.js @@ -12,8 +12,6 @@ const httpsAgent = require("https"); const responseTime = require("response-time"); const uuid = require("uuid/v4"); const Common = require('shock-common') -const fromPairs = require('lodash/fromPairs') - const getListPage = require("../utils/paginate"); const auth = require("../services/auth/auth"); @@ -23,6 +21,7 @@ const LightningServices = require("../utils/lightningServices"); 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 DEFAULT_MAX_NUM_ROUTES_TO_QUERY = 10; const SESSION_ID = uuid(); @@ -1833,10 +1832,13 @@ module.exports = async ( }) ///////////////////////////////// + /** + * @template P + * @typedef {import('express-serve-static-core').RequestHandler

} RequestHandler + */ /** - * @typedef {import('express-serve-static-core').Application} Application - * @typedef {import('express-serve-static-core').Response} Response + * * @typedef {import('shock-common').APISchema.FollowRequest} FollowRequest * @typedef {import('shock-common').APISchema.UnfollowRequest} UnfollowRequest * @typedef {import('shock-common').APISchema.GetFollowsResponse} GetFollowsResponse @@ -1846,111 +1848,72 @@ module.exports = async ( const ap = /** @type {Application} */ (app); /** - * @param {*} _ - * @param {Response} res + * @typedef {object} FollowsRouteParams + * @prop {(string|undefined)=} publicKey */ - const apiGunFollowsGet = async (_, res) => { + + + /** + * @type {RequestHandler} + */ + const apiGunFollowsGet = async (req, res) => { try { - const user = require('../services/gunDB/Mediator').getUser(); + const { publicKey } = req.params; + const currFollows = await GunGetters.currentFollows() - /** - * @type {import('../services/gunDB/contact-api/SimpleGUN').OpenListenerData} - */ - const followsData = await timeout5(new Promise(res => { - user.get(Key.FOLLOWS).load(data => { - res(data) - }) - })) - - /** - * @type {GetFollowsResponse} - */ - const response = { - follows: {} - } - - if (Common.Schema.isObj(followsData)) { - response.follows = fromPairs( - Object.entries(followsData) - .filter(([_, f]) => Common.Schema.isFollow(f)) - ) - } else { - logger.warn('followsData not a map, expected for old users'); - } - - return res.status(200).json(response) + return res.status(200).json(publicKey ? currFollows[publicKey] : currFollows) } catch (err) { return res.status(500).json({ - errorMessage: err.message + errorMessage: err.message || 'Unknown ERR at GET /api/follows' }) } } /** - * @param {{ body: FollowRequest }} req - * @param {Response} res + * @type {RequestHandler} */ - const apiGunFollowsPost = async (req, res) => { + const apiGunFollowsPostOrPut = async (req, res) => { try { - const user = require('../services/gunDB/Mediator').getUser() - const { body: { publicKey }} = req - - /** @type {Follow} */ - const newFollow = { - private: false, - status: 'ok', - user: publicKey + const { publicKey } = req.params; + if (!publicKey) { + throw new Error(`Missing publicKey route param.`) } - console.log('NEWFOLLOW WILL POST ' + publicKey) - - await new Promise((res, rej) => { - user.get(Key.FOLLOWS).get(publicKey).put(newFollow, ack => { - if (ack.err) { - rej(new Error(ack.err)) - } else { - res() - } - }) - }) - - - console.log('NEWFOLLOW POSTED') + await GunActions.follow(req.params.publicKey, req.body.private) + // 201 would be extraneous here return res.status(200) } catch (err) { return res.status(500).json({ - errorMessage: err.message || 'Unknown error inside /api/gun/follow' + errorMessage: err.message || 'Unknown error inside /api/gun/follows/' }) } } /** - * @param {{ body: UnfollowRequest }} req - * @param {Response} res + * @type {RequestHandler} */ - const apiGunFollowsDelete = (req, res) => { + const apiGunFollowsDelete = async (req, res) => { try { - const user = require('../services/gunDB/Mediator').getUser() - /** - * @type {string} - */ - const publicKey = req.params.publickey - - user.get(Key.FOLLOWS).get(publicKey).put(null) + const { publicKey } = req.params; + if (!publicKey) { + throw new Error(`Missing publicKey route param.`) + } + await GunActions.unfollow(req.params.publicKey) return res.status(200) } catch (err) { return res.status(500).json({ - errorMessage: err.message || 'Unknown error inside /api/gun/follow' + errorMessage: err.message || 'Unknown error inside /api/gun/follows/' }) } } - ap.get('/api/gun/follows', apiGunFollowsGet) - ap.post(`/api/gun/follows`, apiGunFollowsPost) - ap.delete(`/api/gun/follows/:publickey`, apiGunFollowsDelete) + ap.get('/api/gun/follows/:publicKey', apiGunFollowsGet) + ap.post(`/api/gun/follows/:publicKey`, apiGunFollowsPostOrPut) + ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPostOrPut) + ap.delete(`/api/gun/follows/:publicKey`, apiGunFollowsDelete) /** * Return app so that it can be used by express. From f70fc2a0abd51fb80e05b53534e676b6d860ab76 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 3 Jun 2020 14:49:11 -0400 Subject: [PATCH 030/124] ensure boolean arg --- src/routes.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/routes.js b/src/routes.js index c9e00672..a9251e51 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1837,13 +1837,6 @@ module.exports = async ( * @typedef {import('express-serve-static-core').RequestHandler

} RequestHandler */ - /** - * - * @typedef {import('shock-common').APISchema.FollowRequest} FollowRequest - * @typedef {import('shock-common').APISchema.UnfollowRequest} UnfollowRequest - * @typedef {import('shock-common').APISchema.GetFollowsResponse} GetFollowsResponse - * @typedef {import('shock-common').Schema.Follow} Follow - */ const ap = /** @type {Application} */ (app); @@ -1880,7 +1873,7 @@ module.exports = async ( throw new Error(`Missing publicKey route param.`) } - await GunActions.follow(req.params.publicKey, req.body.private) + await GunActions.follow(req.params.publicKey, req.body.private || false) // 201 would be extraneous here return res.status(200) From 6e6cb9b479462b8ee9a64f219c808446f43420af Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 3 Jun 2020 15:54:51 -0400 Subject: [PATCH 031/124] explicitness --- services/gunDB/contact-api/actions.js | 2 +- src/routes.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 6522e6fa..e13d8989 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1223,7 +1223,7 @@ const setLastSeenApp = () => * @param {boolean} isPrivate * @returns {Promise} */ -const follow = (publicKey, isPrivate = false) => { +const follow = (publicKey, isPrivate) => { /** @type {import('shock-common').Schema.Follow} */ const newFollow = { private: isPrivate, diff --git a/src/routes.js b/src/routes.js index a9251e51..3a041d8e 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1873,7 +1873,7 @@ module.exports = async ( throw new Error(`Missing publicKey route param.`) } - await GunActions.follow(req.params.publicKey, req.body.private || false) + await GunActions.follow(req.params.publicKey, false) // 201 would be extraneous here return res.status(200) From f375ada0c526887a162610aae29bd03f016020b2 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 4 Jun 2020 09:33:56 -0400 Subject: [PATCH 032/124] getters as a module --- .../gunDB/contact-api/{getters.js => getters/index.js} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename services/gunDB/contact-api/{getters.js => getters/index.js} (92%) diff --git a/services/gunDB/contact-api/getters.js b/services/gunDB/contact-api/getters/index.js similarity index 92% rename from services/gunDB/contact-api/getters.js rename to services/gunDB/contact-api/getters/index.js index d71e53f4..fa724cbc 100644 --- a/services/gunDB/contact-api/getters.js +++ b/services/gunDB/contact-api/getters/index.js @@ -2,13 +2,13 @@ * @format */ const Common = require('shock-common') +const Logger = require('winston') /** * @typedef {import('shock-common').Schema.Follow} Follow */ -const Logger = require('winston') -const Key = require('./key') -const Utils = require('./utils') +const Key = require('../key') +const Utils = require('../utils') /** * @param {string} pub @@ -34,7 +34,7 @@ exports.currentOrderAddress = async pub => { * @returns {Promise} */ exports.userToIncomingID = async pub => { - const incomingID = await require('../Mediator') + const incomingID = await require('../../Mediator') .getUser() .get(Key.USER_TO_INCOMING) .get(pub) @@ -49,7 +49,7 @@ exports.userToIncomingID = async pub => { * @returns {Promise>} */ exports.currentFollows = () => { - const user = require('../Mediator').getUser() + const user = require('../../Mediator').getUser() return new Promise(res => { user.get(Key.FOLLOWS).load(data => { From 47b2a4f01049a1bc23d2e14b4241725c436541ec Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 4 Jun 2020 10:27:13 -0400 Subject: [PATCH 033/124] follows as submodule --- services/gunDB/contact-api/getters/follows.js | 50 +++++++++++++++++++ services/gunDB/contact-api/getters/index.js | 48 +----------------- 2 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 services/gunDB/contact-api/getters/follows.js diff --git a/services/gunDB/contact-api/getters/follows.js b/services/gunDB/contact-api/getters/follows.js new file mode 100644 index 00000000..b74080fa --- /dev/null +++ b/services/gunDB/contact-api/getters/follows.js @@ -0,0 +1,50 @@ +const Common = require('shock-common') +const Logger = require('winston') + +const Key = require('../key') + +/** + * @typedef {Common.Schema.Follow} Follow + */ + +/** + * @returns {Promise>} + */ +exports.currentFollows = () => { + const user = require('../../Mediator').getUser() + + return new Promise(res => { + user.get(Key.FOLLOWS).load(data => { + if (typeof data !== 'object' || data === null) { + Logger.warn( + `GunDb -> getters -> currentFollows() -> Current follows data as fetched from gun is not an object but ${typeof data}. This can happen if Gun lost its cache and it's still retrieving data from the network.` + ) + res({}) + return + } + + const rejected = Object.entries(data).filter( + ([_, follow]) => !Common.Schema.isFollow(follow) + ) + + rejected.forEach(([key, item]) => { + // expected when unfollowed + if (item !== null) { + Logger.warn( + `GunDb -> getters -> currentFollows() -> Item not conforming to schema found inside follows data. Key: ${key}, item: ${JSON.stringify( + item + )}.` + ) + } + }) + + const passed = Object.entries(data).filter(([_, follow]) => + Common.Schema.isFollow(follow) + ) + + const p = /** @type {unknown} */ (passed) + + res(/** @type {Record} */ (p)) + }) + }) +} \ No newline at end of file diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index fa724cbc..9b33cb92 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -1,12 +1,6 @@ /** * @format */ -const Common = require('shock-common') -const Logger = require('winston') -/** - * @typedef {import('shock-common').Schema.Follow} Follow - */ - const Key = require('../key') const Utils = require('../utils') @@ -45,44 +39,4 @@ exports.userToIncomingID = async pub => { return null } -/** - * @returns {Promise>} - */ -exports.currentFollows = () => { - const user = require('../../Mediator').getUser() - - return new Promise(res => { - user.get(Key.FOLLOWS).load(data => { - if (typeof data !== 'object' || data === null) { - Logger.warn( - `GunDb -> getters -> currentFollows() -> Current follows data as fetched from gun is not an object but ${typeof data}. This can happen if Gun lost its cache and it's still retrieving data from the network.` - ) - res({}) - return - } - - const rejected = Object.entries(data).filter( - ([_, follow]) => !Common.Schema.isFollow(follow) - ) - - rejected.forEach(([key, item]) => { - // expected when unfollowed - if (item !== null) { - Logger.warn( - `GunDb -> getters -> currentFollows() -> Item not conforming to schema found inside follows data. Key: ${key}, item: ${JSON.stringify( - item - )}.` - ) - } - }) - - const passed = Object.entries(data).filter(([_, follow]) => - Common.Schema.isFollow(follow) - ) - - const p = /** @type {unknown} */ (passed) - - res(/** @type {Record} */ (p)) - }) - }) -} +module.exports.Follows = require('./follows') From e648ad0cfafd13466bed699a7fe081fec4fbe168 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 10:58:01 -0400 Subject: [PATCH 034/124] comment --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 3a041d8e..d50c828c 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1875,7 +1875,7 @@ module.exports = async ( await GunActions.follow(req.params.publicKey, false) - // 201 would be extraneous here + // 201 would be extraneous here. Implement it inside app.put return res.status(200) } catch (err) { return res.status(500).json({ From e152c2ff0db70fbcfaf97fb0705d2366376e6590 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 11:04:23 -0400 Subject: [PATCH 035/124] actually send res --- src/routes.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/routes.js b/src/routes.js index d50c828c..56dfb573 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1876,7 +1876,9 @@ module.exports = async ( await GunActions.follow(req.params.publicKey, false) // 201 would be extraneous here. Implement it inside app.put - return res.status(200) + return res.status(200).json({ + ok: true + }) } catch (err) { return res.status(500).json({ errorMessage: err.message || 'Unknown error inside /api/gun/follows/' @@ -1895,7 +1897,9 @@ module.exports = async ( } await GunActions.unfollow(req.params.publicKey) - return res.status(200) + return res.status(200).json({ + ok: true + }) } catch (err) { return res.status(500).json({ errorMessage: err.message || 'Unknown error inside /api/gun/follows/' From e6740d4c0049eb190e0aacd9265c36ca35bde7a7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 11:34:46 -0400 Subject: [PATCH 036/124] reject with error --- services/gunDB/contact-api/actions.js | 6 +++--- src/routes.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index e13d8989..36b39716 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1156,7 +1156,7 @@ const saveSeedBackup = async (mnemonicPhrase, user, SEA) => { return new Promise((res, rej) => { user.get(Key.SEED_BACKUP).put(encryptedSeed, ack => { if (ack.err) { - rej(ack.err) + rej(new Error(ack.err)) } else { res() } @@ -1179,7 +1179,7 @@ const saveChannelsBackup = async (backups, user, SEA) => { return new Promise((res, rej) => { user.get(Key.CHANNELS_BACKUP).put(encryptBackups, ack => { if (ack.err) { - rej(ack.err) + rej(new Error(ack.err)) } else { res() } @@ -1239,7 +1239,7 @@ const follow = (publicKey, isPrivate) => { // @ts-ignore .put(newFollow, ack => { if (ack.err) { - rej(ack.err) + rej(new Error(ack.err)) } else { res() } diff --git a/src/routes.js b/src/routes.js index 56dfb573..960c1641 100644 --- a/src/routes.js +++ b/src/routes.js @@ -490,7 +490,7 @@ module.exports = async ( } user.get("FEED_POC").put(JSON.stringify(feedObj), ack => { if (ack.err) { - //rej(ack.err) + //rej(new Error(ack.err)) logger.log(ack.err) } else { logger.log(ack.err) From 668a9da9a9e3e420d217c2e15afc81e16da4d6ad Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 11:47:43 -0400 Subject: [PATCH 037/124] sanitize public key --- services/gunDB/contact-api/actions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 36b39716..455792cf 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1235,7 +1235,7 @@ const follow = (publicKey, isPrivate) => { require('../Mediator') .getUser() .get(Key.FOLLOWS) - .get(publicKey) + .get(`$$__PK__${publicKey}`) // @ts-ignore .put(newFollow, ack => { if (ack.err) { @@ -1256,7 +1256,7 @@ const unfollow = publicKey => require('../Mediator') .getUser() .get(Key.FOLLOWS) - .get(publicKey) + .get(`$$__PK__${publicKey}`) .put(null, ack => { if (ack.err) { rej(new Error(ack.err)) From e6fd66a8c34b13cb7adcbe87c551bcd4c8542f3d Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 13:13:08 -0400 Subject: [PATCH 038/124] comment --- services/gunDB/contact-api/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 455792cf..d8e8ef67 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1220,7 +1220,7 @@ const setLastSeenApp = () => /** * @param {string} publicKey - * @param {boolean} isPrivate + * @param {boolean} isPrivate Will overwrite previous private status. * @returns {Promise} */ const follow = (publicKey, isPrivate) => { From e1eade245252338f9d7bc05bc63941608fc9c897 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 13:13:21 -0400 Subject: [PATCH 039/124] don't sanitize public key --- services/gunDB/contact-api/actions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index d8e8ef67..54bd41fe 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1235,7 +1235,7 @@ const follow = (publicKey, isPrivate) => { require('../Mediator') .getUser() .get(Key.FOLLOWS) - .get(`$$__PK__${publicKey}`) + .get(publicKey) // @ts-ignore .put(newFollow, ack => { if (ack.err) { @@ -1256,7 +1256,7 @@ const unfollow = publicKey => require('../Mediator') .getUser() .get(Key.FOLLOWS) - .get(`$$__PK__${publicKey}`) + .get(publicKey) .put(null, ack => { if (ack.err) { rej(new Error(ack.err)) From 7d7d1f98de0d6a291dff188cfad68044faf25fe2 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 13:15:52 -0400 Subject: [PATCH 040/124] only use put --- src/routes.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index 960c1641..e3f40945 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1866,7 +1866,7 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsPostOrPut = async (req, res) => { + const apiGunFollowsPut = async (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { @@ -1908,8 +1908,7 @@ module.exports = async ( } ap.get('/api/gun/follows/:publicKey', apiGunFollowsGet) - ap.post(`/api/gun/follows/:publicKey`, apiGunFollowsPostOrPut) - ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPostOrPut) + ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPut) ap.delete(`/api/gun/follows/:publicKey`, apiGunFollowsDelete) /** From 2cc5dfd55d5fd922aa3de5672a6cfd070db268b0 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 13:17:28 -0400 Subject: [PATCH 041/124] mock response for now --- src/routes.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/routes.js b/src/routes.js index e3f40945..bf31e0ad 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1866,14 +1866,14 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsPut = async (req, res) => { + const apiGunFollowsPut = (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { throw new Error(`Missing publicKey route param.`) } - await GunActions.follow(req.params.publicKey, false) + // await GunActions.follow(req.params.publicKey, false) // 201 would be extraneous here. Implement it inside app.put return res.status(200).json({ @@ -1889,14 +1889,15 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsDelete = async (req, res) => { + const apiGunFollowsDelete = (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { throw new Error(`Missing publicKey route param.`) } - await GunActions.unfollow(req.params.publicKey) + // await GunActions.unfollow(req.params.publicKey) + return res.status(200).json({ ok: true }) From bde636264072f00ad30a1ffe60610d357e5b9bd5 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 14:25:03 -0400 Subject: [PATCH 042/124] collection get --- src/routes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes.js b/src/routes.js index bf31e0ad..8df67dd8 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1908,6 +1908,7 @@ module.exports = async ( } } + ap.get('/api/gun/follows/', apiGunFollowsGet) ap.get('/api/gun/follows/:publicKey', apiGunFollowsGet) ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPut) ap.delete(`/api/gun/follows/:publicKey`, apiGunFollowsDelete) From 779783aeec5c2da2c1f506131bd759332875d964 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 10 Jun 2020 14:25:21 -0400 Subject: [PATCH 043/124] mock endpoint --- src/routes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes.js b/src/routes.js index 8df67dd8..9dd57c6e 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1849,12 +1849,12 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsGet = async (req, res) => { + const apiGunFollowsGet = (_, res) => { try { - const { publicKey } = req.params; - const currFollows = await GunGetters.currentFollows() + // const { publicKey } = req.params; + // const currFollows = await GunGetters.currentFollows() - return res.status(200).json(publicKey ? currFollows[publicKey] : currFollows) + return res.status(200).json({}) } catch (err) { return res.status(500).json({ errorMessage: err.message || 'Unknown ERR at GET /api/follows' From 4f667cc6c1b11e7e42dbed37f75dd8cb62ca00b6 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 11:58:06 -0400 Subject: [PATCH 044/124] wall-related keys --- services/gunDB/contact-api/key.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/gunDB/contact-api/key.js b/services/gunDB/contact-api/key.js index 4e7e3115..554ddb92 100644 --- a/services/gunDB/contact-api/key.js +++ b/services/gunDB/contact-api/key.js @@ -48,3 +48,7 @@ exports.WALL = 'wall' exports.NUM_OF_PAGES = 'numOfPages' exports.PAGES = 'pages' + +exports.COUNT = 'count' + +exports.CONTENT_ITEMS = 'contentItems' From d22561d5bf77f516e10854dc62b1a72cc22a0a12 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 12:27:42 -0400 Subject: [PATCH 045/124] load() method --- services/gunDB/contact-api/SimpleGUN.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/services/gunDB/contact-api/SimpleGUN.ts b/services/gunDB/contact-api/SimpleGUN.ts index 25f9e8ba..93bb36bf 100644 --- a/services/gunDB/contact-api/SimpleGUN.ts +++ b/services/gunDB/contact-api/SimpleGUN.ts @@ -47,6 +47,7 @@ export interface GUNNodeBase { once(this: GUNNode, cb?: Listener): GUNNode open(this: GUNNode, cb?: OpenListener): GUNNode + load(this: GUNNode, cb?: OpenListener): GUNNode off(): void user(): UserGUNNode From e41d5905491e30bd524830f17e3da5da9907c193 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 12:54:18 -0400 Subject: [PATCH 046/124] upgrade shock-common --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 03efcc0c..cc13fbeb 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "request-promise": "^4.2.2", "response-time": "^2.3.2", "shelljs": "^0.8.2", - "shock-common": "3.0.0", + "shock-common": "3.1.1", "socket.io": "2.1.1", "text-encoding": "^0.7.0", "tingodb": "^0.6.1", diff --git a/yarn.lock b/yarn.lock index e0091187..74b14e07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5894,10 +5894,10 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -shock-common@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-3.0.0.tgz#7ff3c6ea4fc6df9e00edbcdc10315401ff97c381" - integrity sha512-lB7np3289Gedk6xv6Kpm6JE+ABjPWtOzRiOpwegWskcC/cS/CriO4LH0JYrTl312yD7p91sDFVQTs9d40CRIKQ== +shock-common@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-3.1.1.tgz#544af57129dc8ac0db05119b292a8d1810b1ee27" + integrity sha512-WCa9jpzkRUc7dbyGOlp+5Gl8xPSjWXINwZ6bT8cl3tGpThxXk3JgmdC/hY4FVCZVXWXRhBvPWltpTgL1iZu31Q== dependencies: immer "^6.0.6" lodash "^4.17.15" From 8c5026d887b3da4ba701114bbf3b8462585d6514 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 12:56:53 -0400 Subject: [PATCH 047/124] user getter --- services/gunDB/contact-api/getters.js | 86 +++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/services/gunDB/contact-api/getters.js b/services/gunDB/contact-api/getters.js index cc1104f7..0fcf9805 100644 --- a/services/gunDB/contact-api/getters.js +++ b/services/gunDB/contact-api/getters.js @@ -1,3 +1,9 @@ +/** + * @format + */ +const Common = require('shock-common') +const Logger = require('winston') + const Key = require('./key') const Utils = require('./utils') @@ -5,8 +11,13 @@ const Utils = require('./utils') * @param {string} pub * @returns {Promise} */ -exports.currentOrderAddress = async (pub) => { - const currAddr = await Utils.tryAndWait((gun) => gun.user(pub).get(Key.CURRENT_ORDER_ADDRESS).then()) +exports.currentOrderAddress = async pub => { + const currAddr = await Utils.tryAndWait(gun => + gun + .user(pub) + .get(Key.CURRENT_ORDER_ADDRESS) + .then() + ) if (typeof currAddr !== 'string') { throw new TypeError('Expected user.currentOrderAddress to be an string') @@ -19,11 +30,76 @@ exports.currentOrderAddress = async (pub) => { * @param {string} pub * @returns {Promise} */ -exports.userToIncomingID = async (pub) => { - const incomingID = await require('../Mediator').getUser().get(Key.USER_TO_INCOMING).get(pub).then() +exports.userToIncomingID = async pub => { + const incomingID = await require('../Mediator') + .getUser() + .get(Key.USER_TO_INCOMING) + .get(pub) + .then() if (typeof incomingID === 'string') return incomingID return null +} -} \ No newline at end of file +/** + * @param {string} publicKey + * @returns {Promise} + */ +const getUser = async publicKey => { + /** + * @type {Common.Schema.User} + */ + const user = { + avatar: null, + bio: null, + displayName: null, + lastSeenApp: 0, + lastSeenNode: 0, + publicKey + } + + /** + * @type {unknown} + */ + const profile = await Utils.tryAndWait( + gun => + new Promise(res => { + const userNode = gun.get(`~${publicKey}`) + + userNode.load(data => res(data)) + }), + v => typeof v === 'object' && v !== null + ) + + if ( + typeof profile === 'object' && + profile !== null && + Common.Schema.isUser({ + ...profile, + publicKey + }) + ) { + Object.assign(user, profile) + Logger.error( + `Invalid profile found for publicKey: ${publicKey}, found: ${JSON.stringify( + profile + )}` + ) + } + + return user +} + +exports.getUser = getUser + +exports.getMyUser = () => { + const user = require('../Mediator').getUser() + const publicKey = user.is && user.is.pub + + if (typeof publicKey !== 'string') { + throw new Error('NOT_AUTH') + } + + return getUser(publicKey) +} From cbf6e9809e2404a117037240452e151ad7bdc14d Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 12:57:58 -0400 Subject: [PATCH 048/124] last seen inside profile --- services/gunDB/contact-api/jobs/lastSeenNode.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/gunDB/contact-api/jobs/lastSeenNode.js b/services/gunDB/contact-api/jobs/lastSeenNode.js index 002a167c..728f933d 100644 --- a/services/gunDB/contact-api/jobs/lastSeenNode.js +++ b/services/gunDB/contact-api/jobs/lastSeenNode.js @@ -37,6 +37,15 @@ const lastSeenNode = user => { logger.error(`Error inside lastSeenNode job: ${ack.err}`) } }) + + user + .get(Key.PROFILE) + .get(Key.LAST_SEEN_NODE) + .put(Date.now(), ack => { + if (ack.err) { + logger.error(`Error inside lastSeenNode job: ${ack.err}`) + } + }) } }, LAST_SEEN_NODE_INTERVAL) } From 8abfe5ef13b40c2a15b9111dc96944a7ff8bd8c7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 13:00:12 -0400 Subject: [PATCH 049/124] new profile --- services/gunDB/contact-api/actions.js | 35 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index ef145e1b..73746d32 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1133,7 +1133,21 @@ const setBio = (bio, user) => resolve() } }) - }) + }).then( + () => + new Promise((resolve, reject) => { + user + .get(Key.PROFILE) + .get(Key.BIO) + .put(bio, ack => { + if (ack.err) { + reject(new Error(ack.err)) + } else { + resolve() + } + }) + }) + ) /** * @param {string[]} mnemonicPhrase @@ -1216,8 +1230,23 @@ const setLastSeenApp = () => res() } }) - }) -const maxPostPerPage = 10 + }).then( + () => + new Promise((res, rej) => { + require('../Mediator') + .getUser() + .get(Key.PROFILE) + .get(Key.LAST_SEEN_APP) + .put(Date.now(), ack => { + if (ack.err) { + rej(new Error(ack.err)) + } else { + res() + } + }) + }) + ) + /** * @param {string} tags * @param {string} title From ea77a4dd7e6408c8a0795f5f666799ecb22765fb Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 13:00:26 -0400 Subject: [PATCH 050/124] createPost() --- services/gunDB/contact-api/actions.js | 137 +++++++++++++++----------- 1 file changed, 78 insertions(+), 59 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 73746d32..dd38efb2 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -3,7 +3,8 @@ */ const uuidv1 = require('uuid/v1') const logger = require('winston') -const { Constants, Schema } = require('shock-common') +const Common = require('shock-common') +const { Constants, Schema } = Common const { ErrorCode } = Constants @@ -1248,76 +1249,94 @@ const setLastSeenApp = () => ) /** - * @param {string} tags + * @param {string[]} tags * @param {string} title - * @param {Record} content - * @returns {Promise} + * @param {Common.Schema.ContentItem[]} content + * @returns {Promise} */ const createPost = async (tags, title, content) => { const user = require('../Mediator').getUser() const wall = user.get(Key.WALL) - if (!wall) { - throw new Error('wall not found') - } - let lastPageNum = await wall.get(Key.NUM_OF_PAGES).then() - if (typeof lastPageNum !== 'number') { - throw new Error('page not found') - } - const lastPage = await new Promise(res => { - if (typeof lastPageNum !== 'number') { - throw new Error('page not found') - } - wall - .get(Key.PAGES) - .get(lastPageNum.toString()) - //@ts-ignore - .load(res) - }) + const pages = wall.get(Key.PAGES) - const numPosts = Object.keys(lastPage).length - if (numPosts === maxPostPerPage) { - lastPageNum++ - await new Promise((res, rej) => { - if (typeof lastPageNum !== 'number') { - throw new Error('page not found') - } - wall.get(Key.NUM_OF_PAGES).put(lastPageNum, ack => { + const numOfPages = await (async () => { + const maybeNumOfPages = await Utils.tryAndWait(() => + wall.get(Key.NUM_OF_PAGES).then() + ) + + return (typeof maybeNumOfPages === 'number' && maybeNumOfPages) || 0 + })() + + const pageIdx = Math.max(0, numOfPages - 1).toString() + let page = pages.get(pageIdx) + + const count = (await page.get(Key.COUNT).then()) || 0 + + let isNewPage = false + if (count >= Common.Constants.Misc.NUM_OF_POSTS_PER_WALL_PAGE) { + // eslint-disable-next-line require-atomic-updates + page = wall.get(Key.PAGES) + isNewPage = true + } + + /** @type {string} */ + const postID = await new Promise((res, rej) => { + const _n = page.set( + { + date: Date.now(), + status: 'publish', + tags: tags.join('-'), + title + }, + ack => { if (ack.err) { rej(ack.err) } else { - res() + res(_n._.get) } - }) - }) - } - /** - * @type {import('shock-common').Schema.Post} - */ - const post = { - contentItems: content, - date: +Date(), - status: 'publish', - tags, - title - } - //** @type {string} */ - /*const newPostID = */ await new Promise((res, rej) => { - if (typeof lastPageNum !== 'number') { - throw new Error('page not found') - } - const _wallNode = wall - .get(Key.PAGES) - .get(lastPageNum.toString()) - //@ts-ignore - .set(post, ack => { - if (ack.err) { - rej(new Error(ack.err)) - } else { - res(_wallNode._.get) - } - }) + } + ) }) + + if (isNewPage) { + await Utils.promisifyGunNode(wall.get(Key.NUM_OF_PAGES)).put(numOfPages + 1) + } + + const post = page.get(postID) + + await Promise.all( + content.map(ci => { + // @ts-ignore + return Utils.promisifyGunNode(post).set(ci) + }) + ) + + const loadedPost = await new Promise(res => { + post.load(data => { + res(data) + }) + }) + + /** @type {Common.Schema.User} */ + const userForPost = await Getters.getMyUser() + + /** @type {Common.Schema.Post} */ + const completePost = { + ...loadedPost, + author: userForPost + } + + if (!Common.Schema.isPost(completePost)) { + throw new Error( + `completePost not a Post inside Actions.createPost(): ${JSON.stringify( + createPost + )}` + ) + } + + return completePost } + /** * @param {string} postId * @returns {Promise} From 230228713dc1ab00a7d1a707dc2a4086f25eaa1f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 13:07:46 -0400 Subject: [PATCH 051/124] posts post endpoint --- src/routes.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/routes.js b/src/routes.js index 48c08b65..b15774bc 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1757,19 +1757,18 @@ module.exports = async ( } }) - app.post(`/api/gun/wall`, async (req,res) => { + app.post(`/api/gun/wall/`, async (req,res) => { try{ const {tags,title,contentItems} = req.body - res.status(201).json(await GunActions.createPost(title,tags,contentItems)) + return res.status(201).json(await GunActions.createPost( + tags, + title, + contentItems + )) } catch(e) { - const {tags,title,contentItems} = req.body - if(!tags || !title || !contentItems) { - res.status(400).json({ - errorMessage: 'missing params' - }) - } - res.status(500).json({ - errorMessage: typeof e === 'string' ? e : e.message + return res.status(500).json({ + errorMessage: (typeof e === 'string' ? e : e.message) + || 'Unknown error.' }) } }) From 0e5477619fd6c3a6833906c756177293a3c9a6f0 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 18:28:07 -0400 Subject: [PATCH 052/124] upgrade shock-common --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cc13fbeb..13f74847 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "request-promise": "^4.2.2", "response-time": "^2.3.2", "shelljs": "^0.8.2", - "shock-common": "3.1.1", + "shock-common": "4.0.1", "socket.io": "2.1.1", "text-encoding": "^0.7.0", "tingodb": "^0.6.1", diff --git a/yarn.lock b/yarn.lock index 74b14e07..64648074 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5894,10 +5894,10 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -shock-common@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-3.1.1.tgz#544af57129dc8ac0db05119b292a8d1810b1ee27" - integrity sha512-WCa9jpzkRUc7dbyGOlp+5Gl8xPSjWXINwZ6bT8cl3tGpThxXk3JgmdC/hY4FVCZVXWXRhBvPWltpTgL1iZu31Q== +shock-common@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-4.0.1.tgz#035e7081b6e67f6721e68dcc6b4d1e4c8f2cd96d" + integrity sha512-3xAkG8lyfyZHK8trgOy2aN75uG1ZBm0MPoIEzP4hgXhyT/b80WmQzX3DqVSSmjfhq1Di0sjmNCY7O5Nf6cEmFg== dependencies: immer "^6.0.6" lodash "^4.17.15" From a16ec9d4ae9e2d1b99af402239978e8298017fc8 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 18:31:17 -0400 Subject: [PATCH 053/124] include id in newly-created post --- services/gunDB/contact-api/actions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index dd38efb2..3afa662c 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1323,7 +1323,8 @@ const createPost = async (tags, title, content) => { /** @type {Common.Schema.Post} */ const completePost = { ...loadedPost, - author: userForPost + author: userForPost, + id: postID } if (!Common.Schema.isPost(completePost)) { From 015c1a1753b00bd482168266944e4f2a54f90663 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 17 Jun 2020 10:59:44 -0400 Subject: [PATCH 054/124] upgrade shock-common --- package.json | 2 +- yarn.lock | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a1b337c1..10e7a609 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "request-promise": "^4.2.2", "response-time": "^2.3.2", "shelljs": "^0.8.2", - "shock-common": "0.x.x", + "shock-common": "4.0.1", "socket.io": "2.1.1", "text-encoding": "^0.7.0", "tingodb": "^0.6.1", diff --git a/yarn.lock b/yarn.lock index 82894a49..64648074 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3168,6 +3168,11 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +immer@^6.0.6: + version "6.0.9" + resolved "https://registry.yarnpkg.com/immer/-/immer-6.0.9.tgz#b9dd69b8e69b3a12391e87db1e3ff535d1b26485" + integrity sha512-SyCYnAuiRf67Lvk0VkwFvwtDoEiCMjeamnHvRfnVDyc7re1/rQrNxuL+jJ7lA3WvdC4uznrvbmm+clJ9+XXatg== + import-fresh@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" @@ -5500,6 +5505,19 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== + +redux@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" + integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== + dependencies: + loose-envify "^1.4.0" + symbol-observable "^1.2.0" + regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" @@ -5876,13 +5894,17 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -shock-common@0.x.x: - version "0.3.0" - resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-0.3.0.tgz#2e8a9c2cd1eda300a8461ea9648d250237f22f78" - integrity sha512-K0xOKkrOAvD4rlWVQD5WXASiKyfatEX2cj114LC8Wddi3wXpex5yLNdWBXNGFpL6Vc5Wzhza/sEHs4p+Q3xBmw== +shock-common@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/shock-common/-/shock-common-4.0.1.tgz#035e7081b6e67f6721e68dcc6b4d1e4c8f2cd96d" + integrity sha512-3xAkG8lyfyZHK8trgOy2aN75uG1ZBm0MPoIEzP4hgXhyT/b80WmQzX3DqVSSmjfhq1Di0sjmNCY7O5Nf6cEmFg== dependencies: + immer "^6.0.6" lodash "^4.17.15" normalizr "^3.6.0" + redux "^4.0.5" + redux-thunk "^2.3.0" + uuid "3.x.x" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" @@ -6302,6 +6324,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +symbol-observable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -6672,6 +6699,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid@3.x.x: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + uuid@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" From f315adf574831e7b6e09c0565068c96ea38e6ccf Mon Sep 17 00:00:00 2001 From: emad-salah Date: Sat, 20 Jun 2020 22:11:49 +0100 Subject: [PATCH 055/124] Fixed encryption toggle always detected as "true" --- src/routes.js | 2 +- src/server.js | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/routes.js b/src/routes.js index 9dd57c6e..918aadc0 100644 --- a/src/routes.js +++ b/src/routes.js @@ -229,7 +229,7 @@ module.exports = async ( const deviceId = req.headers["x-shockwallet-device-id"]; logger.debug("Decrypting route...") try { - if (nonEncryptedRoutes.includes(req.path) || process.env.DISABLE_SHOCK_ENCRYPTION) { + if (nonEncryptedRoutes.includes(req.path) || process.env.DISABLE_SHOCK_ENCRYPTION === "true") { return next(); } diff --git a/src/server.js b/src/server.js index fca6bab3..c0a8b9b7 100644 --- a/src/server.js +++ b/src/server.js @@ -43,7 +43,7 @@ const server = program => { logger.info('Mainnet Mode:', !!program.mainnet) - if (process.env.DISABLE_SHOCK_ENCRYPTION) { + if (process.env.DISABLE_SHOCK_ENCRYPTION === 'true') { logger.error('Encryption Mode: false') } else { logger.info('Encryption Mode: true') @@ -72,10 +72,7 @@ const server = program => { const deviceId = req.headers['x-shockwallet-device-id'] const oldSend = res.send - if ( - !nonEncryptedRoutes.includes(req.path) && - !process.env.DISABLE_SHOCK_ENCRYPTION - ) { + if (!nonEncryptedRoutes.includes(req.path)) { res.send = (...args) => { if (args[0] && args[0].encryptedData && args[0].encryptionKey) { logger.warn('Response loop detected!') @@ -260,7 +257,9 @@ const server = program => { // app.use(bodyParser.json({limit: '100000mb'})); app.use(bodyParser.json({ limit: '50mb' })) app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })) - app.use(modifyResponseBody) + if (process.env.DISABLE_SHOCK_ENCRYPTION !== 'true') { + app.use(modifyResponseBody) + } serverInstance.listen(module.serverPort, module.serverhost) From b5d2fc6c11c068daacaf6c865078116817c8aff5 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 22 Jun 2020 17:45:45 +0100 Subject: [PATCH 056/124] garbage collect gun --- services/gunDB/Mediator/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 2b91bae7..cd15c802 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -328,6 +328,17 @@ const logoff = () => { } const instantiateGun = () => { + if (user) { + user.leave() + } + // @ts-ignore + user = null + if (gun) { + gun.off() + } + // @ts-ignore + gun = null + const _gun = /** @type {unknown} */ (new Gun({ axe: false, peers: Config.PEERS From 7e996a207d975ff7e0a6309b757376cbc9e89230 Mon Sep 17 00:00:00 2001 From: boufni95 Date: Mon, 25 May 2020 17:47:30 +0200 Subject: [PATCH 057/124] gun err --- src/routes.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index 918aadc0..1c36cc01 100644 --- a/src/routes.js +++ b/src/routes.js @@ -436,12 +436,14 @@ 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", @@ -491,6 +493,13 @@ module.exports = async ( 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) @@ -1677,7 +1686,7 @@ module.exports = async ( res.json(channelBackups); }); }); - + const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') @@ -1695,7 +1704,7 @@ module.exports = async ( res.json({ok:"err"}) } }) - app.get("/api/gun/feedpoc", async (req,res) =>{ + app.get("api/gun/feedpoc", async (req,res) =>{ try{ logger.warn("FEED POC") const user = require('../services/gunDB/Mediator').getUser() @@ -1709,7 +1718,7 @@ module.exports = async ( }) const Events = require('../services/gunDB/contact-api/events') - + app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { try { // spinup From a9f2bc5063ce86885479e85e7b8b004b3c340779 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 22 Jun 2020 16:51:25 -0400 Subject: [PATCH 058/124] slash --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 1c36cc01..e4b59ba4 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1704,7 +1704,7 @@ module.exports = async ( res.json({ok:"err"}) } }) - app.get("api/gun/feedpoc", async (req,res) =>{ + app.get("/api/gun/feedpoc", async (req,res) =>{ try{ logger.warn("FEED POC") const user = require('../services/gunDB/Mediator').getUser() From d3ca2182e08b7eef71fcfc880b808c4c0fc4c4eb Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 15:23:29 -0400 Subject: [PATCH 059/124] always send json --- src/routes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes.js b/src/routes.js index bbaa3dde..ca749e35 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1856,9 +1856,9 @@ module.exports = async ( } }) - app.delete(`/api/gun/wall/:postID`,async (req,res) => { - //res.status(200).json(await GunActions.deletePost(postID)) - }) + app.delete(`/api/gun/wall/:postID`, (_, res) => res.status(200).json({ + ok: 'true' + })) ///////////////////////////////// /** * @template P From fb3314f20743aaf084c4527e266578dad97ed7c6 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 15:37:45 -0400 Subject: [PATCH 060/124] use 200 for now --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index ca749e35..1a254016 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1843,7 +1843,7 @@ module.exports = async ( app.post(`/api/gun/wall/`, async (req,res) => { try{ const {tags,title,contentItems} = req.body - return res.status(201).json(await GunActions.createPost( + return res.status(200).json(await GunActions.createPost( tags, title, contentItems From 9e0271bd98c74369fcdfebc1a7bc6551fc2cd72c Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 19:12:01 -0400 Subject: [PATCH 061/124] delete merge artifact --- services/gunDB/contact-api/getters.js | 105 -------------------------- 1 file changed, 105 deletions(-) delete mode 100644 services/gunDB/contact-api/getters.js diff --git a/services/gunDB/contact-api/getters.js b/services/gunDB/contact-api/getters.js deleted file mode 100644 index 0fcf9805..00000000 --- a/services/gunDB/contact-api/getters.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @format - */ -const Common = require('shock-common') -const Logger = require('winston') - -const Key = require('./key') -const Utils = require('./utils') - -/** - * @param {string} pub - * @returns {Promise} - */ -exports.currentOrderAddress = async pub => { - const currAddr = await Utils.tryAndWait(gun => - gun - .user(pub) - .get(Key.CURRENT_ORDER_ADDRESS) - .then() - ) - - if (typeof currAddr !== 'string') { - throw new TypeError('Expected user.currentOrderAddress to be an string') - } - - return currAddr -} - -/** - * @param {string} pub - * @returns {Promise} - */ -exports.userToIncomingID = async pub => { - const incomingID = await require('../Mediator') - .getUser() - .get(Key.USER_TO_INCOMING) - .get(pub) - .then() - - if (typeof incomingID === 'string') return incomingID - - return null -} - -/** - * @param {string} publicKey - * @returns {Promise} - */ -const getUser = async publicKey => { - /** - * @type {Common.Schema.User} - */ - const user = { - avatar: null, - bio: null, - displayName: null, - lastSeenApp: 0, - lastSeenNode: 0, - publicKey - } - - /** - * @type {unknown} - */ - const profile = await Utils.tryAndWait( - gun => - new Promise(res => { - const userNode = gun.get(`~${publicKey}`) - - userNode.load(data => res(data)) - }), - v => typeof v === 'object' && v !== null - ) - - if ( - typeof profile === 'object' && - profile !== null && - Common.Schema.isUser({ - ...profile, - publicKey - }) - ) { - Object.assign(user, profile) - Logger.error( - `Invalid profile found for publicKey: ${publicKey}, found: ${JSON.stringify( - profile - )}` - ) - } - - return user -} - -exports.getUser = getUser - -exports.getMyUser = () => { - const user = require('../Mediator').getUser() - const publicKey = user.is && user.is.pub - - if (typeof publicKey !== 'string') { - throw new Error('NOT_AUTH') - } - - return getUser(publicKey) -} From dd97106aaefc0f7f6af00b0a2dcfd864edb745c0 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 19:14:11 -0400 Subject: [PATCH 062/124] myUser getter --- services/gunDB/contact-api/getters/index.js | 49 +++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 9b33cb92..54d80fd5 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -1,6 +1,8 @@ /** * @format */ +const Common = require('shock-common') + const Key = require('../key') const Utils = require('../utils') @@ -39,4 +41,51 @@ exports.userToIncomingID = async pub => { return null } +/** + * @returns {Promise} + */ +const getMyUser = async () => { + const oldProfile = await Utils.tryAndWait( + (_, user) => new Promise(res => user.get(Key.PROFILE).load(res)), + v => typeof v !== 'object' + ) + + const bio = await Utils.tryAndWait( + (_, user) => user.get(Key.BIO).then(), + v => typeof v !== 'string' + ) + + const lastSeenApp = await Utils.tryAndWait( + (_, user) => user.get(Key.LAST_SEEN_APP).then(), + v => typeof v !== 'number' + ) + + const lastSeenNode = await Utils.tryAndWait( + (_, user) => user.get(Key.LAST_SEEN_NODE).then(), + v => typeof v !== 'number' + ) + + const publicKey = await Utils.tryAndWait( + (_, user) => Promise.resolve(user.is && user.is.pub), + v => typeof v !== 'string' + ) + + /** @type {Common.SchemaTypes.User} */ + const u = { + avatar: oldProfile.avatar, + // @ts-ignore + bio, + displayName: oldProfile.displayName, + // @ts-ignore + lastSeenApp, + // @ts-ignore + lastSeenNode, + // @ts-ignore + publicKey + } + + return u +} + +module.exports.getMyUser = getMyUser module.exports.Follows = require('./follows') From 06f969b64eb05496474c1fefe4060e84ef3edcbb Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 19:26:53 -0400 Subject: [PATCH 063/124] wall getters --- services/gunDB/contact-api/getters/index.js | 1 + services/gunDB/contact-api/getters/wall.js | 60 +++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 services/gunDB/contact-api/getters/wall.js diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 54d80fd5..5074b5dd 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -89,3 +89,4 @@ const getMyUser = async () => { module.exports.getMyUser = getMyUser module.exports.Follows = require('./follows') +module.exports.Wall = require('./wall') diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js new file mode 100644 index 00000000..50824099 --- /dev/null +++ b/services/gunDB/contact-api/getters/wall.js @@ -0,0 +1,60 @@ +/** + * @format + */ +const Common = require('shock-common') +const Utils = require('../utils') +const Key = require('../key') + +/** + * @returns {Promise} + */ +const getTotalPages = () => + /** @type {Promise} */ (Utils.tryAndWait( + (_, user) => + user + .get(Key.WALL) + .get(Key.NUM_OF_PAGES) + .then(), + v => typeof v !== 'number' + )) + +/** + * Won't fail if given an invalid page, will return an empty set. + * @param {number} page + * @returns {Promise} + */ +const getWallPage = async page => { + const totalPages = await getTotalPages() + const empty = { + count: 0, + posts: {} + } + + if (page === 0) { + return empty + } + + const actualPageIdx = page < 0 ? totalPages + (page + 1) : page - 1 + + const thePage = await Utils.tryAndWait( + (_, user) => + new Promise(res => { + user + .get(Key.WALL) + .get(Key.PAGES) + .get(actualPageIdx.toString()) + .load(res) + }) + ) + + if (Common.Schema.isWallPage(thePage)) { + return thePage + } + + return empty +} + +module.exports = { + getTotalPages, + getWallPage +} From 9e723d651529d86d198f3b2a9c411445ef0fcd57 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 19:28:36 -0400 Subject: [PATCH 064/124] wall GET --- src/routes.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/routes.js b/src/routes.js index 1a254016..57613147 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1839,6 +1839,19 @@ module.exports = async ( }) } }) +//////////////////////////////////////////////////////////////////////////////// + + app.get(`/api/gun/wall`, async (req, res) => { + try { + const { page } = req.query; + + return res.status(200).json(await GunGetters.Wall.getWallPage(page)) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message + }) + } + }) app.post(`/api/gun/wall/`, async (req,res) => { try{ From fb9b71781e1c5fe3bdd68096ed28591d37a3cee4 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 19:35:20 -0400 Subject: [PATCH 065/124] import gun/lib/load --- services/gunDB/Mediator/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index cd15c802..341fcee2 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -7,6 +7,8 @@ const logger = require('winston') Gun.log = () => {} // @ts-ignore require('gun/lib/open') +// @ts-ignore +require('gun/lib/load') const debounce = require('lodash/debounce') const Encryption = require('../../../utils/encryptionStore') From c438d3293f69690733d351dd433d038ea94cbc26 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 07:13:05 -0400 Subject: [PATCH 066/124] javascriptier exports --- services/gunDB/contact-api/getters/index.js | 6 +++++- services/gunDB/contact-api/getters/wall.js | 6 +++--- src/routes.js | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 5074b5dd..2bb192fb 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -6,6 +6,8 @@ const Common = require('shock-common') const Key = require('../key') const Utils = require('../utils') +const Wall = require('./wall') + /** * @param {string} pub * @returns {Promise} @@ -89,4 +91,6 @@ const getMyUser = async () => { module.exports.getMyUser = getMyUser module.exports.Follows = require('./follows') -module.exports.Wall = require('./wall') + +module.exports.getWallPage = Wall.getWallPage +module.exports.getWallTotalPages = Wall.getWallTotalPages diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 50824099..35b3a1ec 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -8,7 +8,7 @@ const Key = require('../key') /** * @returns {Promise} */ -const getTotalPages = () => +const getWallTotalPages = () => /** @type {Promise} */ (Utils.tryAndWait( (_, user) => user @@ -24,7 +24,7 @@ const getTotalPages = () => * @returns {Promise} */ const getWallPage = async page => { - const totalPages = await getTotalPages() + const totalPages = await getWallTotalPages() const empty = { count: 0, posts: {} @@ -55,6 +55,6 @@ const getWallPage = async page => { } module.exports = { - getTotalPages, + getWallTotalPages, getWallPage } diff --git a/src/routes.js b/src/routes.js index 57613147..e21d8686 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1845,7 +1845,7 @@ module.exports = async ( try { const { page } = req.query; - return res.status(200).json(await GunGetters.Wall.getWallPage(page)) + return res.status(200).json(await GunGetters.getWallPage(page)) } catch (err) { return res.status(500).json({ errorMessage: err.message From eecfe341566faa57856fcd4235c74e49d0606911 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 07:18:54 -0400 Subject: [PATCH 067/124] save content items correctly --- services/gunDB/contact-api/actions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 87c5bddf..f83a8616 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1303,11 +1303,12 @@ const createPost = async (tags, title, content) => { } const post = page.get(postID) + const contentItems = post.get(Key.CONTENT_ITEMS) await Promise.all( content.map(ci => { // @ts-ignore - return Utils.promisifyGunNode(post).set(ci) + return Utils.promisifyGunNode(contentItems).set(ci) }) ) From ed3e343e0eacd3715e187ed4a9e539ec01b75bb5 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 12:58:00 +0100 Subject: [PATCH 068/124] validate posts must contain at least one paragraph/image/video --- services/gunDB/contact-api/actions.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index f83a8616..4a8bfcf5 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1255,6 +1255,10 @@ const setLastSeenApp = () => * @returns {Promise} */ const createPost = async (tags, title, content) => { + if (content.length === 0) { + throw new Error(`A post must contain at least one paragraph/image/video`) + } + const user = require('../Mediator').getUser() const wall = user.get(Key.WALL) const pages = wall.get(Key.PAGES) From 82a55c5091ad7af15da92a43edfc533879682084 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 13:37:42 +0100 Subject: [PATCH 069/124] do not use promisifygunnode --- services/gunDB/contact-api/actions.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 4a8bfcf5..45be6a0a 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1310,10 +1310,19 @@ const createPost = async (tags, title, content) => { const contentItems = post.get(Key.CONTENT_ITEMS) await Promise.all( - content.map(ci => { - // @ts-ignore - return Utils.promisifyGunNode(contentItems).set(ci) - }) + content.map( + ci => + new Promise(res => { + // @ts-ignore + contentItems.set(ci, ack => { + if (ack.err) { + throw new Error(ack.err) + } + + res() + }) + }) + ) ) const loadedPost = await new Promise(res => { From 9dd2708f807922881d7389c9553abeb3bcb9fbd7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 08:53:22 -0400 Subject: [PATCH 070/124] provide total pages in api response --- src/routes.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index e21d8686..80a03986 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1845,7 +1845,13 @@ module.exports = async ( try { const { page } = req.query; - return res.status(200).json(await GunGetters.getWallPage(page)) + const totalPages = await GunGetters.getWallTotalPages() + const fetchedPage = await GunGetters.getWallPage(page) + + return res.status(200).json({ + ...fetchedPage, + totalPages, + }) } catch (err) { return res.status(500).json({ errorMessage: err.message From d139a6a05218aae5349782aa18d4c7e27d63ea80 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 09:08:19 -0400 Subject: [PATCH 071/124] return 0 if no page counter has been set --- services/gunDB/contact-api/getters/wall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 35b3a1ec..da92f1c7 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -16,7 +16,7 @@ const getWallTotalPages = () => .get(Key.NUM_OF_PAGES) .then(), v => typeof v !== 'number' - )) + )) || 0 /** * Won't fail if given an invalid page, will return an empty set. From 4a80fe5caf3892712f88dc881adef71bdc40e46b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 09:17:59 -0400 Subject: [PATCH 072/124] always return a number --- services/gunDB/contact-api/getters/wall.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index da92f1c7..94a919e0 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -8,15 +8,18 @@ const Key = require('../key') /** * @returns {Promise} */ -const getWallTotalPages = () => - /** @type {Promise} */ (Utils.tryAndWait( +const getWallTotalPages = async () => { + const totalPages = await Utils.tryAndWait( (_, user) => user .get(Key.WALL) .get(Key.NUM_OF_PAGES) .then(), v => typeof v !== 'number' - )) || 0 + ) + + return typeof totalPages === 'number' ? totalPages : 0 +} /** * Won't fail if given an invalid page, will return an empty set. From 87a71e4fc544c8b7ea18ed69497c226738fdf849 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 14:18:03 -0400 Subject: [PATCH 073/124] better post creation process --- services/gunDB/contact-api/actions.js | 152 ++++++++++++++------- services/gunDB/contact-api/getters/wall.js | 11 ++ 2 files changed, 115 insertions(+), 48 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 45be6a0a..6692eb19 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1259,76 +1259,132 @@ const createPost = async (tags, title, content) => { throw new Error(`A post must contain at least one paragraph/image/video`) } - const user = require('../Mediator').getUser() - const wall = user.get(Key.WALL) - const pages = wall.get(Key.PAGES) - const numOfPages = await (async () => { - const maybeNumOfPages = await Utils.tryAndWait(() => - wall.get(Key.NUM_OF_PAGES).then() + const maybeNumOfPages = await Utils.tryAndWait( + (_, user) => user.get(Key.NUM_OF_PAGES).then(), + v => typeof v !== 'number' ) - return (typeof maybeNumOfPages === 'number' && maybeNumOfPages) || 0 + return typeof maybeNumOfPages === 'number' ? maybeNumOfPages : 0 })() - const pageIdx = Math.max(0, numOfPages - 1).toString() - let page = pages.get(pageIdx) + let pageIdx = Math.max(0, numOfPages - 1).toString() - const count = (await page.get(Key.COUNT).then()) || 0 + const count = + numOfPages === 0 + ? 0 + : /** @type {number} */ (await Utils.tryAndWait( + (_, user) => + user + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .get(Key.COUNT) + .then(), + v => typeof v !== 'number' + )) - let isNewPage = false - if (count >= Common.Constants.Misc.NUM_OF_POSTS_PER_WALL_PAGE) { - // eslint-disable-next-line require-atomic-updates - page = wall.get(Key.PAGES) - isNewPage = true + const shouldBeNewPage = + count >= Common.Constants.Misc.NUM_OF_POSTS_PER_WALL_PAGE + + if (shouldBeNewPage) { + pageIdx = Number(pageIdx + 1).toString() } /** @type {string} */ const postID = await new Promise((res, rej) => { - const _n = page.set( - { - date: Date.now(), - status: 'publish', - tags: tags.join('-'), - title - }, - ack => { - if (ack.err) { - rej(ack.err) - } else { - res(_n._.get) + const _n = require('../Mediator') + .getUser() + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .set( + { + date: Date.now(), + status: 'publish', + tags: tags.join('-'), + title + }, + ack => { + if (ack.err) { + rej(ack.err) + } else { + res(_n._.get) + } } - } - ) + ) }) - if (isNewPage) { - await Utils.promisifyGunNode(wall.get(Key.NUM_OF_PAGES)).put(numOfPages + 1) + if (shouldBeNewPage) { + await new Promise(res => { + require('../Mediator') + .getUser() + .get(Key.WALL) + .get(Key.NUM_OF_PAGES) + .put(numOfPages + 1, ack => { + if (ack.err) { + throw new Error(ack.err) + } + + res() + }) + }) } - const post = page.get(postID) - const contentItems = post.get(Key.CONTENT_ITEMS) + const contentItems = require('../Mediator') + .getUser() + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .get(postID) + .get(Key.CONTENT_ITEMS) - await Promise.all( - content.map( - ci => - new Promise(res => { - // @ts-ignore - contentItems.set(ci, ack => { - if (ack.err) { - throw new Error(ack.err) - } + try { + await Promise.all( + content.map( + ci => + new Promise(res => { + // @ts-ignore + contentItems.set(ci, ack => { + if (ack.err) { + throw new Error(ack.err) + } - res() + res() + }) }) - }) + ) ) - ) + } catch (e) { + await new Promise(res => { + require('../Mediator') + .getUser() + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .get(postID) + .put(null, ack => { + if (ack.err) { + throw new Error(ack.err) + } + + res() + }) + }) + + throw e + } const loadedPost = await new Promise(res => { - post.load(data => { - res(data) - }) + require('../Mediator') + .getUser() + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .get(postID) + .load(data => { + res(data) + }) }) /** @type {Common.Schema.User} */ diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 94a919e0..b5f25d10 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -51,6 +51,17 @@ const getWallPage = async page => { ) if (Common.Schema.isWallPage(thePage)) { + const clean = { + ...thePage + } + + // delete unsuccessful writes + Object.keys(clean.posts).forEach(k => { + if (clean.posts[k] === null) { + delete clean.posts[k] + } + }) + return thePage } From 8bb27affa0b9e6e066dc3b64796a6ba7432b7303 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 16:49:11 -0400 Subject: [PATCH 074/124] writes number of pages after first post --- services/gunDB/contact-api/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 6692eb19..497cfd98 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1315,7 +1315,7 @@ const createPost = async (tags, title, content) => { ) }) - if (shouldBeNewPage) { + if (shouldBeNewPage || numOfPages === 0) { await new Promise(res => { require('../Mediator') .getUser() From 6fb804701c4b0870f72fa1e8a381c6e7122b49ca Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 17:01:20 -0400 Subject: [PATCH 075/124] optimization --- services/gunDB/contact-api/getters/wall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index b5f25d10..969ed3e5 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -33,7 +33,7 @@ const getWallPage = async page => { posts: {} } - if (page === 0) { + if (page === 0 || totalPages === 0) { return empty } From b4c22228ecf203aea20e02b4c01b926b74d6173d Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 17:05:06 -0400 Subject: [PATCH 076/124] sanitize before validation --- services/gunDB/contact-api/getters/wall.js | 24 +++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 969ed3e5..feff74a3 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -50,22 +50,18 @@ const getWallPage = async page => { }) ) - if (Common.Schema.isWallPage(thePage)) { - const clean = { - ...thePage - } - - // delete unsuccessful writes - Object.keys(clean.posts).forEach(k => { - if (clean.posts[k] === null) { - delete clean.posts[k] - } - }) - - return thePage + const clean = { + ...thePage } - return empty + // delete unsuccessful writes + Object.keys(clean.posts).forEach(k => { + if (clean.posts[k] === null) { + delete clean.posts[k] + } + }) + + return Common.Schema.isWallPage(clean) ? clean : empty } module.exports = { From ba12d42d390bdb33cc57903b991b82f7657682f0 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 17:12:31 -0400 Subject: [PATCH 077/124] typo --- services/gunDB/contact-api/actions.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 497cfd98..01c51740 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1261,7 +1261,11 @@ const createPost = async (tags, title, content) => { const numOfPages = await (async () => { const maybeNumOfPages = await Utils.tryAndWait( - (_, user) => user.get(Key.NUM_OF_PAGES).then(), + (_, user) => + user + .get(Key.WALL) + .get(Key.NUM_OF_PAGES) + .then(), v => typeof v !== 'number' ) From b7abbb2535e80ba4120a7aa488ba4e331abf7e37 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 17:27:36 -0400 Subject: [PATCH 078/124] ensure it's object --- services/gunDB/contact-api/getters/wall.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index feff74a3..2a319ad0 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -47,7 +47,8 @@ const getWallPage = async page => { .get(Key.PAGES) .get(actualPageIdx.toString()) .load(res) - }) + }), + v => typeof v !== 'object' ) const clean = { From 1b6fe7894734e3c8faa352713212c097672e957e Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 17:40:09 -0400 Subject: [PATCH 079/124] typos --- services/gunDB/contact-api/actions.js | 17 +++++++++++++++++ services/gunDB/contact-api/key.js | 2 ++ 2 files changed, 19 insertions(+) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 01c51740..0c516f70 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1295,6 +1295,22 @@ const createPost = async (tags, title, content) => { pageIdx = Number(pageIdx + 1).toString() } + await new Promise(res => { + require('../Mediator') + .getUser() + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .get(Key.COUNT) + .put(count + 1, ack => { + if (ack.err) { + throw new Error(ack.err) + } + + res() + }) + }) + /** @type {string} */ const postID = await new Promise((res, rej) => { const _n = require('../Mediator') @@ -1302,6 +1318,7 @@ const createPost = async (tags, title, content) => { .get(Key.WALL) .get(Key.PAGES) .get(pageIdx) + .get(Key.POSTS) .set( { date: Date.now(), diff --git a/services/gunDB/contact-api/key.js b/services/gunDB/contact-api/key.js index 35269545..0c130712 100644 --- a/services/gunDB/contact-api/key.js +++ b/services/gunDB/contact-api/key.js @@ -53,3 +53,5 @@ exports.COUNT = 'count' exports.CONTENT_ITEMS = 'contentItems' exports.FOLLOWS = 'follows' + +exports.POSTS = 'posts' From c543647abab27d3ca6074a1127ba8b203ad70925 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 24 Jun 2020 17:43:39 -0400 Subject: [PATCH 080/124] typo --- services/gunDB/contact-api/actions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 0c516f70..0231e222 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1402,6 +1402,7 @@ const createPost = async (tags, title, content) => { .get(Key.WALL) .get(Key.PAGES) .get(pageIdx) + .get(Key.POSTS) .get(postID) .load(data => { res(data) From 9038b20b71072aac6d620cc3005d78e5114e3f44 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 10:49:35 -0400 Subject: [PATCH 081/124] correct path --- services/gunDB/contact-api/actions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 0231e222..baa4c6f9 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1383,6 +1383,7 @@ const createPost = async (tags, title, content) => { .get(Key.WALL) .get(Key.PAGES) .get(pageIdx) + .get(Key.POSTS) .get(postID) .put(null, ack => { if (ack.err) { From 0cc581c520e3235b9efdcad737b04eefd931f4a8 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 11:03:16 -0400 Subject: [PATCH 082/124] correct path --- services/gunDB/contact-api/actions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index baa4c6f9..5b5a4995 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1357,6 +1357,7 @@ const createPost = async (tags, title, content) => { .get(Key.WALL) .get(Key.PAGES) .get(pageIdx) + .get(Key.POSTS) .get(postID) .get(Key.CONTENT_ITEMS) From 2e516eeeef6d48a60338d31f2e90ce59942b7007 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 11:48:05 -0400 Subject: [PATCH 083/124] better wall getter --- services/gunDB/contact-api/getters/wall.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 2a319ad0..80df18ad 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -22,23 +22,24 @@ const getWallTotalPages = async () => { } /** - * Won't fail if given an invalid page, will return an empty set. * @param {number} page * @returns {Promise} */ const getWallPage = async page => { const totalPages = await getWallTotalPages() - const empty = { - count: 0, - posts: {} - } if (page === 0 || totalPages === 0) { - return empty + return { + count: 0, + posts: {} + } } const actualPageIdx = page < 0 ? totalPages + (page + 1) : page - 1 + /** + * @type {Common.SchemaTypes.WallPage} + */ const thePage = await Utils.tryAndWait( (_, user) => new Promise(res => { @@ -46,6 +47,7 @@ const getWallPage = async page => { .get(Key.WALL) .get(Key.PAGES) .get(actualPageIdx.toString()) + // @ts-ignore .load(res) }), v => typeof v !== 'object' @@ -62,7 +64,13 @@ const getWallPage = async page => { } }) - return Common.Schema.isWallPage(clean) ? clean : empty + if (!Common.Schema.isWallPage(clean)) { + throw new Error( + `Fetched page not a wall page, instead got: ${JSON.stringify(clean)}` + ) + } + + return clean } module.exports = { From fcfd649042647cf349da01698107eb7af1531999 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 12:30:26 -0400 Subject: [PATCH 084/124] assign id --- services/gunDB/contact-api/getters/wall.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 80df18ad..384e8dbe 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -64,6 +64,14 @@ const getWallPage = async page => { } }) + for (const [key, post] of Object.entries(clean.posts)) { + if (post === null) { + delete clean.posts[key] + } else { + post.id = key + } + } + if (!Common.Schema.isWallPage(clean)) { throw new Error( `Fetched page not a wall page, instead got: ${JSON.stringify(clean)}` From 4122f6e5aee70da5f954759332362e9783dc7ca1 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 12:33:54 -0400 Subject: [PATCH 085/124] check out ouf bounds --- services/gunDB/contact-api/getters/wall.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 384e8dbe..dd40ef0d 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -23,6 +23,8 @@ const getWallTotalPages = async () => { /** * @param {number} page + * @throws {TypeError} + * @throws {RangeError} * @returns {Promise} */ const getWallPage = async page => { @@ -37,6 +39,10 @@ const getWallPage = async page => { const actualPageIdx = page < 0 ? totalPages + (page + 1) : page - 1 + if (actualPageIdx > totalPages - 1) { + throw new RangeError(`Requested a page out of bounds`) + } + /** * @type {Common.SchemaTypes.WallPage} */ From 9574634b3088b896a9e53ef887cd0e49382c3f9f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 12:58:10 -0400 Subject: [PATCH 086/124] correct page index for negative page arguments --- services/gunDB/contact-api/getters/wall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index dd40ef0d..908ec622 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -37,7 +37,7 @@ const getWallPage = async page => { } } - const actualPageIdx = page < 0 ? totalPages + (page + 1) : page - 1 + const actualPageIdx = page < 0 ? totalPages + page : page - 1 if (actualPageIdx > totalPages - 1) { throw new RangeError(`Requested a page out of bounds`) From 89862c376c2dcd1fcc2a027944bf042fd568e167 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 13:01:15 -0400 Subject: [PATCH 087/124] remove dup code --- services/gunDB/contact-api/getters/wall.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 908ec622..e9593a33 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -63,14 +63,8 @@ const getWallPage = async page => { ...thePage } - // delete unsuccessful writes - Object.keys(clean.posts).forEach(k => { - if (clean.posts[k] === null) { - delete clean.posts[k] - } - }) - for (const [key, post] of Object.entries(clean.posts)) { + // delete unsuccessful writes if (post === null) { delete clean.posts[key] } else { From a8833b60135d511d1805db7bf96ff6d2aac58071 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 18:03:18 +0100 Subject: [PATCH 088/124] parse page as number --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 80a03986..5cd34080 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1846,7 +1846,7 @@ module.exports = async ( const { page } = req.query; const totalPages = await GunGetters.getWallTotalPages() - const fetchedPage = await GunGetters.getWallPage(page) + const fetchedPage = await GunGetters.getWallPage(Number(page)) return res.status(200).json({ ...fetchedPage, From 304e4f314a706ba2646168b3b6fe30aa06a80748 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 13:28:08 -0400 Subject: [PATCH 089/124] validate page number --- src/routes.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 5cd34080..8303c4fc 100644 --- a/src/routes.js +++ b/src/routes.js @@ -12,6 +12,7 @@ const httpsAgent = require("https"); const responseTime = require("response-time"); const uuid = require("uuid/v4"); const Common = require('shock-common') +const isARealUsableNumber = require('lodash/isFinite') const getListPage = require("../utils/paginate"); const auth = require("../services/auth/auth"); @@ -1845,8 +1846,17 @@ module.exports = async ( try { const { page } = req.query; + const pageNum = Number(page) + + if (isARealUsableNumber(pageNum)) { + return res.status(400).json({ + field: 'page', + errorMessage: 'Not a number' + }) + } + const totalPages = await GunGetters.getWallTotalPages() - const fetchedPage = await GunGetters.getWallPage(Number(page)) + const fetchedPage = await GunGetters.getWallPage(pageNum) return res.status(200).json({ ...fetchedPage, From d02085abea01f219fceb9eb3a74b26decff4bd94 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 13:31:30 -0400 Subject: [PATCH 090/124] correct validation --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 8303c4fc..5c4e99de 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1848,7 +1848,7 @@ module.exports = async ( const pageNum = Number(page) - if (isARealUsableNumber(pageNum)) { + if (!isARealUsableNumber(pageNum)) { return res.status(400).json({ field: 'page', errorMessage: 'Not a number' From d9e9d4f90a14ad181c1b47153d19ff36d1e53eaa Mon Sep 17 00:00:00 2001 From: emad-salah Date: Thu, 25 Jun 2020 21:50:49 +0100 Subject: [PATCH 091/124] Caching now only works on GET requests and added .env toggles for toggling caching and warnings related to it. --- .env.example | 7 ++++++- src/server.js | 53 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/.env.example b/.env.example index 8a042b30..4ea11d88 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,6 @@ -DISABLE_SHOCK_ENCRYPTION=false \ No newline at end of file +DATA_FILE_NAME=data3 +PEERS=["http://gun.shock.network:8765/gun"] +MS_TO_TOKEN_EXPIRATION=4500000 +DISABLE_SHOCK_ENCRYPTION=false +CACHE_HEADERS_MANDATORY=true +SHOCK_CACHE=true \ No newline at end of file diff --git a/src/server.js b/src/server.js index c0a8b9b7..20b4b3c7 100644 --- a/src/server.js +++ b/src/server.js @@ -68,6 +68,46 @@ const server = program => { .digest('hex') } + const cacheCheck = ({ req, res, args, send }) => { + if ( + (process.env.SHOCK_CACHE === 'true' || !process.env.SHOCK_CACHE) && + req.method === 'GET' + ) { + const dataHash = hashData(args[0]).slice(-8) + res.set('shock-cache-hash', dataHash) + + logger.debug('shock-cache-hash:', req.headers['shock-cache-hash']) + logger.debug('Data Hash:', dataHash) + if ( + !req.headers['shock-cache-hash'] && + (process.env.CACHE_HEADERS_MANDATORY === 'true' || + !process.env.CACHE_HEADERS_MANDATORY) + ) { + logger.warn( + "Request is missing 'shock-cache-hash' header, please make sure to include that in each GET request in order to benefit from reduced data usage" + ) + return { cached: false, hash: dataHash } + } + + if (req.headers['shock-cache-hash'] === dataHash) { + logger.debug('Same Hash Detected!') + args[0] = null + res.status(304) + send.apply(res, args) + return { cached: true, hash: dataHash } + } + + return { cached: false, hash: dataHash } + } + + return { cached: false, hash: null } + } + + /** + * @param {Express.Request} req + * @param {Express.Response} res + * @param {(() => void)} next + */ const modifyResponseBody = (req, res, next) => { const deviceId = req.headers['x-shockwallet-device-id'] const oldSend = res.send @@ -80,16 +120,9 @@ const server = program => { return } - const dataHash = hashData(args[0]).slice(-8) - res.set('shock-cache-hash', dataHash) + const { cached, hash } = cacheCheck({ req, res, args, send: oldSend }) - logger.debug('shock-cache-hash:', req.headers['shock-cache-hash']) - logger.debug('Data Hash:', dataHash) - if (req.headers['shock-cache-hash'] === dataHash) { - logger.debug('Same Hash Detected!') - args[0] = null - res.status(304) - oldSend.apply(res, args) + if (cached) { return } @@ -100,7 +133,7 @@ const server = program => { message: args[0] ? args[0] : {}, deviceId, metadata: { - hash: dataHash + hash } }) : args[0] From 552e625e5fd13aee1a6a5805c1c0489343df6e53 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 18:45:31 -0400 Subject: [PATCH 092/124] initial value of 1 for page --- services/gunDB/contact-api/actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 5b5a4995..cfdd96fa 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1302,7 +1302,7 @@ const createPost = async (tags, title, content) => { .get(Key.PAGES) .get(pageIdx) .get(Key.COUNT) - .put(count + 1, ack => { + .put(shouldBeNewPage ? 1 : count + 1, ack => { if (ack.err) { throw new Error(ack.err) } From 39c01733d7a58a452b4f5798a8f019c8d5882748 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 19:03:34 -0400 Subject: [PATCH 093/124] better initialization --- services/gunDB/contact-api/actions.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index cfdd96fa..ab7d6955 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1301,14 +1301,21 @@ const createPost = async (tags, title, content) => { .get(Key.WALL) .get(Key.PAGES) .get(pageIdx) - .get(Key.COUNT) - .put(shouldBeNewPage ? 1 : count + 1, ack => { - if (ack.err) { - throw new Error(ack.err) - } + .put( + { + [Key.COUNT]: shouldBeNewPage ? 1 : count + 1, + posts: { + unused: null + } + }, + ack => { + if (ack.err) { + throw new Error(ack.err) + } - res() - }) + res() + } + ) }) /** @type {string} */ From 0be779b73c992ef74a6870657c7d9db203095e7b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 13:00:21 -0400 Subject: [PATCH 094/124] correctly reject errors --- services/gunDB/contact-api/actions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index ab7d6955..7ab64e61 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1295,7 +1295,7 @@ const createPost = async (tags, title, content) => { pageIdx = Number(pageIdx + 1).toString() } - await new Promise(res => { + await new Promise((res, rej) => { require('../Mediator') .getUser() .get(Key.WALL) @@ -1310,7 +1310,7 @@ const createPost = async (tags, title, content) => { }, ack => { if (ack.err) { - throw new Error(ack.err) + rej(new Error(ack.err)) } res() @@ -1335,7 +1335,7 @@ const createPost = async (tags, title, content) => { }, ack => { if (ack.err) { - rej(ack.err) + rej(new Error(ack.err)) } else { res(_n._.get) } From d0349669f9d3c4c2a3cd91aa618d66831b4e5b49 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 13:00:38 -0400 Subject: [PATCH 095/124] check return type from gun --- services/gunDB/contact-api/actions.js | 31 ++++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 7ab64e61..1998d24a 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1274,19 +1274,24 @@ const createPost = async (tags, title, content) => { let pageIdx = Math.max(0, numOfPages - 1).toString() - const count = - numOfPages === 0 - ? 0 - : /** @type {number} */ (await Utils.tryAndWait( - (_, user) => - user - .get(Key.WALL) - .get(Key.PAGES) - .get(pageIdx) - .get(Key.COUNT) - .then(), - v => typeof v !== 'number' - )) + const count = await (async () => { + if (numOfPages === 0) { + return 0 + } + + const maybeCount = await Utils.tryAndWait( + (_, user) => + user + .get(Key.WALL) + .get(Key.PAGES) + .get(pageIdx) + .get(Key.COUNT) + .then(), + v => typeof v !== 'number' + ) + + return typeof maybeCount === 'number' ? maybeCount : 0 + })() const shouldBeNewPage = count >= Common.Constants.Misc.NUM_OF_POSTS_PER_WALL_PAGE From 35e21970955f2ad67eaa3aa2b2be8e17476f583a Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 13:08:14 -0400 Subject: [PATCH 096/124] check return type from gun --- services/gunDB/contact-api/getters/wall.js | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index e9593a33..43393dbf 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -56,7 +56,28 @@ const getWallPage = async page => { // @ts-ignore .load(res) }), - v => typeof v !== 'object' + maybePage => { + if (typeof maybePage !== 'object' || maybePage === null) { + return true + } + + const clean = { + ...maybePage + } + + // @ts-ignore + for (const [key, post] of Object.entries(clean.posts)) { + // delete unsuccessful writes + if (post === null) { + // @ts-ignore + delete clean.posts[key] + } else { + post.id = key + } + } + + return !Common.Schema.isWallPage(clean) + } ) const clean = { From a8104d490c23596a57da765576a8d6d34aa3ebe7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 19:58:19 -0400 Subject: [PATCH 097/124] circumvent gun.load() bug --- services/gunDB/contact-api/getters/wall.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 43393dbf..25a0b004 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -76,6 +76,12 @@ const getWallPage = async page => { } } + // .load() sometimes doesn't load all data on first call + // @ts-ignore + if (Object.keys(clean.posts).length === 0) { + return true + } + return !Common.Schema.isWallPage(clean) } ) From ca9ecb6c801590b1d85f7ece9b2d730fa5be28f5 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 21:10:32 -0400 Subject: [PATCH 098/124] more precise count --- services/gunDB/contact-api/getters/wall.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 25a0b004..54912536 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -71,6 +71,8 @@ const getWallPage = async page => { if (post === null) { // @ts-ignore delete clean.posts[key] + // @ts-ignore + clean.count-- } else { post.id = key } From b1594e1707e6f9c333711dc180db12839c2186a1 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 21:12:23 -0400 Subject: [PATCH 099/124] correct place for count correction --- services/gunDB/contact-api/getters/wall.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 54912536..f55e7b1e 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -71,8 +71,6 @@ const getWallPage = async page => { if (post === null) { // @ts-ignore delete clean.posts[key] - // @ts-ignore - clean.count-- } else { post.id = key } @@ -96,6 +94,7 @@ const getWallPage = async page => { // delete unsuccessful writes if (post === null) { delete clean.posts[key] + clean.count-- } else { post.id = key } From 140b0a43b0e5d79e2032d3366cc05f4a19a1ba2b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 26 Jun 2020 21:15:53 -0400 Subject: [PATCH 100/124] support public key lookup for wall --- services/gunDB/contact-api/getters/wall.js | 26 ++++++++++++++-------- src/routes.js | 7 +++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index f55e7b1e..cff14b84 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -6,15 +6,19 @@ const Utils = require('../utils') const Key = require('../key') /** + * @param {string=} publicKey * @returns {Promise} */ -const getWallTotalPages = async () => { +const getWallTotalPages = async publicKey => { const totalPages = await Utils.tryAndWait( - (_, user) => - user + (gun, u) => { + const user = publicKey ? gun.get(`~${publicKey}`) : u + + return user .get(Key.WALL) .get(Key.NUM_OF_PAGES) - .then(), + .then() + }, v => typeof v !== 'number' ) @@ -23,12 +27,13 @@ const getWallTotalPages = async () => { /** * @param {number} page + * @param {string=} publicKey * @throws {TypeError} * @throws {RangeError} * @returns {Promise} */ -const getWallPage = async page => { - const totalPages = await getWallTotalPages() +const getWallPage = async (page, publicKey) => { + const totalPages = await getWallTotalPages(publicKey) if (page === 0 || totalPages === 0) { return { @@ -47,15 +52,18 @@ const getWallPage = async page => { * @type {Common.SchemaTypes.WallPage} */ const thePage = await Utils.tryAndWait( - (_, user) => - new Promise(res => { + (g, u) => { + const user = publicKey ? g.get(`~${publicKey}`) : u + + return new Promise(res => { user .get(Key.WALL) .get(Key.PAGES) .get(actualPageIdx.toString()) // @ts-ignore .load(res) - }), + }) + }, maybePage => { if (typeof maybePage !== 'object' || maybePage === null) { return true diff --git a/src/routes.js b/src/routes.js index 5c4e99de..fcaeb879 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1842,9 +1842,10 @@ module.exports = async ( }) //////////////////////////////////////////////////////////////////////////////// - app.get(`/api/gun/wall`, async (req, res) => { + app.get(`/api/gun/wall/:publicKey`, async (req, res) => { try { const { page } = req.query; + const {publicKey} = req.params const pageNum = Number(page) @@ -1855,8 +1856,8 @@ module.exports = async ( }) } - const totalPages = await GunGetters.getWallTotalPages() - const fetchedPage = await GunGetters.getWallPage(pageNum) + const totalPages = await GunGetters.getWallTotalPages(publicKey) + const fetchedPage = await GunGetters.getWallPage(pageNum, publicKey) return res.status(200).json({ ...fetchedPage, From c569526c52a82f0f601ec0e654904c6b8ba17217 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 02:43:45 +0100 Subject: [PATCH 101/124] route param optional --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index fcaeb879..199f4346 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1842,7 +1842,7 @@ module.exports = async ( }) //////////////////////////////////////////////////////////////////////////////// - app.get(`/api/gun/wall/:publicKey`, async (req, res) => { + app.get(`/api/gun/wall/:publicKey?`, async (req, res) => { try { const { page } = req.query; const {publicKey} = req.params From 017dbab0c945e15117436678fa9ffa1e9bd229bc Mon Sep 17 00:00:00 2001 From: boufni95 Date: Sat, 27 Jun 2020 16:30:50 +0200 Subject: [PATCH 102/124] add docker files --- .dockerignore | 3 +++ Dockerfile | 29 +++++++++++++++++++++++++++++ docker-start.sh | 5 +++++ 3 files changed, 37 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-start.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..eebfc91a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +**/.git +**/node_modules +**/radata \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..90e3aef2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM node:12.18.0-alpine3.9 + +WORKDIR /usr/src/app + + +ADD ./package.json /usr/src/app/package.json +ADD ./yarn.lock /usr/src/app/yarn.lock +#RUN useradd app && \ +# mkdir -p /home/app/.lnd +RUN apk update && apk upgrade && \ + apk add --no-cache bash git openssh +RUN yarn install + +ADD . /usr/src/app +RUN ls /usr/src/app + +RUN chmod +x ./docker-start.sh +#ADD ./tls.cert /usr/src/app/tls.cert +#ADD ./admin.macaroon /usr/src/app/admin.macaroon + +# && \ +# chown -R app:app /home/app && \ +# chown -R app:app /usr/src/app && \ +# chown -R app:app /start.sh + +#ARG lnd_address +#ENV LND_ADDR=$lnd_address +EXPOSE 9835 +CMD ["./docker-start.sh"] \ No newline at end of file diff --git a/docker-start.sh b/docker-start.sh new file mode 100644 index 00000000..986525b1 --- /dev/null +++ b/docker-start.sh @@ -0,0 +1,5 @@ +#!/bin/ash +node main -h 0.0.0.0 \ + -m admin.macaroon \ + -d tls.cert \ + -l $LND_ADDR \ No newline at end of file From 75aeb7af42f8e696eea9caf2a5fe7051b290f5a6 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 16:27:43 -0400 Subject: [PATCH 103/124] add ramda --- package.json | 2 ++ yarn.lock | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/package.json b/package.json index 10e7a609..68b03834 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "lodash": "^4.17.15", "method-override": "^2.3.7", "promise": "^8.0.1", + "ramda": "^0.27.0", "request": "^2.87.0", "request-promise": "^4.2.2", "response-time": "^2.3.2", @@ -61,6 +62,7 @@ "@types/jest": "^24.0.18", "@types/jsonwebtoken": "^8.3.7", "@types/lodash": "^4.14.141", + "@types/ramda": "types/npm-ramda#dist", "@types/socket.io": "^2.1.4", "@types/uuid": "^3.4.5", "babel-eslint": "^10.0.3", diff --git a/yarn.lock b/yarn.lock index 64648074..f9da858b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -633,6 +633,10 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/ramda@types/npm-ramda#dist": + version "0.25.0" + resolved "https://codeload.github.com/types/npm-ramda/tar.gz/9529aa3c8ff70ff84afcbc0be83443c00f30ea90" + "@types/range-parser@*": version "1.2.3" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" @@ -5388,6 +5392,11 @@ ramda@^0.26.1: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== +ramda@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.0.tgz#915dc29865c0800bf3f69b8fd6c279898b59de43" + integrity sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA== + random-bytes@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" From 3c72432dceeeeec18dcc014803eeefdb2aa70142 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 18:25:32 -0400 Subject: [PATCH 104/124] simple feed functionality --- services/gunDB/contact-api/getters/feed.js | 64 +++++++++++++++++++++ services/gunDB/contact-api/getters/index.js | 3 + src/routes.js | 42 ++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 services/gunDB/contact-api/getters/feed.js diff --git a/services/gunDB/contact-api/getters/feed.js b/services/gunDB/contact-api/getters/feed.js new file mode 100644 index 00000000..0d7a9a72 --- /dev/null +++ b/services/gunDB/contact-api/getters/feed.js @@ -0,0 +1,64 @@ +/** + * @format + */ +const Common = require('shock-common') +const isFinite = require('lodash/isFinite') +const shuffle = require('lodash/shuffle') +const R = require('ramda') + +const Follows = require('./follows') +const Wall = require('./wall') + +/** + * @param {number} page + * @throws {TypeError} + * @throws {RangeError} + * @returns {Promise} + */ +const getFeedPage = async page => { + if (!isFinite(page)) { + throw new TypeError(`Please provide an actual number for [page]`) + } + + if (page <= 0) { + throw new RangeError(`Please provide only positive numbers for [page]`) + } + + const subbedPublicKeys = Object.values(await Follows.currentFollows()).map( + f => f.user + ) + + if (subbedPublicKeys.length === 0) { + return [] + } + + // say there are 20 public keys total + // page 1: page 1 from first 10 public keys + // page 2: page 1 from second 10 public keys + // page 3: page 2 from first 10 public keys + // page 4: page 2 from first 10 public keys + // etc + + const pagedPublicKeys = R.splitEvery(10, shuffle(subbedPublicKeys)) + + if (pagedPublicKeys.length === 1) { + const [publicKeys] = pagedPublicKeys + + const fetchedPages = await Promise.all( + publicKeys.map(pk => Wall.getWallPage(page, pk)) + ) + + const allPosts = fetchedPages.map(fp => Object.values(fp.posts)) + const posts = R.flatten(allPosts) + // @ts-ignore + const sorted = R.sortBy((a, b) => b.date - a.date, posts) + + return sorted + } + + return [] +} + +module.exports = { + getFeedPage +} diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 2bb192fb..a21048c9 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -7,6 +7,7 @@ const Key = require('../key') const Utils = require('../utils') const Wall = require('./wall') +const Feed = require('./feed') /** * @param {string} pub @@ -94,3 +95,5 @@ module.exports.Follows = require('./follows') module.exports.getWallPage = Wall.getWallPage module.exports.getWallTotalPages = Wall.getWallTotalPages + +module.exports.getFeedPage = Feed.getFeedPage diff --git a/src/routes.js b/src/routes.js index 199f4346..0b82f7e5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1971,6 +1971,48 @@ module.exports = async ( ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPut) ap.delete(`/api/gun/follows/:publicKey`, apiGunFollowsDelete) + /** + * @type {RequestHandler<{}>} + */ + const apiGunFeedGet = async (req, res) => { + try { + const { page } = req.query; + + if (!isFinite(page)) { + return res.json(401).json({ + field: page, + errorMessage: 'page must be a number' + }) + } + + if (!isFinite(page)) { + return res.json(400).json({ + field: page, + errorMessage: 'page must be a number' + }) + } + + if (page < 1) { + return res.json(400).json({ + field: page, + errorMessage: 'page must be a positive number' + }) + } + + + + return res.status(200).json({ + posts: await GunGetters.getFeedPage(page) + }) + } catch (err) { + return res.status(500).json({ + errorMessage: err.message || 'Unknown error inside /api/gun/follows/' + }) + } + } + + ap.get(`/api/gun/feed`, apiGunFeedGet) + /** * Return app so that it can be used by express. */ From c106fd74105f608576b60b299c856f917e67df14 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 18:28:01 -0400 Subject: [PATCH 105/124] re-enable follows --- src/routes.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/routes.js b/src/routes.js index 0b82f7e5..c34fc92f 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1907,12 +1907,11 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsGet = (_, res) => { + const apiGunFollowsGet = async (_, res) => { try { - // const { publicKey } = req.params; - // const currFollows = await GunGetters.currentFollows() + const currFollows = await GunGetters.Follows.currentFollows() - return res.status(200).json({}) + return res.status(200).json(currFollows) } catch (err) { return res.status(500).json({ errorMessage: err.message || 'Unknown ERR at GET /api/follows' @@ -1924,14 +1923,14 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsPut = (req, res) => { + const apiGunFollowsPut = async (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { throw new Error(`Missing publicKey route param.`) } - // await GunActions.follow(req.params.publicKey, false) + await GunActions.follow(req.params.publicKey, false) // 201 would be extraneous here. Implement it inside app.put return res.status(200).json({ @@ -1947,14 +1946,14 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsDelete = (req, res) => { + const apiGunFollowsDelete = async (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { throw new Error(`Missing publicKey route param.`) } - // await GunActions.unfollow(req.params.publicKey) + await GunActions.unfollow(req.params.publicKey) return res.status(200).json({ ok: true From 18a3143d8f0942ce1216f3021a796ba8be32a261 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 18:47:45 -0400 Subject: [PATCH 106/124] circumvent gun.load() bug --- services/gunDB/contact-api/getters/follows.js | 73 +++++++++++-------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/services/gunDB/contact-api/getters/follows.js b/services/gunDB/contact-api/getters/follows.js index b74080fa..22a49333 100644 --- a/services/gunDB/contact-api/getters/follows.js +++ b/services/gunDB/contact-api/getters/follows.js @@ -1,6 +1,11 @@ +/** + * @format + */ const Common = require('shock-common') const Logger = require('winston') +const size = require('lodash/size') +const Utils = require('../utils') const Key = require('../key') /** @@ -8,43 +13,47 @@ const Key = require('../key') */ /** + * @throws {TypeError} * @returns {Promise>} */ -exports.currentFollows = () => { - const user = require('../../Mediator').getUser() - - return new Promise(res => { - user.get(Key.FOLLOWS).load(data => { - if (typeof data !== 'object' || data === null) { - Logger.warn( - `GunDb -> getters -> currentFollows() -> Current follows data as fetched from gun is not an object but ${typeof data}. This can happen if Gun lost its cache and it's still retrieving data from the network.` - ) - res({}) - return +exports.currentFollows = async () => { + /** + * @type {Record} + */ + const raw = await Utils.tryAndWait( + // @ts-ignore + (_, user) => new Promise(res => user.get(Key.FOLLOWS).load(res)), + v => { + if (typeof v !== 'object' || v === null) { + return true } - const rejected = Object.entries(data).filter( - ([_, follow]) => !Common.Schema.isFollow(follow) - ) + if (size(v) === 0) { + return true + } - rejected.forEach(([key, item]) => { - // expected when unfollowed - if (item !== null) { - Logger.warn( - `GunDb -> getters -> currentFollows() -> Item not conforming to schema found inside follows data. Key: ${key}, item: ${JSON.stringify( - item - )}.` - ) - } - }) + return false + } + ) - const passed = Object.entries(data).filter(([_, follow]) => - Common.Schema.isFollow(follow) - ) + if (typeof raw !== 'object' || raw === null) { + Logger.error( + `Expected user.follows to be an object but instead got: ${JSON.stringify( + raw + )}` + ) + throw new TypeError('Could not get follows, not an object') + } - const p = /** @type {unknown} */ (passed) + const clean = { + ...raw + } - res(/** @type {Record} */ (p)) - }) - }) -} \ No newline at end of file + for (const [key, followOrNull] of Object.entries(clean)) { + if (!Common.Schema.isFollow(followOrNull)) { + delete clean[key] + } + } + + return clean +} From b1515bfd9d0c63a29a15ead8a16d957ba21f0e5e Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 20:22:22 -0400 Subject: [PATCH 107/124] ensure follows sub graph is always initialized and non-empty --- services/gunDB/Mediator/index.js | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 341fcee2..f28fe0c9 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -12,6 +12,8 @@ require('gun/lib/load') const debounce = require('lodash/debounce') const Encryption = require('../../../utils/encryptionStore') +const Key = require('../contact-api/key') + /** @type {import('../contact-api/SimpleGUN').ISEA} */ // @ts-ignore const SEAx = require('gun/sea') @@ -267,6 +269,21 @@ const authenticate = async (alias, pass, __user) => { if (typeof ack.err === 'string') { throw new Error(ack.err) } else if (typeof ack.sea === 'object') { + await new Promise((res, rej) => { + _user.get(Key.FOLLOWS).put( + { + unused: null + }, + ack => { + if (ack.err) { + rej(new Error(`Error initializing follows: ${ack.err}`)) + } else { + res() + } + } + ) + }) + return ack.sea.pub } else { throw new Error('Unknown error.') @@ -279,6 +296,22 @@ const authenticate = async (alias, pass, __user) => { `Tried to re-authenticate with an alias different to that of stored one, tried: ${alias} - stored: ${_currentAlias}, logoff first if need to change aliases.` ) } + + await new Promise((res, rej) => { + _user.get(Key.FOLLOWS).put( + { + unused: null + }, + ack => { + if (ack.err) { + rej(new Error(`Error initializing follows: ${ack.err}`)) + } else { + res() + } + } + ) + }) + // move this to a subscription; implement off() ? todo API.Jobs.onAcceptedRequests(_user, mySEA) API.Jobs.onOrders(_user, gun, mySEA) @@ -312,6 +345,21 @@ const authenticate = async (alias, pass, __user) => { await new Promise(res => setTimeout(res, 5000)) + await new Promise((res, rej) => { + _user.get(Key.FOLLOWS).put( + { + unused: null + }, + ack => { + if (ack.err) { + rej(new Error(`Error initializing follows: ${ack.err}`)) + } else { + res() + } + } + ) + }) + API.Jobs.onAcceptedRequests(_user, mySEA) API.Jobs.onOrders(_user, gun, mySEA) API.Jobs.lastSeenNode(_user) From 689ac78853f101c87ac7eaee0dc4161084bd2fab Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 18:28:01 -0400 Subject: [PATCH 108/124] re-enable follows --- src/routes.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/routes.js b/src/routes.js index 5c4e99de..d925f631 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1906,12 +1906,11 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsGet = (_, res) => { + const apiGunFollowsGet = async (_, res) => { try { - // const { publicKey } = req.params; - // const currFollows = await GunGetters.currentFollows() + const currFollows = await GunGetters.Follows.currentFollows() - return res.status(200).json({}) + return res.status(200).json(currFollows) } catch (err) { return res.status(500).json({ errorMessage: err.message || 'Unknown ERR at GET /api/follows' @@ -1923,14 +1922,14 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsPut = (req, res) => { + const apiGunFollowsPut = async (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { throw new Error(`Missing publicKey route param.`) } - // await GunActions.follow(req.params.publicKey, false) + await GunActions.follow(req.params.publicKey, false) // 201 would be extraneous here. Implement it inside app.put return res.status(200).json({ @@ -1946,14 +1945,14 @@ module.exports = async ( /** * @type {RequestHandler} */ - const apiGunFollowsDelete = (req, res) => { + const apiGunFollowsDelete = async (req, res) => { try { const { publicKey } = req.params; if (!publicKey) { throw new Error(`Missing publicKey route param.`) } - // await GunActions.unfollow(req.params.publicKey) + await GunActions.unfollow(req.params.publicKey) return res.status(200).json({ ok: true From b7e66478411181bfbbe43e8dbde12f85d884ad31 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:16:47 -0400 Subject: [PATCH 109/124] use gun's nts --- services/gunDB/Mediator/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index f28fe0c9..0d164beb 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -2,6 +2,8 @@ * @format */ const Gun = require('gun') +// @ts-ignore +require('gun/nts') const logger = require('winston') // @ts-ignore Gun.log = () => {} From 782c2b916034c7194f499db03df0d145c578cfff Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:28:26 -0400 Subject: [PATCH 110/124] parse page --- src/routes.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index c34fc92f..f41b908e 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1975,7 +1975,8 @@ module.exports = async ( */ const apiGunFeedGet = async (req, res) => { try { - const { page } = req.query; + const { pageStr } = req.query; + const page = Number(pageStr) if (!isFinite(page)) { return res.json(401).json({ From 45df3ddb1e0572c8989ab2c3aa7f10f6ade88b83 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:28:47 -0400 Subject: [PATCH 111/124] actual feed getter --- services/gunDB/contact-api/getters/feed.js | 39 +++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/services/gunDB/contact-api/getters/feed.js b/services/gunDB/contact-api/getters/feed.js index 0d7a9a72..7f2593b1 100644 --- a/services/gunDB/contact-api/getters/feed.js +++ b/services/gunDB/contact-api/getters/feed.js @@ -9,6 +9,20 @@ const R = require('ramda') const Follows = require('./follows') const Wall = require('./wall') +/** + * + * @param {number} numberOfPublicKeyGroups + * @param {number} pageRequested + */ +const calculateFeedPage = (numberOfPublicKeyGroups, pageRequested) => { + // thanks to sebassdc + + return [ + ((pageRequested - 1) % numberOfPublicKeyGroups) + 1, + Math.ceil(pageRequested / numberOfPublicKeyGroups) + ] +} + /** * @param {number} page * @throws {TypeError} @@ -38,25 +52,26 @@ const getFeedPage = async page => { // page 3: page 2 from first 10 public keys // page 4: page 2 from first 10 public keys // etc + // thanks to sebassdc (github) const pagedPublicKeys = R.splitEvery(10, shuffle(subbedPublicKeys)) - if (pagedPublicKeys.length === 1) { - const [publicKeys] = pagedPublicKeys + const [publicKeyGroupIdx, pageToRequest] = calculateFeedPage( + pagedPublicKeys.length, + page + ) - const fetchedPages = await Promise.all( - publicKeys.map(pk => Wall.getWallPage(page, pk)) - ) + const publicKeys = pagedPublicKeys[publicKeyGroupIdx] - const allPosts = fetchedPages.map(fp => Object.values(fp.posts)) - const posts = R.flatten(allPosts) - // @ts-ignore - const sorted = R.sortBy((a, b) => b.date - a.date, posts) + const fetchedPages = await Promise.all( + publicKeys.map(pk => Wall.getWallPage(pageToRequest, pk)) + ) - return sorted - } + const fetchedPostsGroups = fetchedPages.map(wp => Object.values(wp.posts)) + const fetchedPosts = R.flatten(fetchedPostsGroups) + const sortered = R.sort((a, b) => b.date - a.date, fetchedPosts) - return [] + return sortered } module.exports = { From ae4e9c9b21c68191896986ead911830ec21e4313 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:31:01 -0400 Subject: [PATCH 112/124] typos --- src/routes.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/routes.js b/src/routes.js index f41b908e..d3336a11 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1979,28 +1979,19 @@ module.exports = async ( const page = Number(pageStr) if (!isFinite(page)) { - return res.json(401).json({ - field: page, - errorMessage: 'page must be a number' - }) - } - - if (!isFinite(page)) { - return res.json(400).json({ + return res.status(400).json({ field: page, errorMessage: 'page must be a number' }) } if (page < 1) { - return res.json(400).json({ + return res.status(400).json({ field: page, errorMessage: 'page must be a positive number' }) } - - return res.status(200).json({ posts: await GunGetters.getFeedPage(page) }) From 6da96122363ae0b0bb987dcc1ed864d51a5820ab Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:33:20 -0400 Subject: [PATCH 113/124] page gets autoparsed --- src/routes.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/routes.js b/src/routes.js index d3336a11..33e95424 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1975,8 +1975,7 @@ module.exports = async ( */ const apiGunFeedGet = async (req, res) => { try { - const { pageStr } = req.query; - const page = Number(pageStr) + const { page } = req.query; if (!isFinite(page)) { return res.status(400).json({ From f5eefd0afc4611fd2bfb575612280983c1757e4c Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:33:36 -0400 Subject: [PATCH 114/124] correct function --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 33e95424..3a86e1af 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1977,7 +1977,7 @@ module.exports = async ( try { const { page } = req.query; - if (!isFinite(page)) { + if (!isARealUsableNumber(page)) { return res.status(400).json({ field: page, errorMessage: 'page must be a number' From 1d59e59cf1eaee892dc4333b667073238755db5b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:45:37 -0400 Subject: [PATCH 115/124] typo --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 3a86e1af..3431eab5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1979,7 +1979,7 @@ module.exports = async ( if (!isARealUsableNumber(page)) { return res.status(400).json({ - field: page, + field: 'page', errorMessage: 'page must be a number' }) } From c9cbe2bf28c06793fab84bad92d67fa004208a13 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 21:47:52 -0400 Subject: [PATCH 116/124] has to be parsed --- src/routes.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index 3431eab5..ca80aa29 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1975,7 +1975,8 @@ module.exports = async ( */ const apiGunFeedGet = async (req, res) => { try { - const { page } = req.query; + const { pageStr } = req.query; + const page = Number(pageStr) if (!isARealUsableNumber(page)) { return res.status(400).json({ From b2e9eb616e44e364971ee685c3300db78e6e250b Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 23:00:26 -0400 Subject: [PATCH 117/124] typo --- src/routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index ca80aa29..35914618 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1975,7 +1975,7 @@ module.exports = async ( */ const apiGunFeedGet = async (req, res) => { try { - const { pageStr } = req.query; + const { page: pageStr } = req.query; const page = Number(pageStr) if (!isARealUsableNumber(page)) { From 688a4c3cdb496a61913942e2784e185a0c8b3452 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 23:25:24 -0400 Subject: [PATCH 118/124] return type --- services/gunDB/contact-api/getters/feed.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/feed.js b/services/gunDB/contact-api/getters/feed.js index 7f2593b1..c067e5cd 100644 --- a/services/gunDB/contact-api/getters/feed.js +++ b/services/gunDB/contact-api/getters/feed.js @@ -10,9 +10,9 @@ const Follows = require('./follows') const Wall = require('./wall') /** - * * @param {number} numberOfPublicKeyGroups * @param {number} pageRequested + * @returns {[ number , number ]} */ const calculateFeedPage = (numberOfPublicKeyGroups, pageRequested) => { // thanks to sebassdc From 66997a8ba09350b316e8dce4b8a4b5d4171e19a6 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 23:25:47 -0400 Subject: [PATCH 119/124] return index --- services/gunDB/contact-api/getters/feed.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/contact-api/getters/feed.js b/services/gunDB/contact-api/getters/feed.js index c067e5cd..e0cce941 100644 --- a/services/gunDB/contact-api/getters/feed.js +++ b/services/gunDB/contact-api/getters/feed.js @@ -18,7 +18,7 @@ const calculateFeedPage = (numberOfPublicKeyGroups, pageRequested) => { // thanks to sebassdc return [ - ((pageRequested - 1) % numberOfPublicKeyGroups) + 1, + (pageRequested - 1) % numberOfPublicKeyGroups, Math.ceil(pageRequested / numberOfPublicKeyGroups) ] } From 96613fc35aefa1cc56d865c27367229344505287 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 23:35:53 -0400 Subject: [PATCH 120/124] combat clock skew --- services/gunDB/Mediator/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 0d164beb..46435035 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -271,6 +271,9 @@ const authenticate = async (alias, pass, __user) => { if (typeof ack.err === 'string') { throw new Error(ack.err) } else if (typeof ack.sea === 'object') { + // clock skew + await new Promise(res => setTimeout(res, 2000)) + await new Promise((res, rej) => { _user.get(Key.FOLLOWS).put( { @@ -299,6 +302,9 @@ const authenticate = async (alias, pass, __user) => { ) } + // clock skew + await new Promise(res => setTimeout(res, 2000)) + await new Promise((res, rej) => { _user.get(Key.FOLLOWS).put( { From 5cb228e87d6f9c0f9f8864698ff7b168e3635634 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sat, 27 Jun 2020 23:35:53 -0400 Subject: [PATCH 121/124] combat clock skew --- services/gunDB/Mediator/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 0d164beb..46435035 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -271,6 +271,9 @@ const authenticate = async (alias, pass, __user) => { if (typeof ack.err === 'string') { throw new Error(ack.err) } else if (typeof ack.sea === 'object') { + // clock skew + await new Promise(res => setTimeout(res, 2000)) + await new Promise((res, rej) => { _user.get(Key.FOLLOWS).put( { @@ -299,6 +302,9 @@ const authenticate = async (alias, pass, __user) => { ) } + // clock skew + await new Promise(res => setTimeout(res, 2000)) + await new Promise((res, rej) => { _user.get(Key.FOLLOWS).put( { From 5a167cc45ccd35ab28d4eb70182764b714aa2a98 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 28 Jun 2020 00:09:17 -0400 Subject: [PATCH 122/124] alternative way of chehcking auth sucess --- services/gunDB/Mediator/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/gunDB/Mediator/index.js b/services/gunDB/Mediator/index.js index 46435035..98bafe55 100644 --- a/services/gunDB/Mediator/index.js +++ b/services/gunDB/Mediator/index.js @@ -1286,7 +1286,7 @@ const register = async (alias, pass) => { if (typeof ack.err === 'string') { throw new Error(ack.err) - } else if (typeof ack.pub === 'string') { + } else if (typeof ack.pub === 'string' || typeof user._.sea === 'object') { const mySecret = await mySEA.secret(user._.sea.epub, user._.sea) _currentAlias = alias _currentPass = await mySEA.encrypt(pass, mySecret) From e8f935b0a90834b009871689c818f3487f0f1a51 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 28 Jun 2020 06:05:25 -0400 Subject: [PATCH 123/124] include author in posts --- services/gunDB/contact-api/getters/index.js | 3 + services/gunDB/contact-api/getters/user.js | 111 ++++++++++++++++++++ services/gunDB/contact-api/getters/wall.js | 5 + 3 files changed, 119 insertions(+) create mode 100644 services/gunDB/contact-api/getters/user.js diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 2bb192fb..64b5a531 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -7,6 +7,7 @@ const Key = require('../key') const Utils = require('../utils') const Wall = require('./wall') +const User = require('./user') /** * @param {string} pub @@ -94,3 +95,5 @@ module.exports.Follows = require('./follows') module.exports.getWallPage = Wall.getWallPage module.exports.getWallTotalPages = Wall.getWallTotalPages + +module.exports.getUser = User.getAnUser diff --git a/services/gunDB/contact-api/getters/user.js b/services/gunDB/contact-api/getters/user.js new file mode 100644 index 00000000..fdcd7dfb --- /dev/null +++ b/services/gunDB/contact-api/getters/user.js @@ -0,0 +1,111 @@ +/** + * @format + */ +const Common = require('shock-common') + +const Key = require('../key') +const Utils = require('../utils') + +/** + * @param {string} publicKey + * @returns {Promise} + */ +const getAnUser = async publicKey => { + const oldProfile = await Utils.tryAndWait( + g => { + const user = g.get(`~${publicKey}`) + + return new Promise(res => user.get(Key.PROFILE).load(res)) + }, + v => typeof v !== 'object' + ) + + const bio = await Utils.tryAndWait( + g => + g + .get(`~${publicKey}`) + .get(Key.BIO) + .then(), + v => typeof v !== 'string' + ) + + const lastSeenApp = await Utils.tryAndWait( + g => + g + .get(`~${publicKey}`) + .get(Key.LAST_SEEN_APP) + .then(), + v => typeof v !== 'number' + ) + + const lastSeenNode = await Utils.tryAndWait( + (_, user) => user.get(Key.LAST_SEEN_NODE).then(), + v => typeof v !== 'number' + ) + + /** @type {Common.SchemaTypes.User} */ + const u = { + avatar: oldProfile.avatar, + // @ts-ignore + bio, + displayName: oldProfile.displayName, + // @ts-ignore + lastSeenApp, + // @ts-ignore + lastSeenNode, + // @ts-ignore + publicKey + } + + return u +} + +module.exports.getAnUser = getAnUser + +/** + * @returns {Promise} + */ +const getMyUser = async () => { + const oldProfile = await Utils.tryAndWait( + (_, user) => new Promise(res => user.get(Key.PROFILE).load(res)), + v => typeof v !== 'object' + ) + + const bio = await Utils.tryAndWait( + (_, user) => user.get(Key.BIO).then(), + v => typeof v !== 'string' + ) + + const lastSeenApp = await Utils.tryAndWait( + (_, user) => user.get(Key.LAST_SEEN_APP).then(), + v => typeof v !== 'number' + ) + + const lastSeenNode = await Utils.tryAndWait( + (_, user) => user.get(Key.LAST_SEEN_NODE).then(), + v => typeof v !== 'number' + ) + + const publicKey = await Utils.tryAndWait( + (_, user) => Promise.resolve(user.is && user.is.pub), + v => typeof v !== 'string' + ) + + /** @type {Common.SchemaTypes.User} */ + const u = { + avatar: oldProfile.avatar, + // @ts-ignore + bio, + displayName: oldProfile.displayName, + // @ts-ignore + lastSeenApp, + // @ts-ignore + lastSeenNode, + // @ts-ignore + publicKey + } + + return u +} + +module.exports.getMyUser = getMyUser diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 25a0b004..0c0b19d7 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -2,9 +2,12 @@ * @format */ const Common = require('shock-common') + const Utils = require('../utils') const Key = require('../key') +const Wall = require('./user') + /** * @returns {Promise} */ @@ -95,6 +98,8 @@ const getWallPage = async page => { if (post === null) { delete clean.posts[key] } else { + // eslint-disable-next-line no-await-in-loop + post.author = await Wall.getMyUser() post.id = key } } From 5cce69fb75991b9cea882806e632d5e34648c729 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 28 Jun 2020 06:15:17 -0400 Subject: [PATCH 124/124] get third party user for posts --- services/gunDB/contact-api/getters/wall.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/services/gunDB/contact-api/getters/wall.js b/services/gunDB/contact-api/getters/wall.js index 77b82dfe..f639780e 100644 --- a/services/gunDB/contact-api/getters/wall.js +++ b/services/gunDB/contact-api/getters/wall.js @@ -107,8 +107,11 @@ const getWallPage = async (page, publicKey) => { delete clean.posts[key] clean.count-- } else { - // eslint-disable-next-line no-await-in-loop - post.author = await Wall.getMyUser() + post.author = publicKey + ? // eslint-disable-next-line no-await-in-loop + await Wall.getAnUser(publicKey) + : // eslint-disable-next-line no-await-in-loop + await Wall.getMyUser() post.id = key } }