Skip to content

Commit

Permalink
Extraction middleware to fix #2.
Browse files Browse the repository at this point in the history
  • Loading branch information
wbyoung committed Nov 15, 2014
1 parent 6de91cc commit b1b9044
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 24 deletions.
1 change: 1 addition & 0 deletions lib/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = function(adapter, middleware, opts) {
create: load('create'),
authenticate: load('authenticate'),
authorize: load('authorize'),
extract: load('extract'),
invalidate: load('invalidate')
};
};
40 changes: 16 additions & 24 deletions lib/middleware/authorize.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var raise = require('../raise');
module.exports = function(adapter, middleware, opts) {
var users = adapter.users;
var attrs = adapter.attrs;
var extract = require('./extract')(adapter, middleware, opts);

/**
* Authorization middleware
Expand All @@ -29,29 +30,20 @@ module.exports = function(adapter, middleware, opts) {
* @function
*/
return function(req, res, next) {
Promise.resolve()
.bind({})
.then(function() {
var authorization = req.get('Authorization');
var match = authorization && authorization.match(/^token\s+(\w+)$/i);
var token = this.token = match && match[1];
if (!token) { raise(401, 'invalid credentials', '(token)'); }
var digest = crypto.createHash('sha1').update(token).digest('hex');
return users.findByToken(digest);
})
.tap(raise.verify.defined(401, 'invalid credentials', '(user lookup)'))
.then(function(user) { this.user = user; })
.then(function() {
req.auth = req.auth || {};
req.auth.user = _.omit(attrs.all(this.user), opts.passwordDigest);
req.auth.db = { user: this.user };
req.auth.token = this.token;
next();
})
.catch(raise.catch(function(e) {
req.auth = {};
res.json(e.code, { error: e.message });
}))
.done();
extract(req, res, function(err) {
if (err) { next(err); }

Promise.resolve().then(function() {
var auth = req.auth;
if (!auth.token) { raise(401, 'invalid credentials', '(token)'); }
if (!auth.user) { raise(401, 'invalid credentials', '(user lookup)'); }
})
.then(next)
.catch(raise.catch(function(e) {
req.auth = {};
res.json(e.code, { error: e.message });
}))
.done();
});
};
};
55 changes: 55 additions & 0 deletions lib/middleware/extract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

var _ = require('lodash');
var bluebird = require('bluebird'), Promise = bluebird;
var crypto = require('crypto');

module.exports = function(adapter, middleware, opts) {
var users = adapter.users;
var attrs = adapter.attrs;

/**
* Extraction middleware
*
* Extract the user based on information submitted in the HTTP header,
* `Authorization`. The header must match the format `Token value` where
* `value` is the token previously given by authentication. If unsuccessful,
* this middleware does not cause the request to fail.
*
* When authorization is successful, this middleware sets the following:
*
* - `req.auth.user` is set to information about the authenticated user that
* is safe to send back to the client.
* - `req.auth.db.user` is set to the authenticated user.
* - `req.auth.token` is set to the value of the token used to authenticate
* the user.
*
* @function
*/
return function(req, res, next) {
Promise.resolve()
.bind({})
.then(function() {
var authorization = req.get('Authorization');
var match = authorization && authorization.match(/^token\s+(\w+)$/i);
var token = this.token = match && match[1];
var user;
if (token) {
var digest = crypto.createHash('sha1').update(token).digest('hex');
user = users.findByToken(digest);
}
return user;
})
.then(function(user) {
req.auth = req.auth || {};
req.auth.token = this.token;
if (user) {
req.auth.user = _.omit(attrs.all(user), opts.passwordDigest);
req.auth.db = { user: user };
}
next();
})
.catch(next)
.done();
};
};

0 comments on commit b1b9044

Please sign in to comment.