Skip to content
This repository has been archived by the owner on Mar 22, 2022. It is now read-only.

Commit

Permalink
De-authenticating sockets on logout. Closes #136
Browse files Browse the repository at this point in the history
  • Loading branch information
ekryski committed Mar 28, 2016
1 parent 6736a07 commit a0b2ed4
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 29 deletions.
24 changes: 20 additions & 4 deletions src/client/index.js
@@ -1,6 +1,13 @@
import * as hooks from './hooks';
import { connected, authenticateSocket, getJWT, getStorage, clearCookie } from './utils';
import errors from 'feathers-errors';
import * as hooks from './hooks';
import {
connected,
authenticateSocket,
logoutSocket,
getJWT,
getStorage,
clearCookie
} from './utils';

const defaults = {
cookie: 'fathers-jwt',
Expand Down Expand Up @@ -67,14 +74,23 @@ export default function(opts = {}) {
});
};

// Set our logout method with the correct socket context
app.logout = function() {
app.set('user', null);
app.set('token', null);

clearCookie(config.cookie);

// TODO (EK): invalidate token with server
return Promise.resolve(app.get('storage').setItem(config.tokenKey, ''));
// remove the token from localStorage
return Promise.resolve(app.get('storage').setItem(config.tokenKey, '')).then(() => {
// If using sockets de-authenticate the socket
if (app.io || app.primus) {
const method = app.io ? 'emit' : 'send';
const socket = app.io ? app.io : app.primus;

return logoutSocket(socket, method);
}
});
};

// Set up hook that adds adds token and user to params so that
Expand Down
18 changes: 18 additions & 0 deletions src/client/utils.js
Expand Up @@ -36,6 +36,24 @@ export function authenticateSocket(options, socket, method) {
});
}

// Returns a promise that de-authenticates a socket
export function logoutSocket(socket, method) {
return new Promise((resolve, reject) => {
// If we don't get a logged out message within 10 seconds
// consider it a failure.
const timeout = setTimeout(function() {
reject(new Error('Could not logout over socket'));
}, 10000);

socket.once('logged out', function() {
clearTimeout(timeout);
resolve();
});

socket[method]('logout');
});
}

// Returns the value for a cookie
export function getCookie(name) {
if (typeof document !== 'undefined') {
Expand Down
28 changes: 28 additions & 0 deletions src/middleware/index.js
Expand Up @@ -190,6 +190,20 @@ export let setupSocketIOAuthentication = function(app, options = {}) {
}).catch(errorHandler);
}
});

socket.on('logout', function() {

// TODO (EK): Blacklist token
try {
delete socket.feathers.token;
delete socket.feathers.user;
}
catch(error) {
return errorHandler(error);
}

socket.emit('logged out');
});
};
};

Expand Down Expand Up @@ -247,6 +261,20 @@ export let setupPrimusAuthentication = function(app, options = {}) {
}).catch(errorHandler);
}
});

socket.on('logout', function() {

// TODO (EK): Blacklist token
try {
delete socket.request.feathers.token;
delete socket.request.feathers.user;
}
catch(error) {
return errorHandler(error);
}

socket.send('logged out');
});
};
};

Expand Down
15 changes: 11 additions & 4 deletions test/client/index.test.js
Expand Up @@ -104,13 +104,13 @@ const setupTests = initApp => {
expect(response.data).to.not.equal(undefined);

return app.authenticate().then(response => {
expect(app.get('token')).to.deep.equal(response.token);
expect(app.get('token')).to.equal(response.token);
expect(app.get('user')).to.deep.equal(response.data);
}).then(done);
}).catch(done);
});

it.skip('.logout works, does not grant access to protected service', done => {
it('.logout works, does not grant access to protected service', done => {
app.authenticate({
type: 'local',
email, password
Expand All @@ -119,10 +119,17 @@ const setupTests = initApp => {
expect(response.data).to.not.equal(undefined);

app.logout().then(() => {
expect(app.get('token')).to.equal(null);
expect(app.get('user')).to.equal(null);

app.service('messages').create({ text: 'auth test message' })
.then(msg => console.log('!!!', msg))
.catch(error => console.log(error));
});
.catch(error => {
console.log(error);
expect(error.code).to.equal(401);
done();
});
}).catch(done);
}).catch(done);
});
};
Expand Down
42 changes: 21 additions & 21 deletions test/integration/rest.test.js
Expand Up @@ -30,7 +30,7 @@ describe('REST authentication', function() {
let expiredToken = jwt.sign({ id: 0 }, settings.token.secret, jwtOptions);

before((done) => {
createApplication(settings, email, password, true, (err, obj) =>{
createApplication(settings, email, password, true, (error, obj) =>{
app = obj.app;
server = obj.server;

Expand Down Expand Up @@ -58,7 +58,7 @@ describe('REST authentication', function() {
password
};

request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(200);
expect(response.request.uri.path).to.equal('/auth/failure');
done();
Expand All @@ -78,7 +78,7 @@ describe('REST authentication', function() {
};

it('redirects to success page', function(done) {
request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(200);
expect(response.request.uri.path).to.equal('/auth/success');
done();
Expand Down Expand Up @@ -115,7 +115,7 @@ describe('REST authentication', function() {
password
};

request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(401);
done();
});
Expand All @@ -127,7 +127,7 @@ describe('REST authentication', function() {
password: 'invalid'
};

request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(401);
done();
});
Expand All @@ -146,21 +146,21 @@ describe('REST authentication', function() {
};

it('returns a 201', function(done) {
request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(201);
done();
});
});

it('returns a JWT', function(done) {
request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.token).to.not.equal(undefined);
done();
});
});

it('returns the logged in user', function(done) {
request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.data.email).to.equal('test@feathersjs.com');
done();
});
Expand All @@ -183,7 +183,7 @@ describe('REST authentication', function() {
token: 'invalid'
};

request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(401);
done();
});
Expand All @@ -194,7 +194,7 @@ describe('REST authentication', function() {
token: expiredToken
};

request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(401);
done();
});
Expand All @@ -212,21 +212,21 @@ describe('REST authentication', function() {
};

it('returns a 201', function(done) {
request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(201);
done();
});
});

it('returns a JWT', function(done) {
request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.token).to.not.equal(undefined);
done();
});
});

it('returns the logged in user', function(done) {
request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.data.email).to.equal('test@feathersjs.com');
done();
});
Expand Down Expand Up @@ -260,7 +260,7 @@ describe('REST authentication', function() {
it('returns data from protected route', (done) => {
options.url = `${host}/messages/1`;

request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.id).to.equal(1);
done();
});
Expand All @@ -284,7 +284,7 @@ describe('REST authentication', function() {
it('returns updates data behind protected route', (done) => {
options.url = `${host}/messages/2`;

request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.id).to.equal(2);
expect(body.text).to.equal('new text');
done();
Expand All @@ -305,7 +305,7 @@ describe('REST authentication', function() {
it('returns data from protected route', (done) => {
options.url = `${host}/messages/1?token=${validToken}`;

request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body.id).to.equal(1);
done();
});
Expand All @@ -329,14 +329,14 @@ describe('REST authentication', function() {
});

it('returns 401', (done) => {
request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(401);
done();
});
});

it('returns error instead of data', (done) => {
request(options, function(err, response, body) {
it('returns erroror instead of data', (done) => {
request(options, function(error, response, body) {
expect(body.code).to.equal(401);
done();
});
Expand All @@ -349,14 +349,14 @@ describe('REST authentication', function() {
});

it('returns 200', (done) => {
request(options, function(err, response) {
request(options, function(error, response) {
expect(response.statusCode).to.equal(200);
done();
});
});

it('returns data', (done) => {
request(options, function(err, response, body) {
request(options, function(error, response, body) {
expect(body).to.not.equal(undefined);
done();
});
Expand Down

0 comments on commit a0b2ed4

Please sign in to comment.