Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

express-reaccess

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-reaccess - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

2

package.json
{
"name": "express-reaccess",
"version": "0.0.4",
"version": "0.0.5",
"description": "Express/Connect middleware to manage API access on a RegExp basis",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -14,3 +14,3 @@ # express-reaccess

rightsProp: 'user.rights',
userProp: 'user'
valuesProp: 'user'
}));

@@ -88,8 +88,8 @@

req.user.rights = [{
path: '/organizations/:orgId/users.json'
methods: reaccess.GET | reaccess.POST
path: '/organizations/:orgId/users.json'
methods: reaccess.GET | reaccess.POST
}];
```
### options.userProp
### options.valuesProp
Type: `String`

@@ -103,8 +103,8 @@

req.user.rights = [{
path: '/organizations/:org.id/users.json'
methods: reaccess.GET | reaccess.POST
path: '/organizations/:org.id/users.json'
methods: reaccess.GET | reaccess.POST
}];
```
He will be able to access this URI /organizations/1/users.json if a previously
set middleware have set the `req.user.org.id` to `1` and `options.userProp` to
set middleware have set the `req.user.org.id` to `1` and `options.valuesProp` to
`'user'`.

@@ -171,3 +171,39 @@

## Want more ?
express-reaccess supports multivalued path templates. The following rights/values couple:
```
req.user.rights = [{
path: '/organizations/:organizations.#.id/users/:id.json'
methods: reaccess.GET | reaccess.POST
}];
req.user.organizations = [{
id: 1,
name: 'FranceJS'
}, {
id: 2,
name: 'ChtiJS'
}];
req.user.id = 3;
```
Will give access to GET/POST /organizations/1/users/3.json and
GET/POST /organizations/2/users/3.json.
You also can use the express-reaccess middleware several times to bring a
fine access control of your API to your consumers:
```
// Access control based on the pricing plan of the user organization
app.use(reaccess({
rightsProp: 'pricingPlan.rights',
valuesProp: 'organization'
}));
// Access control based on the user rights set per each organization administrator
app.use(reaccess({
rightsProp: 'user.rights',
valuesProp: 'user'
}));
```
## Stats

@@ -174,0 +210,0 @@

@@ -8,2 +8,3 @@ var escRegExp = require('escape-regexp-component');

options.rightsProp = options.rightsProp || 'user.rights';
options.valuesProp = options.valuesProp || options.userProp; // Legacy
options.errorConstructor = options.errorConstructor || Error;

@@ -14,26 +15,31 @@ options.accessErrorMessage = options.accessErrorMessage || 'Unauthorized access!';

var rights = getValues([req], options.rightsProp)[0];
var user;
var rootValues;
if(!(rights && rights instanceof Array)) {
throw new Error('The rights property must be an array.');
}
if(options.userProp) {
user = getValues([req], options.userProp)[0];
if(options.valuesProp) {
rootValues = getValues([req], options.valuesProp);
}
if(rights.some(function(right) {
var path = '';
if(!(right.methods && right.methods&reaccess[req.method.toUpperCase()])) {
if(!('undefined' !== typeof right.methods &&
'undefined' !== typeof right.path &&
right.methods&reaccess[req.method.toUpperCase()])) {
return false;
}
path = user ?
right.path.replace(/(.*\/|^):([a-z0-9_\-\.\*\@\#]+)(\/.*|$)/,
function($, $1, $2, $3) {
var values = getValues([user], $2);
if(values.length) {
return $1 + (1 === values.length ?
escRegExp(values[0]) :
'(' + values.map(escRegExp).join('|') + ')') + $3;
}
return '';
}) :
right.path;
path = right.path;
if(options.valuesProp) {
while(/(.*\/|^):([a-z0-9_\-\.\*\@\#]+)(\/.*|$)/.test(path)) {
path = path.replace(/(.*\/|^):([a-z0-9_\-\.\*\@\#]+)(\/.*|$)/,
function($, $1, $2, $3) {
var values = getValues(rootValues, $2);
if(values.length) {
return $1 + (1 === values.length ?
escRegExp(values[0]) :
'(' + values.map(escRegExp).join('|') + ')') + $3;
}
return '';
});
}
}
return path && new RegExp('^'+path+'$').test(req.path);

@@ -40,0 +46,0 @@ })) {

@@ -8,10 +8,10 @@ var assert = require('assert');

it('when there is no rights', function(done) {
testReq()
.expect(500, 'Unauthorized access!')
.end(function(err, res){
if(err) throw err;
done();
});
});
it('when there is no rights', function(done) {
testReq()
.expect(500, 'Unauthorized access!')
.end(function(err, res){
if(err) throw err;
done();
});
});
it('when there is no rights matching the path', function(done) {

@@ -21,3 +21,3 @@ testReq({

path: '/bar',
methods: reaccess.METHODS
methods: reaccess.ALL_MASK
}

@@ -36,6 +36,6 @@ })

path: '/bar',
methods: reaccess.METHODS
methods: reaccess.ALL_MASK
},{
path: '/plop',
methods: reaccess.METHODS
methods: reaccess.ALL_MASK
}]

@@ -54,6 +54,6 @@ })

path: '/bar',
methods: reaccess.METHODS
methods: reaccess.ALL_MASK
},{
path: '/plop',
methods: reaccess.METHODS
methods: reaccess.ALL_MASK
}]

@@ -72,6 +72,6 @@ })

path: '/foo/:bar.ba.pa.pa/plop',
methods: reaccess.METHODS ^ reaccess.GET
methods: reaccess.ALL_MASK ^ reaccess.GET
},{
path: '/plop',
methods: reaccess.METHODS
methods: reaccess.ALL_MASK
}]

@@ -86,2 +86,38 @@ })

it('when there is a templated value with no value', function(done) {
testReq({
rightsObj: [{
path: '/foo/:bar.foo',
methods: reaccess.ALL_MASK
}],
valuesProp: 'user.content',
userObj: {}
}, {
valuesProp: 'user.content'
}, '/foo/')
.expect(500, /Unauthorized access!/)
.end(function(err, res){
if(err) throw err;
done();
});
});
it('when there is a templated value with no value and several templates', function(done) {
testReq({
rightsObj: [{
path: '/foo/:bar.foo/:bar.foo',
methods: reaccess.ALL_MASK
}],
valuesProp: 'user.content',
userObj: {}
}, {
valuesProp: 'user.content'
}, '/foo//')
.expect(500, /Unauthorized access!/)
.end(function(err, res){
if(err) throw err;
done();
});
});
});

@@ -117,3 +153,3 @@

}],
userProp: 'user.content',
valuesProp: 'user.content',
userObj: {

@@ -130,3 +166,3 @@ bar: {

}, {
userProp: 'user.content'
valuesProp: 'user.content'
}, '/foo/1/plop')

@@ -149,3 +185,3 @@ .expect(200, 'plop')

}],
userProp: 'user.content',
valuesProp: 'user.content',
userObj: {

@@ -156,3 +192,3 @@ bar: 'a',

}, {
userProp: 'user.content'
valuesProp: 'user.content'
}, '/foo/a/plop')

@@ -175,3 +211,3 @@ .expect(200, 'plop')

}],
userProp: 'user.content',
valuesProp: 'user.content',
userObj: {

@@ -190,3 +226,3 @@ bar: {

}, {
userProp: 'user.content'
valuesProp: 'user.content'
}, '/foo/1/plop')

@@ -209,3 +245,3 @@ .expect(200, 'plop')

}],
userProp: 'user.content',
valuesProp: 'user.content',
userObj: {

@@ -224,3 +260,3 @@ bar: {

}, {
userProp: 'user.content'
valuesProp: 'user.content'
}, '/foo/1/plop')

@@ -243,3 +279,3 @@ .expect(200, 'plop')

}],
userProp: 'user.content',
valuesProp: 'user.content',
userObj: {

@@ -263,3 +299,3 @@ bar: {

}, {
userProp: 'user.content'
valuesProp: 'user.content'
}, '/foo/1/plop')

@@ -273,2 +309,23 @@ .expect(200, 'plop')

it('whith several templates for a single path', function(done) {
testReq({
rightsObj: [{
path: '/foo/:bar/:foo',
methods: reaccess.ALL_MASK
}],
valuesProp: 'user.content',
userObj: {
bar: 'bapapa',
foo: 'lcontact'
}
}, {
valuesProp: 'user.content'
}, '/foo/bapapa/lcontact')
.expect(200, 'plop')
.end(function(err, res){
if(err) throw err;
done();
});
});
});

@@ -296,8 +353,8 @@

options.rightsObj = options.rightsObj || [];
options.userProp = options.userProp || '';
options.valuesProp = options.valuesProp || '';
options.userObj = options.userObj || {};
return function (req, res, next) {
setProp(req, options.rightsProp, options.rightsObj);
if(options.userProp) {
setProp(req, options.userProp, options.userObj);
if(options.valuesProp) {
setProp(req, options.valuesProp, options.userObj);
}

@@ -304,0 +361,0 @@ next();

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc