diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 9312f864..4433c150 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -752,162 +752,6 @@ const createPostNew = async (tags, title, content) => { return [postID, newPost] } -/** - * @param {string[]} tags - * @param {string} title - * @param {Common.Schema.ContentItem[]} content - * @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 numOfPages = await (async () => { - const maybeNumOfPages = await Utils.tryAndWait( - (_, user) => - user - .get(Key.WALL) - .get(Key.NUM_OF_PAGES) - .then(), - v => typeof v !== 'number' - ) - - if (typeof maybeNumOfPages !== 'number') { - throw new TypeError( - `Could not fetch number of pages from wall, instead got: ${JSON.stringify( - maybeNumOfPages - )}` - ) - } - - return maybeNumOfPages - })() - - let pageIdx = Math.max(0, numOfPages - 1).toString() - - 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 - - if (shouldBeNewPage) { - pageIdx = Number(pageIdx + 1).toString() - } - - await /** @type {Promise} */ (new Promise((res, rej) => { - require('../Mediator') - .getUser() - .get(Key.WALL) - .get(Key.PAGES) - .get(pageIdx) - .put( - { - [Key.COUNT]: shouldBeNewPage ? 1 : count + 1, - posts: { - unused: null - } - }, - ack => { - if (ack.err && typeof ack.err !== 'number') { - rej(new Error(ack.err)) - } - - res() - } - ) - })) - - const [postID, newPost] = await createPostNew(tags, title, content) - - await Common.makePromise((res, rej) => { - require('../Mediator') - .getUser() - .get(Key.WALL) - .get(Key.PAGES) - .get(pageIdx) - .get(Key.POSTS) - .get(postID) - .put( - // @ts-expect-error - newPost, - ack => { - if (ack.err && typeof ack.err !== 'number') { - rej(new Error(ack.err)) - } else { - res() - } - } - ) - }) - - if (shouldBeNewPage || numOfPages === 0) { - await /** @type {Promise} */ (new Promise(res => { - require('../Mediator') - .getUser() - .get(Key.WALL) - .get(Key.NUM_OF_PAGES) - .put(numOfPages + 1, ack => { - if (ack.err && typeof ack.err !== 'number') { - throw new Error(ack.err) - } - - res() - }) - })) - } - - const loadedPost = await new Promise(res => { - require('../Mediator') - .getUser() - .get(Key.WALL) - .get(Key.PAGES) - .get(pageIdx) - .get(Key.POSTS) - .get(postID) - .load(data => { - res(data) - }) - }) - - /** @type {Common.Schema.User} */ - const userForPost = await Getters.getMyUser() - - /** @type {Common.Schema.Post} */ - const completePost = { - ...loadedPost, - author: userForPost, - id: postID - } - - if (!Common.Schema.isPost(completePost)) { - throw new Error( - `completePost not a Post inside Actions.createPost(): ${JSON.stringify( - completePost - )}` - ) - } - - return completePost -} - /** * @param {string} postId * @param {string} page @@ -1058,7 +902,6 @@ module.exports = { saveSeedBackup, saveChannelsBackup, setLastSeenApp, - createPost, deletePost, follow, unfollow, diff --git a/services/gunDB/contact-api/getters/feed.js b/services/gunDB/contact-api/getters/feed.js deleted file mode 100644 index ba4704ce..00000000 --- a/services/gunDB/contact-api/getters/feed.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @format - */ -//@ts-ignore -const Common = require('shock-common') -const isFinite = require('lodash/isFinite') -const shuffle = require('lodash/shuffle') -const R = require('ramda') - -const { asyncFilter } = require('../../../../utils') - -const Follows = require('./follows') -const Wall = require('./wall') - -/** - * @param {number} numberOfPublicKeyGroups - * @param {number} pageRequested - * @returns {[ number , number ]} - */ -const calculateWallRequest = (numberOfPublicKeyGroups, pageRequested) => { - // thanks to sebassdc - - return [ - (pageRequested - 1) % numberOfPublicKeyGroups, - Math.ceil(pageRequested / numberOfPublicKeyGroups) - ] -} - -/** - * @param {number} page - * @throws {TypeError} - * @throws {RangeError} - * @returns {Promise} - */ -//@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 - // thanks to sebassdc (github) - - const pagedPublicKeys = R.splitEvery(10, shuffle(subbedPublicKeys)) - - const [publicKeyGroupIdx, pageToRequest] = calculateWallRequest( - pagedPublicKeys.length, - page - ) - - const publicKeysRaw = pagedPublicKeys[publicKeyGroupIdx] - const publicKeys = await asyncFilter( - publicKeysRaw, - // reject public keys for which the page to request would result in an out - // of bounds error - async pk => pageToRequest <= (await Wall.getWallTotalPages(pk)) - ) - - const fetchedPages = await Promise.all( - publicKeys.map(pk => Wall.getWallPage(pageToRequest, pk)) - ) - - 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 sortered -} - -module.exports = { - getFeedPage -} diff --git a/services/gunDB/contact-api/getters/follows.js b/services/gunDB/contact-api/getters/follows.js deleted file mode 100644 index e7972276..00000000 --- a/services/gunDB/contact-api/getters/follows.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @format - */ -const Common = require('shock-common') -const Logger = require('../../../../config/log') -const size = require('lodash/size') - -const Utils = require('../utils') -const Key = require('../key') - -/** - * @typedef {Common.Schema.Follow} Follow - */ - -/** - * @throws {TypeError} - * @returns {Promise>} - */ -exports.currentFollows = async () => { - /** - * @type {Record} - */ - const raw = await Utils.tryAndWait( - (_, user) => - new Promise(res => - // @ts-expect-error - user.get(Key.FOLLOWS).load(res) - ), - v => { - if (typeof v !== 'object' || v === null) { - return true - } - - // load sometimes returns an empty set on the first try - if (size(v) === 0) { - return true - } - - // sometimes it returns empty sub objects - return Object.values(v) - .filter(Common.Schema.isObj) - .some(obj => size(obj) === 0) - } - ) - - 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 clean = { - ...raw - } - - for (const [key, followOrNull] of Object.entries(clean)) { - if (!Common.Schema.isFollow(followOrNull)) { - delete clean[key] - } - } - - return clean -} diff --git a/services/gunDB/contact-api/getters/index.js b/services/gunDB/contact-api/getters/index.js index 81ea8dc2..d5e198b6 100644 --- a/services/gunDB/contact-api/getters/index.js +++ b/services/gunDB/contact-api/getters/index.js @@ -1,16 +1,10 @@ /** * @format */ -const Common = require('shock-common') const Key = require('../key') const Utils = require('../utils') -const Wall = require('./wall') -const Feed = require('./feed') -const User = require('./user') -const { size } = require('lodash') - /** * @param {string} pub * @returns {Promise} @@ -29,118 +23,3 @@ exports.currentOrderAddress = async pub => { 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 -} - -/** - * @returns {Promise} - */ -//@returns {Promise} -const getMyUser = async () => { - const oldProfile = await Utils.tryAndWait( - (_, user) => new Promise(res => user.get(Key.PROFILE).load(res)), - v => { - if (typeof v !== 'object') { - return true - } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - } - ) - - 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' - ) - //@ts-ignore - /** @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 -} -/** - * @param {string} publicKey - */ -const getUserInfo = async publicKey => { - const userInfo = await Utils.tryAndWait( - gun => - new Promise(res => - gun - .user(publicKey) - .get(Key.PROFILE) - .load(res) - ), - v => { - if (typeof v !== 'object') { - return true - } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - } - ) - return { - publicKey, - avatar: userInfo.avatar, - displayName: userInfo.displayName - } -} - -module.exports.getMyUser = getMyUser -module.exports.getUserInfo = getUserInfo -module.exports.Follows = require('./follows') - -module.exports.getWallPage = Wall.getWallPage -module.exports.getWallTotalPages = Wall.getWallTotalPages - -module.exports.getFeedPage = Feed.getFeedPage -module.exports.getAnUser = User.getAnUser diff --git a/services/gunDB/contact-api/getters/user.js b/services/gunDB/contact-api/getters/user.js deleted file mode 100644 index f560d65c..00000000 --- a/services/gunDB/contact-api/getters/user.js +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @format - */ -const Common = require('shock-common') -const size = require('lodash/size') - -const Key = require('../key') -const Utils = require('../utils') - -/** - * @param {string} publicKey - * @returns {Promise} - */ -//@returns {Promise} -const getAnUser = async publicKey => { - const oldProfile = await Utils.tryAndWait( - (g, u) => { - const user = u._.sea.pub === publicKey ? u : g.user(publicKey) - - return new Promise(res => user.get(Key.PROFILE).load(res)) - }, - v => typeof v !== 'object' - ) - - const bio = await Utils.tryAndWait( - (g, u) => { - const user = u._.sea.pub === publicKey ? u : g.user(publicKey) - - return user.get(Key.BIO).then() - }, - v => typeof v !== 'string' - ) - - const lastSeenApp = await Utils.tryAndWait( - (g, u) => { - const user = u._.sea.pub === publicKey ? u : g.user(publicKey) - - return user.get(Key.LAST_SEEN_APP).then() - }, - v => typeof v !== 'number' - ) - - const lastSeenNode = await Utils.tryAndWait( - (g, u) => { - const user = u._.sea.pub === publicKey ? u : g.user(publicKey) - - return user.get(Key.LAST_SEEN_NODE).then() - }, - v => typeof v !== 'number' - ) - //@ts-ignore - /** @type {Common.SchemaTypes.User} */ - const u = { - avatar: oldProfile.avatar || null, - // @ts-ignore - bio: bio || null, - displayName: oldProfile.displayName || null, - // @ts-ignore - lastSeenApp: lastSeenApp || 0, - // @ts-ignore - lastSeenNode: lastSeenNode || 0, - // @ts-ignore - publicKey - } - - return u -} - -module.exports.getAnUser = getAnUser - -/** - * @returns {Promise} - */ -//@returns {Promise} -const getMyUser = async () => { - const oldProfile = await Utils.tryAndWait( - (_, user) => new Promise(res => user.get(Key.PROFILE).load(res)), - v => { - if (typeof v !== 'object') { - return true - } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - } - ) - - 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' - ) - //@ts-ignore - /** @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 deleted file mode 100644 index 96c7fd70..00000000 --- a/services/gunDB/contact-api/getters/wall.js +++ /dev/null @@ -1,208 +0,0 @@ -/** - * @format - */ -const Common = require('shock-common') -const pickBy = require('lodash/pickBy') -const size = require('lodash/size') -const mapValues = require('lodash/mapValues') - -const Utils = require('../utils') -const Key = require('../key') - -const User = require('./user') - -/** - * @param {string=} publicKey - * @returns {Promise} - */ -const getWallTotalPages = async publicKey => { - const totalPages = await Utils.tryAndWait( - (gun, u) => { - /** - * @type {import('../SimpleGUN').GUNNode} - */ - let user = u - - if (publicKey && u._.sea.pub !== publicKey) { - user = gun.user(publicKey) - } - - return user - .get(Key.WALL) - .get(Key.NUM_OF_PAGES) - .then() - }, - v => typeof v !== 'number' - ) - - return typeof totalPages === 'number' ? totalPages : 0 -} - -/** - * @param {number} page - * @param {string=} publicKey - * @throws {TypeError} - * @throws {RangeError} - * @returns {Promise} - */ -////@returns {Promise} -const getWallPage = async (page, publicKey) => { - const totalPages = await getWallTotalPages(publicKey) - - if (page === 0) { - throw new RangeError( - `Page number cannot be zero, only positive and negative integers are allowed.` - ) - } - - const empty = { - count: 0, - posts: {} - } - - if (totalPages === 0) { - return empty - } - - const actualPageIdx = page < 0 ? totalPages + page : page - 1 - - if (actualPageIdx > totalPages - 1) { - throw new RangeError(`Requested a page out of bounds`) - } - - /** - * @type {number} - */ - // @ts-ignore - const count = await Utils.tryAndWait( - (g, u) => { - /** - * @type {import('../SimpleGUN').GUNNode} - */ - let user = u - - if (publicKey && u._.sea.pub !== publicKey) { - user = g.user(publicKey) - } - - return user - .get(Key.WALL) - .get(Key.PAGES) - .get(actualPageIdx.toString()) - .get(Key.COUNT) - .then() - }, - v => typeof v !== 'number' - ) - - if (count === 0) { - return empty - } - - /** - * We just use it so Common.Schema.isWallPage passes. - */ - const mockUser = await User.getMyUser() - - /* - * @type {Common.SchemaTypes.WallPage} - */ - //@ts-ignore - const thePage = await Utils.tryAndWait( - (g, u) => { - /** - * @type {import('../SimpleGUN').GUNNode} - */ - let user = u - - if (publicKey && u._.sea.pub !== publicKey) { - user = g.user(publicKey) - } - - return new Promise(res => { - // forces data fetch - user - .get(Key.WALL) - .get(Key.PAGES) - .get(actualPageIdx.toString()) - // @ts-ignore - .load(() => {}) - - process.nextTick(() => { - user - .get(Key.WALL) - .get(Key.PAGES) - .get(actualPageIdx.toString()) - // @ts-ignore - .load(res) - }) - }) - }, - maybePage => { - // sometimes load() returns an empty object on the first call - if (size(/** @type {any} */ (maybePage)) === 0) { - return true - } - - const page = /** @type {Common.Schema.WallPage} */ (maybePage) - - if (typeof page.count !== 'number') { - return true - } - - // removes 'unused' initializer and aborted writes - page.posts = pickBy(page.posts, v => v !== null) - - // .load() sometimes doesn't load all data on first call - if (size(page.posts) === 0) { - return true - } - - // Give ids based on keys - page.posts = mapValues(page.posts, (v, k) => ({ - ...v, - id: k - })) - - page.posts = mapValues(page.posts, v => ({ - ...v, - // isWallPage() would otherwise not pass - author: mockUser - })) - - return !Common.Schema.isWallPage(page) - } - ) - - const clean = { - ...thePage - } - - for (const [key, post] of Object.entries(clean.posts)) { - // delete unsuccessful writes - if (post === null) { - delete clean.posts[key] - clean.count-- - } else { - post.author = publicKey - ? // eslint-disable-next-line no-await-in-loop - await User.getAnUser(publicKey) - : // eslint-disable-next-line no-await-in-loop - await User.getMyUser() - post.id = key - } - } - - if (!Common.Schema.isWallPage(clean)) { - throw new Error( - `Fetched page not a wall page, instead got: ${JSON.stringify(clean)}` - ) - } - - return clean -} - -module.exports = { - getWallTotalPages, - getWallPage -} diff --git a/services/gunDB/contact-api/utils/index.js b/services/gunDB/contact-api/utils/index.js index d1fd34f9..fb6963bf 100644 --- a/services/gunDB/contact-api/utils/index.js +++ b/services/gunDB/contact-api/utils/index.js @@ -196,6 +196,7 @@ const pubToEpub = async pub => { return epub } catch (err) { + logger.error(`Error inside pubToEpub:`) logger.error(err) throw new Error(`pubToEpub() -> ${err.message}`) } diff --git a/src/routes.js b/src/routes.js index 27879828..ff0fd167 100644 --- a/src/routes.js +++ b/src/routes.js @@ -50,8 +50,6 @@ module.exports = async ( { serverPort, CA, CA_KEY, usetls } ) => { try { - const { timeout5 } = require('../services/gunDB/contact-api/utils') - const Http = Axios.create({ httpsAgent: new httpsAgent.Agent({ ca: await FS.readFile(CA) @@ -2109,7 +2107,7 @@ module.exports = async ( const SEA = require('../services/gunDB/Mediator').mySEA const mySecret = require('../services/gunDB/Mediator').getMySecret() - const encBackup = await timeout5(user.get(Key.CHANNELS_BACKUP).then()) + const encBackup = await user.get(Key.CHANNELS_BACKUP).then() const backup = await SEA.decrypt(encBackup, mySecret) logger.info(backup) res.json({ data: backup }) @@ -2117,88 +2115,7 @@ 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_DISPLAY_NAME}`, async (_, res) => { - try { - const user = require('../services/gunDB/Mediator').getUser() - const data = await timeout5( - user - .get(Key.PROFILE) - .get(Key.DISPLAY_NAME) - .then() - ) - res.json({ - data - }) - } catch (err) { - logger.info('Error in Display Name poll:') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: typeof err === 'string' ? err : err.message - }) - } - }) - - app.get(`/api/gun/${GunEvent.ON_HANDSHAKE_ADDRESS}`, async (_, res) => { - try { - const user = require('../services/gunDB/Mediator').getUser() - const data = await timeout5( - user.get(Key.CURRENT_HANDSHAKE_ADDRESS).then() - ) - res.json({ - data - }) - } catch (err) { - logger.info('Error in Handshake Address poll:') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: typeof err === 'string' ? err : err.message - }) - } - }) - - app.get(`/api/gun/${GunEvent.ON_BIO}`, async (_, res) => { - try { - const user = require('../services/gunDB/Mediator').getUser() - const data = await timeout5(user.get(Key.BIO).then()) - logger.debug(data) - res.json({ - data - }) - } catch (err) { - logger.info('Error in BIO poll:') - logger.error(err) - res - .status( - err.message === Common.Constants.ErrorCode.NOT_AUTH ? 401 : 500 - ) - .json({ - errorMessage: typeof err === 'string' ? err : err.message - }) - } - }) //////////////////////////////////////////////////////////////////////////////// app.post(`/api/gun/sendpayment`, async (req, res) => { @@ -2248,41 +2165,6 @@ module.exports = async ( } }) - app.get(`/api/gun/wall/:publicKey?`, async (req, res) => { - try { - const { page } = req.query - const { publicKey } = req.params - - const pageNum = Number(page) - - if (!isARealUsableNumber(pageNum)) { - return res.status(400).json({ - field: 'page', - errorMessage: 'Not a number' - }) - } - - if (pageNum === 0) { - return res.status(400).json({ - field: 'page', - errorMessage: 'Page must be a non-zero integer' - }) - } - - const totalPages = await GunGetters.getWallTotalPages(publicKey) - const fetchedPage = await GunGetters.getWallPage(pageNum, publicKey) - - return res.status(200).json({ - ...fetchedPage, - totalPages - }) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message - }) - } - }) - app.post(`/api/gun/wall/`, async (req, res) => { try { const { tags, title, contentItems, enableTipsOverlay } = req.body @@ -2328,27 +2210,6 @@ module.exports = async ( } }) - app.post(`/api/gun/userInfo`, async (req, res) => { - try { - const { pubs } = req.body - const reqs = pubs.map( - e => - new Promise((res, rej) => { - GunGetters.getUserInfo(e) - .then(r => res(r)) - .catch(e => rej(e)) - }) - ) - const infos = await Promise.all(reqs) - return res.status(200).json({ - pubInfos: infos - }) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message - }) - } - }) ///////////////////////////////// /** * @template P @@ -2362,21 +2223,6 @@ module.exports = async ( * @prop {(string|undefined)=} publicKey */ - /** - * @type {RequestHandler} - */ - const apiGunFollowsGet = async (_, res) => { - try { - const currFollows = await GunGetters.Follows.currentFollows() - - return res.status(200).json(currFollows) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message || 'Unknown ERR at GET /api/follows' - }) - } - } - /** * @type {RequestHandler} */ @@ -2433,109 +2279,9 @@ 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) - /** - * @type {RequestHandler<{}>} - */ - const apiGunFeedGet = async (req, res) => { - try { - const MAX_PAGES_TO_FETCH_FOR_TRY_UNTIL = 4 - - const { page: pageStr } = req.query - - /** - * Similar to a "before" query param in cursor based pagination. We call - * it "try" because it is likely that this item lies beyond - * MAX_PAGES_TO_FETCH_FOR_TRY_UNTIL in which case we gracefully just send - * 2 pages and 205 response. - */ - // eslint-disable-next-line prefer-destructuring - const before = req.query.before - - if (pageStr) { - const page = Number(pageStr) - - if (!isARealUsableNumber(page)) { - return res.status(400).json({ - field: 'page', - errorMessage: 'page must be a number' - }) - } - - if (page < 1) { - return res.status(400).json({ - field: page, - errorMessage: 'page must be a positive number' - }) - } - - return res.status(200).json({ - posts: await GunGetters.getFeedPage(page), - page - }) - } - - if (before) { - const pages = range(1, MAX_PAGES_TO_FETCH_FOR_TRY_UNTIL) - const promises = pages.map(p => GunGetters.getFeedPage(p)) - - let results = await Promise.all(promises) - - const idxIfFound = results.findIndex(pp => - pp.some(p => p.id === before) - ) - - if (idxIfFound > -1) { - results = results.slice(0, idxIfFound + 1) - - const posts = flatten(results) - - return res.status(200).json({ - posts, - page: idxIfFound - }) - } - - // we couldn't find the posts leading up to the requested post - // (try_until) Let's just return the ones we found with together with a - // 205 code (client should refresh UI) - - return res.status(205).json({ - posts: results[0] || [], - page: 1 - }) - } - - return res.status(400).json({ - errorMessage: `Must provide at least a page or a try_until query param.` - }) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message || 'Unknown error inside /api/gun/follows/' - }) - } - } - - ap.get(`/api/gun/feed`, apiGunFeedGet) - - /** - * @type {RequestHandler<{}>} - */ - const apiGunMeGet = async (_, res) => { - try { - return res.status(200).json(await GunGetters.getMyUser()) - } catch (err) { - logger.error(err) - return res.status(500).json({ - errorMessage: err.message - }) - } - } - /** * @type {RequestHandler<{}>} */ @@ -2589,102 +2335,8 @@ module.exports = async ( } } - ap.get(`/api/gun/me`, apiGunMeGet) ap.put(`/api/gun/me`, apiGunMePut) - ap.get(`/api/gun/dev/currentHandshakeAddress`, async (_, res) => { - try { - const { tryAndWait } = require('../services/gunDB/contact-api/utils') - - const data = await tryAndWait((_, u) => - u.get(GunKey.CURRENT_HANDSHAKE_ADDRESS).then() - ) - - return res.status(200).json({ - data - }) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message - }) - } - }) - - ap.get( - `/api/gun/dev/handshakeNodes/:handshakeAddress`, - async (req, res) => { - try { - const { tryAndWait } = require('../services/gunDB/contact-api/utils') - - const data = await tryAndWait( - g => - new Promise(res => { - g.get(GunKey.HANDSHAKE_NODES) - .get(req.params.handshakeAddress) - .load(data => { - res(data) - }) - }), - v => { - if (typeof v !== 'object') { - return true - } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - } - ) - - return res.status(200).json({ - data - }) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message - }) - } - } - ) - - ap.get(`/api/gun/dev/user/:publicKey`, async (req, res) => { - try { - const { tryAndWait } = require('../services/gunDB/contact-api/utils') - - const data = await tryAndWait( - g => - new Promise(res => { - g.user(req.params.publicKey).load(data => { - res(data) - }) - }), - v => { - if (typeof v !== 'object') { - return true - } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - } - ) - - return res.status(200).json({ - data - }) - } catch (err) { - return res.status(500).json({ - errorMessage: err.message - }) - } - }) - ap.get(`/api/gun/auth`, (_, res) => { const { isAuthenticated } = require('../services/gunDB/Mediator')