UNPKG

2.44 kBJavaScriptView Raw
1const util = require('util')
2const get = require('lodash.get')
3
4const UnauthorizedError = require('./error')
5const PermissionError = new UnauthorizedError(
6 'permission_denied', { message: 'Permission denied' }
7)
8
9const Guard = function (options) {
10 const defaults = {
11 requestProperty: 'user',
12 permissionsProperty: 'permissions'
13 }
14
15 this._options = Object.assign({}, defaults, options)
16}
17
18function isString (value) {
19 return typeof value === 'string'
20}
21
22function isArray (value) {
23 return value instanceof Array
24}
25
26Guard.prototype = {
27
28 check: function (required) {
29 if (isString(required)) {
30 required = [[required]]
31 } else if (isArray(required) && required.every(isString)) {
32 required = [required]
33 }
34
35 const _middleware = function _middleware (req, res, next) {
36 const self = this
37 const options = self._options
38
39 if (!options.requestProperty) {
40 return next(new UnauthorizedError('request_property_undefined', {
41 message: 'requestProperty hasn\'t been defined. Check your configuration.'
42 }))
43 }
44
45 const user = get(req, options.requestProperty, undefined)
46 if (!user) {
47 return next(new UnauthorizedError('user_object_not_found', {
48 message: util.format('user object "%s" was not found. Check your configuration.', options.requestProperty)
49 }))
50 }
51
52 let permissions = get(user, options.permissionsProperty, undefined)
53 if (!permissions) {
54 return next(new UnauthorizedError('permissions_not_found', {
55 message: 'Could not find permissions for user. Bad configuration?'
56 }))
57 }
58
59 if (typeof permissions === 'string') {
60 permissions = permissions.split(' ')
61 }
62
63 if (!Array.isArray(permissions)) {
64 return next(new UnauthorizedError('permissions_invalid', {
65 message: 'Permissions should be an Array or String. Bad format?'
66 }))
67 }
68
69 const sufficient = required.some(function (required) {
70 return required.every(function (permission) {
71 return permissions.indexOf(permission) !== -1
72 })
73 })
74
75 next(!sufficient ? PermissionError : null)
76 }.bind(this)
77
78 _middleware.unless = require('express-unless')
79
80 return _middleware
81 }
82}
83
84module.exports = function (options) {
85 return new Guard(options)
86}