Asymmetrik/mean2-starter

View on GitHub
src/server/app/notifications/sockets/notification.server.socket.js

Summary

Maintainability
D
2 days
Test Coverage
'use strict';

let path = require('path'),
    nodeUtil = require('util'),

    deps = require(path.resolve('./src/server/dependencies')),
    config = require(path.resolve('./src/server/config')),

    logger = deps.logger,
    socketIO = deps.socketIO,

    socketProvider = require(path.resolve(config.socketProvider)),
    users = require(path.resolve('./src/server/app/admin/controllers/users.server.controller.js')),

    emitName = 'notification';

/**
 * NotificationSocket Socket Controller that overrides Base Socket Controller
 * methods to handle specifics of Notifications
 */
function NotificationSocket(socketConfig) {
    this._emitType = `${emitName}:data`;
    this._topicName = config.dispatcher ? config.dispatcher.notificationTopic : '';
    this._subscriptionCount = 0;
    socketProvider.apply(this, arguments);
}

nodeUtil.inherits(NotificationSocket, socketProvider);

NotificationSocket.prototype.name = 'NotificationSocket';

/**
 * @override
 *
 */
NotificationSocket.prototype.getEmitNotificationKey = () => {
    return '';
};

NotificationSocket.prototype.getEmitMessage = function(json, rawMessage, consumer) {
    return {
        value: json,
        key: this.getEmitMessageKey(json, rawMessage, consumer)
    };
};
//
NotificationSocket.prototype.ignorePayload = function(json) {
    // Ignore any payloads that do not match the current user.
    return !json || !json.user || json.user.toString() !== this.getUserId().toString();
};

/**
 * Returns the topic for a user ID.
 */
NotificationSocket.prototype.getTopic = function(userId) {
    return this._topicName;
};

/**
 * Handle socket disconnects
 */
NotificationSocket.prototype.disconnect = function() {
    logger.info('NotificationSocket: Disconnected from client.');

    this.unsubscribe(this.getTopic());

};

/**
 * Handle socket errors
 */
NotificationSocket.prototype.error = function(err) {
    logger.error(err, 'NotificationSocket: Client connection error');

    this.unsubscribe(this.getTopic());
};

/**
 *
 */
NotificationSocket.prototype.handleSubscribe = function(payload) {
    let self = this;

    if(logger.debug()) {
        logger.debug(`NotificationSocket: ${emitName}:subscribe event with payload: ${JSON.stringify(payload)}`);
    }

    // Check that the user account has access
    self.applyMiddleware([
        users.hasAccess
    ]).then(() => {
        // Subscribe to the user's notification topic
        let topic = self.getTopic();
        self.subscribe(topic);
        self._subscriptionCount++;
    }, (err) => {
        logger.warn(`Unauthorized access to notifications by inactive user ${self.getUserId()}: ${err}`);
    });
};

/**
 *
 */
NotificationSocket.prototype.handleUnsubscribe = function(payload) {
    if(logger.debug()) {
        logger.debug(`NotificationSocket: ${emitName}:unsubscribe event with payload: ${JSON.stringify(payload)}`);
    }

    let topic = this.getTopic();
    this.unsubscribe(topic);

    this._subscriptionCount = Math.max(0, this._subscriptionCount - 1);
    // If we are no longer listening for anything, unsubscribe
    if (this._subscriptionCount === 0) {
        this.unsubscribe(this.getTopic());
    }
};

/**
 *
 */
NotificationSocket.prototype.addListeners = function() {
    let s = this.getSocket();

    if(typeof s.on === 'function') {
        // Set up Subscribe events
        s.on(`${emitName}:subscribe`, this.handleSubscribe.bind(this));

        // Set up Unsubscribe events
        s.on(`${emitName}:unsubscribe`, this.handleUnsubscribe.bind(this));
    }
};

if (config.dispatcher && (!config.dispatcher.hasOwnProperty('enabled') || config.dispatcher.enabled)) {
    socketIO.registerSocketListener(NotificationSocket);
}

module.exports = NotificationSocket;