Merge pull request #163 from strongloop/feature/include-user-in-login-result
Include user in login result
This commit is contained in:
commit
c36e20587e
|
@ -128,10 +128,15 @@ var User = module.exports = Model.extend('User', properties, options);
|
||||||
* @param {AccessToken} token
|
* @param {AccessToken} token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
User.login = function (credentials, fn) {
|
User.login = function (credentials, include, fn) {
|
||||||
var UserCtor = this;
|
if (typeof include === 'function') {
|
||||||
var query = {};
|
fn = include;
|
||||||
|
include = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
include = (include || '').toLowerCase();
|
||||||
|
|
||||||
|
var query = {};
|
||||||
if(credentials.email) {
|
if(credentials.email) {
|
||||||
query.email = credentials.email;
|
query.email = credentials.email;
|
||||||
} else if(credentials.username) {
|
} else if(credentials.username) {
|
||||||
|
@ -154,7 +159,19 @@ User.login = function (credentials, fn) {
|
||||||
} else if(isMatch) {
|
} else if(isMatch) {
|
||||||
user.accessTokens.create({
|
user.accessTokens.create({
|
||||||
ttl: Math.min(credentials.ttl || User.settings.ttl, User.settings.maxTTL)
|
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 {
|
} else {
|
||||||
debug('The password is invalid for user %s', query.email || query.username);
|
debug('The password is invalid for user %s', query.email || query.username);
|
||||||
fn(defaultError);
|
fn(defaultError);
|
||||||
|
@ -391,9 +408,18 @@ User.setup = function () {
|
||||||
UserModel.login,
|
UserModel.login,
|
||||||
{
|
{
|
||||||
accepts: [
|
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'}
|
http: {verb: 'post'}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -408,7 +434,10 @@ User.setup = function () {
|
||||||
var tokenID = accessToken && accessToken.id;
|
var tokenID = accessToken && accessToken.id;
|
||||||
|
|
||||||
return tokenID;
|
return tokenID;
|
||||||
}}
|
}, description:
|
||||||
|
'Do not supply this argument, it is automatically extracted ' +
|
||||||
|
'from request headers.'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
http: {verb: 'all'}
|
http: {verb: 'all'}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ var userMemory = loopback.createDataSource({
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('User', function(){
|
describe('User', function(){
|
||||||
|
var validCredentials = {email: 'foo@bar.com', password: 'bar'};
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
User = loopback.User.extend('user');
|
User = loopback.User.extend('user');
|
||||||
User.email = loopback.Email.extend('email');
|
User.email = loopback.Email.extend('email');
|
||||||
|
@ -25,7 +26,7 @@ describe('User', function(){
|
||||||
app.use(loopback.rest());
|
app.use(loopback.rest());
|
||||||
app.model(User);
|
app.model(User);
|
||||||
|
|
||||||
User.create({email: 'foo@bar.com', password: 'bar'}, done);
|
User.create(validCredentials, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function (done) {
|
afterEach(function (done) {
|
||||||
|
@ -105,7 +106,7 @@ describe('User', function(){
|
||||||
|
|
||||||
describe('User.login', function() {
|
describe('User.login', function() {
|
||||||
it('Login a user by providing credentials', function(done) {
|
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.userId);
|
||||||
assert(accessToken.id);
|
assert(accessToken.id);
|
||||||
assert.equal(accessToken.id.length, 64);
|
assert.equal(accessToken.id.length, 64);
|
||||||
|
@ -119,7 +120,7 @@ describe('User', function(){
|
||||||
.post('/users/login')
|
.post('/users/login')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.send({email: 'foo@bar.com', password: 'bar'})
|
.send(validCredentials)
|
||||||
.end(function(err, res){
|
.end(function(err, res){
|
||||||
if(err) return done(err);
|
if(err) return done(err);
|
||||||
var accessToken = res.body;
|
var accessToken = res.body;
|
||||||
|
@ -127,11 +128,28 @@ describe('User', function(){
|
||||||
assert(accessToken.userId);
|
assert(accessToken.userId);
|
||||||
assert(accessToken.id);
|
assert(accessToken.id);
|
||||||
assert.equal(accessToken.id.length, 64);
|
assert.equal(accessToken.id.length, 64);
|
||||||
|
assert(accessToken.user === undefined);
|
||||||
|
|
||||||
done();
|
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) {
|
it('Login should only allow correct credentials', function(done) {
|
||||||
User.create({email: 'foo22@bar.com', password: 'bar'}, function(user, err) {
|
User.create({email: 'foo22@bar.com', password: 'bar'}, function(user, err) {
|
||||||
User.login({email: 'foo44@bar.com', password: 'bar'}, function(err, accessToken) {
|
User.login({email: 'foo44@bar.com', password: 'bar'}, function(err, accessToken) {
|
||||||
|
|
Loading…
Reference in New Issue