Overview
ExpressAuth is a simplicity inspired RESTful Express middleware to handle authentication features. It's still a work in progress so hang on for the published version!
Usage
Installation
To install it for use, use npm
:
Alternative with yarn
:
Basic w/ Default Options
You can use the express-authy
library as follows:
const express = require('express');
const ExpressAuthy = require('express-authy');
const server = express();
server.use(new ExpressAuthy());
server.listen(process.env.PORT);
This will set up express-authy
at the root endpoint. With the default options,
the following endpoints will be created:
/access
/forgot
/login
/logout
/register
/verify
Customizations
Setting the Base Path
The following line of code creates the 6 endpoints, /access
, /forgot
, /login
, /logout
, /register
, /verify
:
const ExpressAuthy = reuqire('express-authy');
server.use(new ExpressAuthy());
To change this to /auth/:endpoints
, use:
const ExpressAuthy = reuqire('express-authy');
server.use('/auth', new ExpressAuthy());
Changing the Default Options
A .get()
and .set()
method of the ExpressAuth
object allows you to alter and retrieve different options via a cursor. The method signatures are as follows:
.get( selector : {Array, String} )
The :selector
argument can be of an Array type or a String type and it points to the item in the options tree. For example, to get the required parameters of an endpoint, of which the structure is:
{
param: {
access: {
}
}
}
We use:
ExpressAuth.get(['param', 'access']);
.set( selector : {Array, String}, value : {Any} )
The :selector
property works in the same way as in .get()
. The :value
argument indicates the value to assign to the selected option. For example, to set the value of the option at param.access.token
to the string 'token-id'
, we use:
ExpressAuth.set(['param', 'access', 'token'], 'token-id');
Options Tree
The options are defined with a tree structure. The .get()
and .set()
methods as described above are used to select the nested property as desired. For an example tree:
{
"a": {
"b": {
"c": "d",
"e": {
"f": 0
}
},
"g": 1
},
"h": 2,
"i": 3
}
Using .get(['a', 'b', 'c'])
will return "d"
.
Using .get(['h'])
will return 2
.
Using .set(['a', 'b', 'e', 'f'], 4)
will set the 0
to 4
.
Using .set(['a'], 'a')
will result in the "a"
branch being replaced with the string literal, "a"
.
Defaults
The defaults are defined as follows:
var defaults = {
keys: [
access: 'access',
login: 'login',
logout: 'logout',
forgot: 'forgot',
register: 'register',
verify: 'verify',
],
method: {
[defaults.keys.access]: 'get',
[defaults.keys.login]: 'get',
[defaults.keys.logout]: 'get',
[defaults.keys.forgot]: 'get',
[defaults.keys.register]: 'get',
[defaults.keys.verify]: 'get',
},
model: {
sequelize: {
config: {
extraColumns: {},
get: function() => {configuration},
model: function(sequelize : Sequelize) => SequelizeModel,
names: {
columnEmail: 'email',
columnPassword: 'password',
columnNonce: 'nonce_token',
columnSession: 'session_token',
},
path: './sequelize.json',
table: 'Accounts',
nonceTokenLength: defaults.options.nonceTokenLength
},
handle: {
[defaults.keys.access]: function(token) : Promise,
[defaults.keys.login]: function(email, password) : Promise,
[defaults.keys.logout]: function(id) : Promise,
[defaults.keys.register]: function(email, password, [ otherInfo ]) : Promise,
[defaults.keys.verify]: function(token) : Promise,
[defaults.keys.forgot]: function(email) : Promise,
}
}
},
handlers: {
after: {
[defaults.keys.access]: null,
[defaults.keys.login]: null,
[defaults.keys.logout]: null,
[defaults.keys.register]: null,
[defaults.keys.verify]: null,
[defaults.keys.forgot]: null
},
[defaults.keys.access]: function(req, res, next) : void,
[defaults.keys.login]: function(req, res, next) : void
[defaults.keys.logout]: function(req, res, next) : void
[defaults.keys.register]: function(req, res, next) : void
[defaults.keys.verify]: function(req, res, next) : void
forgot: function(req, res, next) : void
},
params: {
required: {
[defaults.keys.access]: {
token: 'token',
},
[defaults.keys.login]: {
userIdentifier: 'user-id',
password: 'password',
},
[defaults.keys.logout]: {
token: 'token',
},
[defaults.keys.register]: {
email: 'email',
password: 'password',
passwordConfirmation: 'password-confirmation',
},
[defaults.keys.verify]: {
nonce: 'token',
},
[defaults.keys.forgot]: {
email: 'email',
}
},
get: function(endpointId) : Object
},
secret: {
keys: {
private: './config/key.priv',
public: './config/key.pub'
},
password: 'password',
asymmetric: function(),
symmetric: function()
},
options: {
modelStrategy: 'sequelize',
secretStrategy: 'symmetric',
tokenStrategy: 'jwt',
nonceTokenLength: 32
},
slug: {
access: 'access',
login: 'login',
logout: 'logout',
forgot: 'forgot',
register: 'register',
verify: 'verify',
},
token: {
jwt: {
generate: function(payload : Object) : String,
validate: function(token : String) : Object
}
}
};
Under The Hood Notes
Sequelize
ExpressAuth currently only uses Sequelize to manage database operations so we can
target more platforms.
Contributing
Fork this repo, create your stuff and issue a pull request(:
Getting Started
Clone the repo locally.
To install dependencies, use yarn install:
To initialize the test environment, you can run the following command:
This will set up the SQLite3 database, create a public/private key pair for the tests to use, and create and run database migrations.
Running Tests
You will need to run the above command to set up the test environment before the tests will work as expected!
Code Quality
You can run the code quality tests using:
Unit Tests
You can run the Mocha unit tests using:
You can also run it continuously in the background watching for file changes with:
To test a single file, you can run:
To test and watch a single file, you can run:
Coverage
Coverage files will be generated in /coverage
.
More notes on contributing coming soon!
Changelog
v0 (pre-release)
0.1.1
- code refactor
- documentation updates
0.1.0