The other answers here work great, but here is an implementation that I find slightly cleaner.
Instead of creating policies designed for an OR situation that call next()
even though they should fail, you can modify your existing policies to use in an AND/OR context, while hardly changing their behavior. Then create a composite policy (like the OP suggested) that checks the modified existing policies.
config/policies.js with example controllers and policies:
AdminController: {
adminDashboard: 'isAuthenticated',
},
ItemController: {
findOne: 'isPublishedOrIsAuthenticated'
}
api/policies/isAuthenticated.js and api/policies/isPublished.js and any other policy you want to use as a part of an AND/OR check:
If next
was set to the true
boolean (as opposed to a callback), just return true
or false
before the policy would normally return next()
, res.notFound()
, etc.
module.exports = function(req, res, next) {
// do some checking
if(next === true) return true; // or return false
return next();
};
Note that we need to use the triple-equals sign here.
api/policies/isPublishedOrIsAuthenticated.js
module.exports = function(req, res, next) {
var isPublished = require('./isPublished.js');
var isAuthenticated = require('./isAuthenticated.js');
// This reads like what we are trying to achieve!
// The third argument in each call tells the function to return a boolean
if(isPublished(req, res, true) || isAuthenticated(req, res, true))
return next();
return res.notFound();
};