Merge branch 'release/1.6.1' into production
This commit is contained in:
commit
bdaaa7cb44
|
@ -17,7 +17,7 @@ var Model = require('../loopback').Model
|
|||
*/
|
||||
|
||||
var properties = {
|
||||
id: {type: String, generated: true, id: 1},
|
||||
id: {type: String, id: true},
|
||||
ttl: {type: Number, ttl: true, default: DEFAULT_TTL}, // time to live in seconds
|
||||
created: {type: Date, default: function() {
|
||||
return new Date();
|
||||
|
|
|
@ -18,6 +18,7 @@ var Model = require('../loopback').Model
|
|||
, ACL = require('./acl').ACL
|
||||
, assert = require('assert');
|
||||
|
||||
var debug = require('debug')('loopback:user');
|
||||
/**
|
||||
* Default User properties.
|
||||
*/
|
||||
|
@ -127,10 +128,15 @@ var User = module.exports = Model.extend('User', properties, options);
|
|||
* @param {AccessToken} token
|
||||
*/
|
||||
|
||||
User.login = function (credentials, fn) {
|
||||
var UserCtor = this;
|
||||
User.login = function (credentials, include, fn) {
|
||||
if (typeof include === 'function') {
|
||||
fn = include;
|
||||
include = undefined;
|
||||
}
|
||||
|
||||
include = (include || '').toLowerCase();
|
||||
|
||||
var query = {};
|
||||
|
||||
if(credentials.email) {
|
||||
query.email = credentials.email;
|
||||
} else if(credentials.username) {
|
||||
|
@ -143,20 +149,36 @@ User.login = function (credentials, fn) {
|
|||
var defaultError = new Error('login failed');
|
||||
|
||||
if(err) {
|
||||
debug('An error is reported from User.findOne: %j', err);
|
||||
fn(defaultError);
|
||||
} else if(user) {
|
||||
user.hasPassword(credentials.password, function(err, isMatch) {
|
||||
if(err) {
|
||||
debug('An error is reported from User.hasPassword: %j', err);
|
||||
fn(defaultError);
|
||||
} else if(isMatch) {
|
||||
user.accessTokens.create({
|
||||
ttl: Math.min(credentials.ttl || User.settings.ttl, User.settings.maxTTL)
|
||||
}, fn);
|
||||
}, function(err, token) {
|
||||
if (err) return fn(err);
|
||||
if (include === 'user') {
|
||||
// NOTE(bajtos) We can't set token.user here:
|
||||
// 1. token.user already exists, it's a function injected by
|
||||
// "AccessToken belongsTo User" relation
|
||||
// 2. ModelBaseClass.toJSON() ignores own properties, thus
|
||||
// the value won't be included in the HTTP response
|
||||
// See also loopback#161 and loopback#162
|
||||
token.__data.user = user;
|
||||
}
|
||||
fn(err, token);
|
||||
});
|
||||
} else {
|
||||
debug('The password is invalid for user %s', query.email || query.username);
|
||||
fn(defaultError);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
debug('No matching record is found for user %s', query.email || query.username);
|
||||
fn(defaultError);
|
||||
}
|
||||
});
|
||||
|
@ -386,9 +408,18 @@ User.setup = function () {
|
|||
UserModel.login,
|
||||
{
|
||||
accepts: [
|
||||
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}}
|
||||
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}},
|
||||
{arg: 'include', type: 'string', http: {source: 'query' }, description:
|
||||
'Related objects to include in the response. ' +
|
||||
'See the description of return value for more details.'}
|
||||
],
|
||||
returns: {arg: 'accessToken', type: 'object', root: true},
|
||||
returns: {
|
||||
arg: 'accessToken', type: 'object', root: true, description:
|
||||
'The response body contains properties of the AccessToken created on login.\n' +
|
||||
'Depending on the value of `include` parameter, the body may contain ' +
|
||||
'additional properties:\n\n' +
|
||||
' - `user` - `{User}` - Data of the currently logged in user. (`include=user`)\n\n'
|
||||
},
|
||||
http: {verb: 'post'}
|
||||
}
|
||||
);
|
||||
|
@ -403,7 +434,10 @@ User.setup = function () {
|
|||
var tokenID = accessToken && accessToken.id;
|
||||
|
||||
return tokenID;
|
||||
}}
|
||||
}, description:
|
||||
'Do not supply this argument, it is automatically extracted ' +
|
||||
'from request headers.'
|
||||
}
|
||||
],
|
||||
http: {verb: 'all'}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"Platform",
|
||||
"mBaaS"
|
||||
],
|
||||
"version": "1.6.0",
|
||||
"version": "1.6.1",
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
|
|
|
@ -8,6 +8,7 @@ var userMemory = loopback.createDataSource({
|
|||
});
|
||||
|
||||
describe('User', function(){
|
||||
var validCredentials = {email: 'foo@bar.com', password: 'bar'};
|
||||
beforeEach(function() {
|
||||
User = loopback.User.extend('user');
|
||||
User.email = loopback.Email.extend('email');
|
||||
|
@ -25,7 +26,7 @@ describe('User', function(){
|
|||
app.use(loopback.rest());
|
||||
app.model(User);
|
||||
|
||||
User.create({email: 'foo@bar.com', password: 'bar'}, done);
|
||||
User.create(validCredentials, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
|
@ -105,7 +106,7 @@ describe('User', function(){
|
|||
|
||||
describe('User.login', function() {
|
||||
it('Login a user by providing credentials', function(done) {
|
||||
User.login({email: 'foo@bar.com', password: 'bar'}, function (err, accessToken) {
|
||||
User.login(validCredentials, function (err, accessToken) {
|
||||
assert(accessToken.userId);
|
||||
assert(accessToken.id);
|
||||
assert.equal(accessToken.id.length, 64);
|
||||
|
@ -119,7 +120,7 @@ describe('User', function(){
|
|||
.post('/users/login')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
.send({email: 'foo@bar.com', password: 'bar'})
|
||||
.send(validCredentials)
|
||||
.end(function(err, res){
|
||||
if(err) return done(err);
|
||||
var accessToken = res.body;
|
||||
|
@ -127,11 +128,28 @@ describe('User', function(){
|
|||
assert(accessToken.userId);
|
||||
assert(accessToken.id);
|
||||
assert.equal(accessToken.id.length, 64);
|
||||
assert(accessToken.user === undefined);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('Returns current user when `include` is `USER`', function(done) {
|
||||
request(app)
|
||||
.post('/users/login?include=USER')
|
||||
.send(validCredentials)
|
||||
.expect(200)
|
||||
.expect('Content-Type', /json/)
|
||||
.end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
var token = res.body;
|
||||
expect(token.user, 'body.user').to.not.equal(undefined);
|
||||
expect(token.user, 'body.user')
|
||||
.to.have.property('email', validCredentials.email);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Login should only allow correct credentials', function(done) {
|
||||
User.create({email: 'foo22@bar.com', password: 'bar'}, function(user, err) {
|
||||
User.login({email: 'foo44@bar.com', password: 'bar'}, function(err, accessToken) {
|
||||
|
|
Loading…
Reference in New Issue