is-able
v1.4.1
Published
Stupid simple authorization layer designed for maximum flexibility and readability
Downloads
11
Readme
is-able
Keep the buisness logic of authentication seperate from its implementation details.
Define the implementation details of authentication in a User object, then assert rules using user.mustBeAbleTo
, user.mustNotBeAbleTo
, or implement custom handling using user.can
and user.cannot
.
import { User } from 'is-able';
const user = new User({
rules: {
create: id => id === 301,
read: (id, age) => id !== 0 && age >= 14,
update: (...names) => names && names.includes('The boss'),
delete: ({ id, age }) => id !== 0 && age >= 14,
}
});
...
console.log(user.can('create', 301)); // true
console.log(user.cannot('read', 301, 14)); // false
user.mustBeAbleTo('update', 'jimmy', 'The boss steven'); // no exception
user.mustNotBeAbleTo('delete', { id: 123, age: 7 }); // throws exception
is-able also supports the alternate forms user.mustBe
, user.mustNotBe
, user.is
, and user.isNot
.
import { User } from 'is-able';
const user = new User({
rules: {
'logged in': ({ id }) => id !== undefined && id > 0,
admin: ({ id }) => id === 1000,
}
});
...
user.mustBe('logged in', { id: userId });
user.mustBe('admin', { id: userId });
console.log('Authenticated as admin!');
// Alternatively...
if (user.isNot('logged in', { id: userId })) {
// do something interesting here
throw new Error();
}
if (user.isNot('admin', { id: userId })) {
// do something else interesting here
throw new Error();
}
console.log('Authenticated as admin!');
Wrap user in a function to pass in global or per-request variables, like user token or other auth credentials. Authentication and authorization errors are given a code of 401 so they can be easily identified by your server.
// auth.js
import { User } from 'is-able';
export function auth(token) => new User({
rules: {
'view protected resource A': () => token.id;
}
});
// index.js
import { auth } from './auth';
import express from 'express';
const app = express();
// create user object
app.use((req, res, next) => {
req.user = auth(req.headers.authorization);
next();
});
app.get('/protected-resource', (req, res) => {
req.user.mustBeAbleTo('view protected resource A');
res.send('Super secret data!!');
});
// Handle auth errors
app.use(function (err, req, res, next) {
if (err.code === 401) {
res.status(401).send('Unauthorized');
return;
}
next(err);
});
app.listen(8080);