I come to see you to help me improve an express middleware that allows you to control access resources by checking the rights of the user. The following code is supposed to be as generic as possible so that it can easily be added to another project.
But I have doubts both on its genericity and the clarity of its prototype, I let you judge :)
acl.ts
export let config: ACLConfig = {
userField: 'me',
roleField: 'roles'
};
export function isAllowed(roles: String[], ...cbs: Function[]) {
return async function (req, res, next) {
let allowed = false;
let user = req[config.userField];
if (!user) throw new APIError('ACL module cannot find req.{{userField}}', APICodes.ACL_INTERNAL_ERROR);
let userRoles = user[config.roleField] || '';
userRoles = userRoles.split(',');
if (roles && roles.length) {
for (let role of roles) {
if (userRoles.indexOf(role) !== -1) return next();
}
}
if (cbs && cbs.length) {
for (let cb of cbs) {
if (cb(req) === true) return next();
}
}
throw new APIError('You do not have the required privileges', APICodes.AUTH_ACCESS_FORBIDDEN, HttpStatus.UNAUTHORIZED, true);
}
}
must be used like this
route('/...').all(verifyToken, isAllowed(['staff, admin'], policies.isMyArticle))
maybe this following prototype is better ?
isAllow(...args: String | Function)
isAllow('staff', policies.isMyArticle, 'staff');