2013-07-02 23:51:38 +00:00
|
|
|
/**
|
|
|
|
* Module Dependencies.
|
|
|
|
*/
|
|
|
|
|
2013-07-16 17:49:25 +00:00
|
|
|
var Model = require('../loopback').Model
|
|
|
|
, loopback = require('../loopback')
|
2013-11-14 21:01:47 +00:00
|
|
|
, crypto = require('crypto')
|
2013-11-14 23:27:36 +00:00
|
|
|
, uid = require('uid2')
|
|
|
|
, DEFAULT_TOKEN_LEN = 64;
|
2013-07-02 23:51:38 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-13 19:49:08 +00:00
|
|
|
* Default AccessToken properties.
|
2013-07-02 23:51:38 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
var properties = {
|
2013-10-04 22:51:48 +00:00
|
|
|
id: {type: String, generated: true, id: 1},
|
2013-07-02 23:51:38 +00:00
|
|
|
uid: {type: String},
|
|
|
|
ttl: {type: Number, ttl: true}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-07-16 17:49:25 +00:00
|
|
|
* Extends from the built in `loopback.Model` type.
|
2013-07-02 23:51:38 +00:00
|
|
|
*/
|
|
|
|
|
2013-11-14 21:01:47 +00:00
|
|
|
var AccessToken = module.exports = Model.extend('AccessToken', properties);
|
2013-07-12 22:47:58 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-13 19:49:08 +00:00
|
|
|
* Create a cryptographically random access token id.
|
2013-07-12 22:47:58 +00:00
|
|
|
*
|
|
|
|
* @param {Function} callback
|
|
|
|
*/
|
|
|
|
|
2013-11-13 19:49:08 +00:00
|
|
|
AccessToken.createAccessTokenId = function (fn) {
|
2013-11-14 23:27:36 +00:00
|
|
|
uid(this.settings.accessTokenIdLength || DEFAULT_TOKEN_LEN, function(err, guid) {
|
2013-07-12 22:47:58 +00:00
|
|
|
if(err) {
|
|
|
|
fn(err);
|
|
|
|
} else {
|
2013-11-14 23:27:36 +00:00
|
|
|
fn(null, guid);
|
2013-07-12 22:47:58 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2013-11-13 19:49:08 +00:00
|
|
|
* Hook to create accessToken id.
|
2013-07-12 22:47:58 +00:00
|
|
|
*/
|
|
|
|
|
2013-11-13 19:49:08 +00:00
|
|
|
AccessToken.beforeCreate = function (next, data) {
|
2013-07-12 22:47:58 +00:00
|
|
|
data = data || {};
|
|
|
|
|
2013-11-13 19:49:08 +00:00
|
|
|
AccessToken.createAccessTokenId(function (err, id) {
|
2013-07-12 22:47:58 +00:00
|
|
|
if(err) {
|
|
|
|
next(err);
|
|
|
|
} else {
|
|
|
|
data.id = id;
|
|
|
|
next();
|
|
|
|
}
|
|
|
|
});
|
2013-11-11 21:35:54 +00:00
|
|
|
}
|
2013-11-14 21:01:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Find a token for the given `ServerRequest`.
|
|
|
|
*
|
|
|
|
* @param {ServerRequest} req
|
|
|
|
* @param {Object} [options] Options for finding the token
|
|
|
|
* @param {Function} callback Calls back with a token if one exists otherwise null or an error.
|
|
|
|
*/
|
|
|
|
|
|
|
|
AccessToken.findForRequest = function(req, options, cb) {
|
|
|
|
var id = tokenIdForRequest(req, options);
|
|
|
|
|
|
|
|
if(id) {
|
|
|
|
this.findById(id, cb);
|
|
|
|
} else {
|
|
|
|
process.nextTick(function() {
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function tokenIdForRequest(req, options) {
|
|
|
|
var params = options.params || [];
|
|
|
|
var headers = options.headers || [];
|
|
|
|
var cookies = options.cookies || [];
|
|
|
|
var i = 0;
|
|
|
|
var length;
|
|
|
|
var id;
|
|
|
|
|
|
|
|
params.push('access_token');
|
|
|
|
headers.push('X-Access-Token');
|
|
|
|
headers.push('authorization');
|
|
|
|
cookies.push('access_token');
|
|
|
|
cookies.push('authorization');
|
|
|
|
|
|
|
|
for(length = params.length; i < length; i++) {
|
|
|
|
id = req.param(params[i]);
|
|
|
|
|
|
|
|
if(typeof id === 'string') {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-14 23:27:36 +00:00
|
|
|
for(i = 0, length = headers.length; i < length; i++) {
|
|
|
|
id = req.header(headers[i]);
|
2013-11-14 21:01:47 +00:00
|
|
|
|
|
|
|
if(typeof id === 'string') {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-14 23:27:36 +00:00
|
|
|
for(i = 0, length = headers.length; i < length; i++) {
|
|
|
|
id = req.signedCookies[cookies[i]];
|
2013-11-14 21:01:47 +00:00
|
|
|
|
|
|
|
if(typeof id === 'string') {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|