diff --git a/lib/index.js b/lib/index.js index 986fa0d..e53aa5d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,11 +7,11 @@ function noQsMethod(options) { options = xtend(defaults, options); return function (socket) { - var server = this; + var server = this.server || socket.server; if (!server.$emit) { //then is socket.io 1.0 - var Namespace = Object.getPrototypeOf(server.server.sockets).constructor; + var Namespace = Object.getPrototypeOf(server.sockets).constructor; if (!~Namespace.events.indexOf('authenticated')) { Namespace.events.push('authenticated'); } @@ -53,8 +53,13 @@ function noQsMethod(options) { if (server.$emit) { server.$emit('authenticated', socket); } else { + //try getting the current namespace otherwise fallback to all sockets. + var namespace = (server.nsps && socket.nsp && + server.nsps[socket.nsp.name]) || + server.sockets; + // explicit namespace - server.server.nsps[socket.nsp.name].emit('authenticated', socket); + namespace.emit('authenticated', socket); } }; diff --git a/package.json b/package.json index efbf6af..3f9f522 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "mocha": "~1.17.0", "passport-local": "~0.1.6", "request": "~2.19.0", + "server-destroy": "~1.0.1", "should": "~1.2.2", "socket.io": "^1.0.4", "socket.io-client": "^1.0.4" diff --git a/test/authorizer_namespaces.test.js b/test/authorizer_namespaces.test.js new file mode 100644 index 0000000..84785b3 --- /dev/null +++ b/test/authorizer_namespaces.test.js @@ -0,0 +1,54 @@ +var fixture = require('./fixture/namespace'); +var request = require('request'); +var io = require('socket.io-client'); + +describe('authorizer with namespaces', function () { + + //start and stop the server + before(fixture.start); + + after(fixture.stop); + + describe('when the user is not logged in', function () { + + it('should be able to connect to the default namespace', function (done){ + var socket = io.connect('http://localhost:9000'); + socket.once('hi', done); + }); + + it('should not be able to connect to the admin namespace', function (done){ + var socket = io.connect('http://localhost:9000/admin'); + socket.once('disconnect', function () { + done(); + }); + }); + + }); + + describe('when the user is logged in', function() { + + beforeEach(function (done) { + request.post({ + url: 'http://localhost:9000/login', + form: { username: 'jose', password: 'Pa123' }, + json: true + }, function (err, resp, body) { + this.token = body.token; + done(); + }.bind(this)); + }); + + it('should do the handshake and connect', function (done){ + var socket = io.connect('http://localhost:9000/admin', { + 'forceNew': true, + }); + var token = this.token; + socket.on('connect', function(){ + socket.on('authenticated', function () { + done(); + }).emit('authenticate', { token: token }); + }); + }); + }); + +}); \ No newline at end of file diff --git a/test/authorizer_noqs.test.js b/test/authorizer_noqs.test.js index ed49a1d..53ef9ca 100644 --- a/test/authorizer_noqs.test.js +++ b/test/authorizer_noqs.test.js @@ -16,8 +16,10 @@ describe('authorizer without querystring', function () { describe('when the user is not logged in', function () { it('should close the connection after a timeout if no auth message is received', function (done){ - var socket = io.connect('http://localhost:9000'); - socket.on('disconnect', function () { + var socket = io.connect('http://localhost:9000', { + forceNew: true + }); + socket.once('disconnect', function () { done(); }); }); diff --git a/test/fixture/index.js b/test/fixture/index.js index 126514e..b57f766 100644 --- a/test/fixture/index.js +++ b/test/fixture/index.js @@ -9,6 +9,7 @@ var jwt = require('jsonwebtoken'); var xtend = require('xtend'); var server, sio; +var enableDestroy = require('server-destroy'); exports.start = function (options, callback) { @@ -49,11 +50,8 @@ exports.start = function (options, callback) { sio = socketIo.listen(server); if (options.handshake) { - // this.set('authorization', socketio_jwt.authorize(options)); sio.use(socketio_jwt.authorize(options)); - } - if (options.handshake) { sio.sockets.on('echo', function (m) { sio.sockets.emit('echo-response', m); }); @@ -72,9 +70,11 @@ exports.start = function (options, callback) { server.__sockets.push(c); }); server.listen(9000, callback); + enableDestroy(server); }; exports.stop = function (callback) { sio.close(); + server.destroy(); callback(); }; \ No newline at end of file diff --git a/test/fixture/namespace.js b/test/fixture/namespace.js new file mode 100644 index 0000000..5078d74 --- /dev/null +++ b/test/fixture/namespace.js @@ -0,0 +1,72 @@ +var express = require('express'); +var http = require('http'); + +var socketIo = require('socket.io'); +var socketio_jwt = require('../../lib'); + +var jwt = require('jsonwebtoken'); + +var xtend = require('xtend'); + +var server, sio; +var enableDestroy = require('server-destroy'); + +/** + * This is an example server that shows how to do namespace authentication. + * + * The /admin namespace is protected by JWTs while the global namespace is public. + */ +exports.start = function (callback) { + + options = { + secret: 'aaafoo super sercret', + timeout: 1000, + handshake: false + }; + + var app = express(); + + app.configure(function(){ + this.use(express.json()); + this.use(express.urlencoded()); + }); + + app.post('/login', function (req, res) { + var profile = { + first_name: 'John', + last_name: 'Doe', + email: 'john@doe.com', + id: 123 + }; + + // We are sending the profile inside the token + var token = jwt.sign(profile, options.secret, { expiresInMinutes: 60*5 }); + + res.json({token: token}); + }); + + server = http.createServer(app); + + sio = socketIo.listen(server); + + sio.on('connection', function (socket) { + socket.emit('hi'); + }); + + var admin_nsp = sio.of('/admin'); + + admin_nsp.on('connection', socketio_jwt.authorize(options)) + .on('authenticated', function (socket) { + socket.emit('hi admin'); + }); + + + server.listen(9000, callback); + enableDestroy(server); +}; + +exports.stop = function (callback) { + sio.close(); + server.destroy(); + callback(); +}; \ No newline at end of file