From 24a7712ac45222142a81b0714e743e89f2bbcce9 Mon Sep 17 00:00:00 2001 From: Val Date: Mon, 3 May 2021 19:28:05 +0200 Subject: [PATCH 1/5] removes admin auth for getting all pages through api --- lib/modules/apostrophe-pages-headless/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/modules/apostrophe-pages-headless/index.js b/lib/modules/apostrophe-pages-headless/index.js index 598b87a..d505fd9 100644 --- a/lib/modules/apostrophe-pages-headless/index.js +++ b/lib/modules/apostrophe-pages-headless/index.js @@ -19,10 +19,8 @@ module.exports = { self.apos.app.get(endpoint, function(req, res) { var all = self.apos.launder.boolean(req.query.all); var flat = self.apos.launder.boolean(req.query.flat); + if (all) { - if (!self.apos.permissions.can(req, 'admin-apostrophe-page')) { - return res.status(403).send({ error: 'forbidden' }); - } // TODO lifted far too much code from the jqtree route, // refactor to share code. However note property name differences return self.findForRestApi(req).and({ level: 0 }).children({ From 3a735a6a403e042427ad8889bf41d2bfc6102b05 Mon Sep 17 00:00:00 2001 From: Val Date: Tue, 4 May 2021 14:07:11 +0200 Subject: [PATCH 2/5] asks for edit permissions only if no apiKeys set --- lib/modules/apostrophe-pages-headless/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/apostrophe-pages-headless/index.js b/lib/modules/apostrophe-pages-headless/index.js index d505fd9..2b8e911 100644 --- a/lib/modules/apostrophe-pages-headless/index.js +++ b/lib/modules/apostrophe-pages-headless/index.js @@ -452,7 +452,7 @@ module.exports = { .children(includeChildren) .published(null); - if (options.restApi.getRequiresEditPermission) { + if (options.restApi.getRequiresEditPermission && !options.apiKeys) { cursor.permission('edit'); } return cursor; From ef7e7b26f6323e17e1e1fce40b25ce075cf5bcfb Mon Sep 17 00:00:00 2001 From: Val Date: Tue, 4 May 2021 22:50:54 +0200 Subject: [PATCH 3/5] refacto to remove duplicate code --- .../apostrophe-pages-headless/index.js | 175 +++++++++--------- 1 file changed, 84 insertions(+), 91 deletions(-) diff --git a/lib/modules/apostrophe-pages-headless/index.js b/lib/modules/apostrophe-pages-headless/index.js index 2b8e911..62ff9bb 100644 --- a/lib/modules/apostrophe-pages-headless/index.js +++ b/lib/modules/apostrophe-pages-headless/index.js @@ -8,117 +8,110 @@ module.exports = { construct: function(self, options) { self.addRestApiRoutes = function() { - var restApi = self.apos.modules['apostrophe-headless']; + const restApi = self.apos.modules['apostrophe-headless']; if ((!options.restApi) || (options.restApi.enabled === false)) { return; } - var baseEndpoint = restApi.endpoint; - var endpoint = baseEndpoint + '/' + (options.restApi.name || self.__meta.name); + const baseEndpoint = restApi.endpoint; + const endpoint = baseEndpoint + '/' + (options.restApi.name || self.__meta.name); // GET home or tree - self.apos.app.get(endpoint, function(req, res) { - var all = self.apos.launder.boolean(req.query.all); - var flat = self.apos.launder.boolean(req.query.flat); - - if (all) { - // TODO lifted far too much code from the jqtree route, - // refactor to share code. However note property name differences - return self.findForRestApi(req).and({ level: 0 }).children({ - depth: 1000, - published: null, - trash: false, - orphan: null, - joins: false, - areas: false, - permission: false - }).toObject(function(err, page) { + self.apos.app.get(endpoint, async function(req, res) { + const all = self.apos.launder.boolean(req.query.all); + const flat = self.apos.launder.boolean(req.query.flat); + + const childrenOptions = { + depth: 1000, + published: null, + trash: false, + orphan: null, + joins: false, + areas: false, + permission: false + }; + + try { + const home = all + ? await self.findForRestApi(req).and({ level: 0 }).children(childrenOptions).toObject() + : await self.findForRestApi(req).and({ level: 0 }).toObject(); + + if (!home) { + return res.status(404).send({ error: 'notfound' }); + } + + // const data = options.apiKeys ? [ page ] : clean([ page ]); + const data = clean([ home ]); + + const dataTosend = flat ? flatten(data[0]) : data[0]; + + if (all) { + return res.send(dataTosend); + } + + // Attach `_url` and `_urls` properties + self.apos.attachments.all(dataTosend, { annotate: true }); + + render(dataTosend, (err) => { if (err) { self.apos.utils.error(err); return res.status(500).send({ error: 'error' }); } + return res.send(dataTosend); + }); + } catch (err) { + self.apos.utils.error(err); + return res.status(500).send({ error: 'error' }); + } - if (!page) { - return res.status(404).send({ error: 'notfound' }); - } - - var data = [ page ]; - - // Prune pages we can't reorganize - data = clean(data); - if (flat) { - var result = []; - flatten(result, data[0]); - return res.send(result); - } - return res.send(data[0]); - - // If I can't publish at least one of a node's - // descendants, prune it from the tree. Returns - // a pruned version of the tree - - function clean(nodes) { - mark(nodes, []); - return prune(nodes); - function mark(nodes, ancestors) { - _.each(nodes, function(node) { - if (node._publish) { - node.good = true; - _.each(ancestors, function(ancestor) { - ancestor.good = true; - }); - } - mark(node._children || [], ancestors.concat([ node ])); + function clean(nodes) { + mark(nodes, []); + return prune(nodes); + function mark(nodes, ancestors) { + _.each(nodes, function(node) { + if (node._publish) { + node.good = true; + _.each(ancestors, function(ancestor) { + ancestor.good = true; }); } - function prune(nodes) { - var newNodes = []; - _.each(nodes, function(node) { - node._children = prune(node._children || []); - if (node.good) { - newNodes.push(_.pick(node, 'title', 'slug', '_id', 'type', 'tags', '_url', '_children')); - } - }); - return newNodes; + mark(node._children || [], ancestors.concat([ node ])); + }); + } + + function prune(nodes) { + var newNodes = []; + _.each(nodes, function(node) { + node._children = prune(node._children || []); + if (node.good) { + newNodes.push(_.pick(node, 'title', 'slug', '_id', 'type', 'tags', '_url', '_children')); } + }); + return newNodes; + } + } - } - function flatten(result, node) { - var children = node._children; - node._children = _.map(node._children, '_id'); - result.push(node); - _.each(children || [], function(child) { - flatten(result, child); - }); - } - }); + function flatten(node) { + return parseChildren([], node); - } - var result; - return async.series([ findPages, render ], function(err) { - if (err) { - self.apos.utils.error(err); - return res.status(500).send({ error: 'error' }); - } - return res.send(result); - }); + function parseChildren (result, item) { + const children = item._children || []; + const data = { + ...item, + _children: (item._children || []).map((child) => child._id) + }; - function findPages(callback) { - return self.findForRestApi(req).and({ level: 0 }).toObject(function(err, home) { - if (err) { - return callback(err); - } - // Attach `_url` and `_urls` properties - self.apos.attachments.all(home, { annotate: true }); - result = home; - return callback(null); - }); + result.push(data); + + children.reduce(parseChildren, result); + + return result; + } } - function render(callback) { + function render(result, callback) { var restApi = self.apos.modules['apostrophe-headless']; return restApi.apiRender(req, self, result, 'page', callback); } - }); // GET one @@ -452,7 +445,7 @@ module.exports = { .children(includeChildren) .published(null); - if (options.restApi.getRequiresEditPermission && !options.apiKeys) { + if (options.restApi.getRequiresEditPermission) { cursor.permission('edit'); } return cursor; From 36eb1a9cfcfc6f963db74f75ed809f465f2db837 Mon Sep 17 00:00:00 2001 From: Val Date: Tue, 4 May 2021 23:48:42 +0200 Subject: [PATCH 4/5] minor changes --- index.js | 9 ++++++--- lib/modules/apostrophe-pages-headless/index.js | 12 +++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index c270252..e22ff45 100644 --- a/index.js +++ b/index.js @@ -232,13 +232,13 @@ module.exports = { }; self.apiKeyMiddleware = function(req, res, next) { - if (req.url.substr(0, self.endpoint.length + 1) !== (self.endpoint + '/')) { return next(); } - var key = req.query.apikey || req.query.apiKey || getAuthorizationApiKey(); - var taskReq; + const key = req.query.apikey || getAuthorizationApiKey(); + + let taskReq; if (!key) { return next(); } @@ -247,11 +247,13 @@ module.exports = { taskReq = self.apos.tasks.getReq(); req.user = taskReq.user; req.csrfExempt = true; + return next(); } else { var module = _.find(self.registeredModules, function(module) { return _.includes(module.options.apiKeys, key); }); + if (module) { taskReq = self.apos.tasks.getReq(); req.user = taskReq.user; @@ -264,6 +266,7 @@ module.exports = { req.user._permissions['admin-' + module.name] = true; } req.csrfExempt = true; + return next(); } } diff --git a/lib/modules/apostrophe-pages-headless/index.js b/lib/modules/apostrophe-pages-headless/index.js index 62ff9bb..c42cf0e 100644 --- a/lib/modules/apostrophe-pages-headless/index.js +++ b/lib/modules/apostrophe-pages-headless/index.js @@ -40,9 +40,9 @@ module.exports = { } // const data = options.apiKeys ? [ page ] : clean([ page ]); - const data = clean([ home ]); + const data = all ? clean([ home ]) : [ home ]; - const dataTosend = flat ? flatten(data[0]) : data[0]; + const dataTosend = (all && flat) ? flatten(data[0]) : data[0]; if (all) { return res.send(dataTosend); @@ -97,11 +97,9 @@ module.exports = { const children = item._children || []; const data = { ...item, - _children: (item._children || []).map((child) => child._id) + _children: children.map((child) => child._id) }; - result.push(data); - children.reduce(parseChildren, result); return result; @@ -109,8 +107,8 @@ module.exports = { } function render(result, callback) { - var restApi = self.apos.modules['apostrophe-headless']; - return restApi.apiRender(req, self, result, 'page', callback); + return self.apos.modules['apostrophe-headless'] + .apiRender(req, self, result, 'page', callback); } }); From a3260e6f5b1ed65b63adfadeebb00da43f3d3f33 Mon Sep 17 00:00:00 2001 From: Val Date: Wed, 5 May 2021 11:59:50 +0200 Subject: [PATCH 5/5] roll back back modif --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index e22ff45..ff696b6 100644 --- a/index.js +++ b/index.js @@ -236,7 +236,7 @@ module.exports = { return next(); } - const key = req.query.apikey || getAuthorizationApiKey(); + const key = req.query.apikey || req.query.apiKey || getAuthorizationApiKey(); let taskReq; if (!key) {