diff --git a/lib/index.js b/lib/index.js index 601e02d..924d239 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,40 +1,41 @@ -var xtend = require('xtend'); -var jwt = require('jsonwebtoken'); -var UnauthorizedError = require('./UnauthorizedError'); +const xtend = require('xtend'); +const jwt = require('jsonwebtoken'); +const UnauthorizedError = require('./UnauthorizedError'); -function noQsMethod(options) { - var defaults = { required: true }; - options = xtend(defaults, options); +function noQsMethod (options) { + const defaults = { required: true }; + options = xtend(defaults, options); return function (socket) { - var server = this.server || socket.server; + const server = this.server || socket.server; if (!server.$emit) { //then is socket.io 1.0 - var Namespace = Object.getPrototypeOf(server.sockets).constructor; + const Namespace = Object.getPrototypeOf(server.sockets).constructor; if (!~Namespace.events.indexOf('authenticated')) { Namespace.events.push('authenticated'); } } - if(options.required){ - var auth_timeout = setTimeout(function () { - socket.disconnect('unauthorized'); - }, options.timeout || 5000); - } - socket.on('authenticate', function (data) { - if(options.required){ + if (options.required) { + let auth_timeout = setTimeout(function () { + socket.disconnect('unauthorized'); + }, options.timeout || 5000); + clearTimeout(auth_timeout); } + // error handler - var onError = function(err, code) { + const onError = function (err, code) { if (err) { - code = code || 'unknown'; - var error = new UnauthorizedError(code, { + code = code || 'unknown'; + + const error = new UnauthorizedError(code, { message: (Object.prototype.toString.call(err) === '[object Object]' && err.message) ? err.message : err }); - var callback_timeout; + + let callback_timeout; // If callback explicitely set to false, start timeout to disconnect socket if (options.callback === false || typeof options.callback === 'number') { if (typeof options.callback === 'number') { @@ -47,6 +48,7 @@ function noQsMethod(options) { socket.disconnect('unauthorized'); }, (options.callback === false ? 0 : options.callback)); } + socket.emit('unauthorized', error, function() { if (typeof options.callback === 'number') { clearTimeout(callback_timeout); @@ -57,30 +59,29 @@ function noQsMethod(options) { } }; - var token = options.cookie ? socket.request.cookies[options.cookie] : (data ? data.token : undefined); + const token = options.cookie ? socket.request.cookies[options.cookie] : (data ? data.token : undefined); - if(!token || typeof token !== "string") { - return onError({message: 'invalid token datatype'}, 'invalid_token'); + if (!token || typeof token !== "string") { + return onError({ message: 'invalid token datatype' }, 'invalid_token'); } // Store encoded JWT - socket[options.encodedPropertyName] = data.token; - - var onJwtVerificationReady = function(err, decoded) { + socket[options.encodedPropertyName] = token; + const onJwtVerificationReady = function (err, decoded) { if (err) { return onError(err, 'invalid_token'); } // success handler - var onSuccess = function() { + const onSuccess = function () { socket[options.decodedPropertyName] = decoded; socket.emit('authenticated'); if (server.$emit) { server.$emit('authenticated', socket); } else { //try getting the current namespace otherwise fallback to all sockets. - var namespace = (server.nsps && socket.nsp && + const namespace = (server.nsps && socket.nsp && server.nsps[socket.nsp.name]) || server.sockets; @@ -89,14 +90,14 @@ function noQsMethod(options) { } }; - if(options.additional_auth && typeof options.additional_auth === 'function') { + if (options.additional_auth && typeof options.additional_auth === 'function') { options.additional_auth(decoded, onSuccess, onError); } else { onSuccess(); } }; - var onSecretReady = function(err, secret) { + const onSecretReady = function (err, secret) { if (err || !secret) { return onError(err, 'invalid_secret'); } @@ -109,22 +110,22 @@ function noQsMethod(options) { }; } -function authorize(options, onConnection) { +function authorize (options, onConnection) { options = xtend({ decodedPropertyName: 'decoded_token', encodedPropertyName: 'encoded_token' }, options); if (!options.handshake) { return noQsMethod(options); } - var defaults = { - success: function(socket, accept){ + const defaults = { + success: function (socket, accept) { if (socket.request) { accept(); } else { accept(null, true); } }, - fail: function(error, socket, accept){ + fail: function (error, socket, accept) { if (socket.request) { accept(error); } else { @@ -133,19 +134,19 @@ function authorize(options, onConnection) { } }; - var auth = xtend(defaults, options); + const auth = xtend(defaults, options); - return function(socket, accept){ - var token, error; - var handshake = data.handshake; - var req = socket.request || socket; - var authorization_header = (req.headers || {}).authorization; + return function (socket, accept) { + let token, error; + const handshake = socket.handshake; + const req = socket.request || socket; + const authorization_header = (req.headers || {}).authorization; if (authorization_header) { - var parts = authorization_header.split(' '); + const parts = authorization_header.split(' '); if (parts.length == 2) { - var scheme = parts[0], - credentials = parts[1]; + const scheme = parts[0], + credentials = parts[1]; if (scheme.toLowerCase() === 'bearer') { token = credentials; @@ -166,7 +167,7 @@ function authorize(options, onConnection) { } // Get the token from handshake or query string - if (handshake && handshake.query.token){ + if (handshake && handshake.query.token) { token = handshake.query.token; } else if (req._query && req._query.token) { @@ -186,8 +187,7 @@ function authorize(options, onConnection) { // Store encoded JWT socket[options.encodedPropertyName] = token; - var onJwtVerificationReady = function(err, decoded) { - + const onJwtVerificationReady = function (err, decoded) { if (err) { error = new UnauthorizedError(err.code || 'invalid_token', err); return auth.fail(error, socket, accept); @@ -198,7 +198,7 @@ function authorize(options, onConnection) { return auth.success(socket, accept); }; - var onSecretReady = function(err, secret) { + const onSecretReady = function (err, secret) { if (err) { error = new UnauthorizedError(err.code || 'invalid_secret', err); return auth.fail(error, socket, accept); @@ -211,13 +211,13 @@ function authorize(options, onConnection) { }; } -function getSecret(request, secret, token, callback) { +function getSecret (request, secret, token, callback) { if (typeof secret === 'function') { if (!token) { return callback({ code: 'invalid_token', message: 'jwt must be provided' }); } - var parts = token.split('.'); + const parts = token.split('.'); if (parts.length < 3) { return callback({ code: 'invalid_token', message: 'jwt malformed' }); @@ -227,7 +227,7 @@ function getSecret(request, secret, token, callback) { return callback({ code: 'invalid_token', message: 'jwt signature is required' }); } - var decodedToken = jwt.decode(token); + let decodedToken = jwt.decode(token); if (!decodedToken) { return callback({ code: 'invalid_token', message: 'jwt malformed' }); diff --git a/package.json b/package.json index 055d2e5..7118d2a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ }, "license": "MIT", "dependencies": { + "jsonwebtoken": "^8.3.0", + "xtend": "~2.1.2" }, "devDependencies": { "@types/socket.io": "~1.4.29", @@ -30,10 +32,8 @@ "express": "~4.15.2", "mocha": "~3.2.0", "request": "~2.81.0", - "serve-static": "^1.12.1", - "jsonwebtoken": "^8.3.0", - "xtend": "~2.1.2", - "q": "^1.4.1", + "serve-static": "^1.13.2", + "q": "^1.5.1", "server-destroy": "~1.0.1", "should": "~11.2.1", "socket.io": "^1.7.3",