Allow the creation of access token to be overriden
This commit is contained in:
parent
d8c6f9d962
commit
6b4ebdf609
|
@ -2,14 +2,12 @@
|
||||||
* Module Dependencies.
|
* Module Dependencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Model = require('../loopback').Model
|
var loopback = require('../loopback')
|
||||||
, loopback = require('../loopback')
|
, Model = loopback.Model
|
||||||
, path = require('path')
|
, path = require('path')
|
||||||
, SALT_WORK_FACTOR = 10
|
, SALT_WORK_FACTOR = 10
|
||||||
, crypto = require('crypto')
|
, crypto = require('crypto')
|
||||||
, bcrypt = require('bcryptjs')
|
, bcrypt = require('bcryptjs')
|
||||||
, passport = require('passport')
|
|
||||||
, LocalStrategy = require('passport-local').Strategy
|
|
||||||
, BaseAccessToken = require('./access-token')
|
, BaseAccessToken = require('./access-token')
|
||||||
, DEFAULT_TTL = 1209600 // 2 weeks in seconds
|
, DEFAULT_TTL = 1209600 // 2 weeks in seconds
|
||||||
, DEFAULT_RESET_PW_TTL = 15 * 60 // 15 mins in seconds
|
, DEFAULT_RESET_PW_TTL = 15 * 60 // 15 mins in seconds
|
||||||
|
@ -128,6 +126,22 @@ var options = {
|
||||||
|
|
||||||
var User = module.exports = Model.extend('User', properties, options);
|
var User = module.exports = Model.extend('User', properties, options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create access token for the logged in user. This method can be overridden to
|
||||||
|
* customize how access tokens are generated
|
||||||
|
*
|
||||||
|
* @param [Number} ttl The requested ttl
|
||||||
|
* @callack {Function} cb The callback function
|
||||||
|
* @param {String|Error} err The error string or object
|
||||||
|
* @param {AccessToken} token The generated access token object
|
||||||
|
*/
|
||||||
|
User.prototype.createAccessToken = function(ttl, cb) {
|
||||||
|
ttl = Math.min(ttl || User.settings.ttl, User.settings.maxTTL);
|
||||||
|
this.accessTokens.create({
|
||||||
|
ttl: ttl
|
||||||
|
}, cb);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Login a user by with the given `credentials`.
|
* Login a user by with the given `credentials`.
|
||||||
*
|
*
|
||||||
|
@ -144,6 +158,7 @@ var User = module.exports = Model.extend('User', properties, options);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.login = function (credentials, include, fn) {
|
User.login = function (credentials, include, fn) {
|
||||||
|
var self = this;
|
||||||
if (typeof include === 'function') {
|
if (typeof include === 'function') {
|
||||||
fn = include;
|
fn = include;
|
||||||
include = undefined;
|
include = undefined;
|
||||||
|
@ -162,7 +177,7 @@ User.login = function (credentials, include, fn) {
|
||||||
return fn(err);
|
return fn(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.findOne({where: query}, function(err, user) {
|
self.findOne({where: query}, function(err, user) {
|
||||||
var defaultError = new Error('login failed');
|
var defaultError = new Error('login failed');
|
||||||
defaultError.statusCode = 401;
|
defaultError.statusCode = 401;
|
||||||
|
|
||||||
|
@ -175,9 +190,7 @@ User.login = function (credentials, include, fn) {
|
||||||
debug('An error is reported from User.hasPassword: %j', err);
|
debug('An error is reported from User.hasPassword: %j', err);
|
||||||
fn(defaultError);
|
fn(defaultError);
|
||||||
} else if(isMatch) {
|
} else if(isMatch) {
|
||||||
user.accessTokens.create({
|
user.createAccessToken(credentials.ttl, function(err, token) {
|
||||||
ttl: Math.min(credentials.ttl || User.settings.ttl, User.settings.maxTTL)
|
|
||||||
}, function(err, token) {
|
|
||||||
if (err) return fn(err);
|
if (err) return fn(err);
|
||||||
if (include === 'user') {
|
if (include === 'user') {
|
||||||
// NOTE(bajtos) We can't set token.user here:
|
// NOTE(bajtos) We can't set token.user here:
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
"express": "~3.5.0",
|
"express": "~3.5.0",
|
||||||
"strong-remoting": "~1.5.0",
|
"strong-remoting": "~1.5.0",
|
||||||
"inflection": "~1.3.5",
|
"inflection": "~1.3.5",
|
||||||
"passport": "~0.2.0",
|
|
||||||
"passport-local": "~1.0.0",
|
|
||||||
"nodemailer": "~0.6.5",
|
"nodemailer": "~0.6.5",
|
||||||
"ejs": "~1.0.0",
|
"ejs": "~1.0.0",
|
||||||
"bcryptjs": "~0.7.12",
|
"bcryptjs": "~0.7.12",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
var User;
|
var User;
|
||||||
var AccessToken = loopback.AccessToken;
|
var AccessToken = loopback.AccessToken;
|
||||||
var passport = require('passport');
|
|
||||||
var MailConnector = require('../lib/connectors/mail');
|
var MailConnector = require('../lib/connectors/mail');
|
||||||
|
|
||||||
var userMemory = loopback.createDataSource({
|
var userMemory = loopback.createDataSource({
|
||||||
|
@ -9,6 +8,7 @@ var userMemory = loopback.createDataSource({
|
||||||
|
|
||||||
describe('User', function(){
|
describe('User', function(){
|
||||||
var validCredentials = {email: 'foo@bar.com', password: 'bar'};
|
var validCredentials = {email: 'foo@bar.com', password: 'bar'};
|
||||||
|
var validCredentialsWithTTL = {email: 'foo@bar.com', password: 'bar', ttl: 3600};
|
||||||
var invalidCredentials = {email: 'foo1@bar.com', password: 'bar1'};
|
var invalidCredentials = {email: 'foo1@bar.com', password: 'bar1'};
|
||||||
var incompleteCredentials = {password: 'bar1'};
|
var incompleteCredentials = {password: 'bar1'};
|
||||||
|
|
||||||
|
@ -117,6 +117,44 @@ describe('User', function(){
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Login a user by providing credentials with TTL', function(done) {
|
||||||
|
User.login(validCredentialsWithTTL, function (err, accessToken) {
|
||||||
|
assert(accessToken.userId);
|
||||||
|
assert(accessToken.id);
|
||||||
|
assert.equal(accessToken.ttl, validCredentialsWithTTL.ttl);
|
||||||
|
assert.equal(accessToken.id.length, 64);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Login a user using a custom createAccessToken', function(done) {
|
||||||
|
var createToken = User.prototype.createAccessToken; // Save the original method
|
||||||
|
// Override createAccessToken
|
||||||
|
User.prototype.createAccessToken = function(ttl, cb) {
|
||||||
|
// Reduce the ttl by half for testing purpose
|
||||||
|
this.accessTokens.create({ttl: ttl /2 }, cb);
|
||||||
|
};
|
||||||
|
User.login(validCredentialsWithTTL, function (err, accessToken) {
|
||||||
|
assert(accessToken.userId);
|
||||||
|
assert(accessToken.id);
|
||||||
|
assert.equal(accessToken.ttl, 1800);
|
||||||
|
assert.equal(accessToken.id.length, 64);
|
||||||
|
|
||||||
|
User.findById(accessToken.userId, function(err, user) {
|
||||||
|
user.createAccessToken(120, function (err, accessToken) {
|
||||||
|
assert(accessToken.userId);
|
||||||
|
assert(accessToken.id);
|
||||||
|
assert.equal(accessToken.ttl, 60);
|
||||||
|
assert.equal(accessToken.id.length, 64);
|
||||||
|
// Restore create access token
|
||||||
|
User.prototype.createAccessToken = createToken;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Login a user over REST by providing credentials', function(done) {
|
it('Login a user over REST by providing credentials', function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
|
|
Loading…
Reference in New Issue