From 8d1aae0ac37f29e758951e72036e63c89e1e67ce Mon Sep 17 00:00:00 2001 From: boufni95 Date: Fri, 12 Jun 2020 19:03:43 +0200 Subject: [PATCH 01/50] 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 02/50] 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 4f667cc6c1b11e7e42dbed37f75dd8cb62ca00b6 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 16 Jun 2020 11:58:06 -0400 Subject: [PATCH 03/50] 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 04/50] 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 05/50] 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 06/50] 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 07/50] 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 08/50] 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 09/50] 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 10/50] 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 11/50] 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 12/50] 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 d3ca2182e08b7eef71fcfc880b808c4c0fc4c4eb Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Tue, 23 Jun 2020 15:23:29 -0400 Subject: [PATCH 13/50] 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 14/50] 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 15/50] 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 16/50] 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 17/50] 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 18/50] 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 19/50] 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 20/50] 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 21/50] 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 22/50] 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 23/50] 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 24/50] 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 25/50] 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 26/50] 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 27/50] 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 28/50] 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 29/50] 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 30/50] 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 31/50] 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 32/50] 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 33/50] 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 34/50] 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 35/50] 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 36/50] 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 37/50] 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 38/50] 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 39/50] 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 40/50] 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 41/50] 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 42/50] 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 43/50] 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 44/50] 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 552e625e5fd13aee1a6a5805c1c0489343df6e53 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Thu, 25 Jun 2020 18:45:31 -0400 Subject: [PATCH 45/50] 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 46/50] 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 47/50] 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 48/50] 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 49/50] 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 50/50] 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) } )