Asymmetrik/mean2-starter

View on GitHub
src/server/lib/socket.io.js

Summary

Maintainability
A
1 hr
Test Coverage
'use strict';

// Load the module dependencies
let
    cookieParser = require('cookie-parser'),
    http = require('http'),
    passport = require('passport'),
    path = require('path'),
    socketio = require('socket.io'),
    session = require('express-session'),
    MongoStore = require('connect-mongo')(session),

    config = require(path.resolve('./src/server/config.js')),
    logger = require(path.resolve('./src/server/lib/bunyan.js')).logger;

/**
 * Controllers created outside of this class will register
 * themselves as socket listeners, with function definitions
 * stored here.
 */
var registeredSocketListeners = [];

// Give each socket connection its own variable scope
function onConnect(socket) {
    logger.debug('SocketIO: New client connection');

    /**
     * Setup Socket Event Handlers
     */
    registeredSocketListeners.forEach(function(S) {
        new S({ socket: socket });
    });
}

// Define the Socket.io configuration method
module.exports = function(app, db) {

    // Create a new HTTP server
    logger.info('Creating HTTP Server');
    var server = http.createServer(app);

    // Create a new Socket.io server
    logger.info('Creating SocketIO Server');
    var io = socketio.listen(server);

    // Create a MongoDB storage object
    var mongoStore = new MongoStore({
        db: db.connection.db,
        collection: config.auth.sessionCollection
    });

    // Intercept Socket.io's handshake request
    io.use(function(socket, next) {
        // Use the 'cookie-parser' module to parse the request cookies
        cookieParser(config.auth.sessionSecret)(socket.request, {}, function(err) {
            // Get the session id from the request cookies
            var sessionId = socket.request.signedCookies['connect.sid'];

            // Use the mongoStorage instance to get the Express session information
            mongoStore.get(sessionId, function(err, session) {
                // Set the Socket.io session information
                socket.request.session = session;

                // Use Passport to populate the user details
                passport.initialize()(socket.request, {}, function() {
                    passport.session()(socket.request, {}, function() {
                        if (socket.request.user) {
                            logger.debug('SocketIO: New authenticated user: %s', socket.request.user.username);
                            next(null, true);
                        } else {
                            logger.info('SocketIO: Unauthenticated user attempting to connect.');
                            next(new Error('User is not authenticated'), false);
                        }
                    });
                });
            });
        });
    });

    // Add an event listener to the 'connection' event
    io.on('connection', onConnect);

    return server;
};

/*
 * App-specific function to register controllers that will be
 * sent the socket
 */
module.exports.registerSocketListener = function(s) {
    var name = s;
    if (null != s.prototype.name) {
        name = s.prototype.name;
    }

    logger.info('Registering Socket Listener: %s', name);
    registeredSocketListeners.push(s);
};