Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes admin check when getting all pages #69

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 || req.query.apiKey || getAuthorizationApiKey();

let taskReq;
if (!key) {
return next();
}
Expand All @@ -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;
Expand All @@ -264,6 +266,7 @@ module.exports = {
req.user._permissions['admin-' + module.name] = true;
}
req.csrfExempt = true;

return next();
}
}
Expand Down
175 changes: 82 additions & 93 deletions lib/modules/apostrophe-pages-headless/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,119 +8,108 @@ 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) {
if (!self.apos.permissions.can(req, 'admin-apostrophe-page')) {
return res.status(403).send({ error: 'forbidden' });
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 = all ? clean([ home ]) : [ home ];

const dataTosend = (all && flat) ? flatten(data[0]) : data[0];

if (all) {
return res.send(dataTosend);
}
// 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) {

// 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: children.map((child) => child._id)
};
result.push(data);
children.reduce(parseChildren, result);

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);
});
return result;
}
}

function render(callback) {
var restApi = self.apos.modules['apostrophe-headless'];
return restApi.apiRender(req, self, result, 'page', callback);
function render(result, callback) {
return self.apos.modules['apostrophe-headless']
.apiRender(req, self, result, 'page', callback);
}

});

// GET one
Expand Down