Fix logout to handle no or missing accessToken
Return 401 when the request does not provide any accessToken argument or the token was not found. Also simplify the implementation of the `logout` method to make only a single database call (`deleteById`) instead of `findById` + `delete`.
This commit is contained in:
parent
2ade55ec03
commit
1dac9ada0b
|
@ -293,13 +293,23 @@ module.exports = function(User) {
|
|||
|
||||
User.logout = function(tokenId, fn) {
|
||||
fn = fn || utils.createPromiseCallback();
|
||||
this.relations.accessTokens.modelTo.findById(tokenId, function(err, accessToken) {
|
||||
|
||||
if (!tokenId) {
|
||||
var err = new Error(g.f('{{accessToken}} is required to logout'));
|
||||
err.status = 401;
|
||||
process.nextTick(function() { fn(err); });
|
||||
return fn.promise;
|
||||
}
|
||||
|
||||
this.relations.accessTokens.modelTo.destroyById(tokenId, function(err, info) {
|
||||
if (err) {
|
||||
fn(err);
|
||||
} else if (accessToken) {
|
||||
accessToken.destroy(fn);
|
||||
} else if ('count' in info && info.count === 0) {
|
||||
err = new Error(g.f('Could not find {{accessToken}}'));
|
||||
err.status = 401;
|
||||
fn(err);
|
||||
} else {
|
||||
fn(new Error(g.f('could not find {{accessToken}}')));
|
||||
fn();
|
||||
}
|
||||
});
|
||||
return fn.promise;
|
||||
|
@ -743,10 +753,10 @@ module.exports = function(User) {
|
|||
{
|
||||
description: 'Logout a user with access token.',
|
||||
accepts: [
|
||||
{arg: 'access_token', type: 'string', required: true, http: function(ctx) {
|
||||
{arg: 'access_token', type: 'string', http: function(ctx) {
|
||||
var req = ctx && ctx.req;
|
||||
var accessToken = req && req.accessToken;
|
||||
var tokenID = accessToken && accessToken.id;
|
||||
var tokenID = accessToken ? accessToken.id : undefined;
|
||||
return tokenID;
|
||||
}, description: 'Do not supply this argument, it is automatically extracted ' +
|
||||
'from request headers.',
|
||||
|
|
|
@ -148,6 +148,17 @@ describe('users - integration', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('returns 401 on logout with no access token', function(done) {
|
||||
this.post('/api/users/logout')
|
||||
.expect(401, done);
|
||||
});
|
||||
|
||||
it('returns 401 on logout with invalid access token', function(done) {
|
||||
this.post('/api/users/logout')
|
||||
.set('Authorization', 'unknown-token')
|
||||
.expect(401, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sub-user', function() {
|
||||
|
|
|
@ -1186,6 +1186,22 @@ describe('User', function() {
|
|||
}
|
||||
});
|
||||
|
||||
it('fails when accessToken is not provided', function(done) {
|
||||
User.logout(undefined, function(err) {
|
||||
expect(err).to.have.property('message');
|
||||
expect(err).to.have.property('status', 401);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fails when accessToken is not found', function(done) {
|
||||
User.logout('expired-access-token', function(err) {
|
||||
expect(err).to.have.property('message');
|
||||
expect(err).to.have.property('status', 401);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
function verify(token, done) {
|
||||
assert(token);
|
||||
|
||||
|
|
Loading…
Reference in New Issue