UNPKG

@aarconada/urserver

Version:

Basic Server definitions to develope REST API with a node + express Server

161 lines (156 loc) 10.3 kB
const server = require('./server')(); const _ = require('lodash'); var io = null; const events = { EntityCreated : '_CREATED', EntityUpdated : '_UPDATED', EntityDeleted : '_DELETED', EntityDeletedAll : '_DELETED_ALL' } module.exports.Events = events; const validSockets = []; const validSubscriptions = []; module.exports.initialize = function () { if (!_.isUndefined(server.configuration.socket)) { if (server.configuration.socket.enabled) { server.debug('Initializing socket...'); if (server.configuration.https.enabled) { const serverOptions = {}; if(!_.isNull(server.configuration.https.keyFilename)) serverOptions.key = server.fileSystem.readFile(server.configuration.https.folder, server.configuration.https.keyFilename); if(!_.isNull(server.configuration.https.certFilename)) serverOptions.cert = server.fileSystem.readFile(server.configuration.https.folder, server.configuration.https.certFilename); if(!_.isNull(server.configuration.https.caFilename)) serverOptions.ca = server.fileSystem.readFile(server.configuration.https.folder, server.configuration.https.caFilename); serverOptions.requestCert = false; serverOptions.rejectUnauthorized = false; this.socketServer = require('https').createServer(serverOptions, server.app); } else this.socketServer = require('http').createServer(server.app); this.socketServer.listen(server.configuration.socket.port, '0.0.0.0', function () { server.debug('%s Socket Server listening on port %s', server.configuration.https.enabled ? 'HTTPS' : 'HTTP', server.configuration.socket.port); }); io = require('socket.io')(this.socketServer, { forceNew: true, handlePreflightRequest: function (req, res) { var headers = { 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Allow-Origin': server.configuration.socket.origins, 'Access-Control-Allow-Credentials': true }; res.writeHead(200, headers); res.end(); } }); io.on('connection', function (socket) { const receivedSocketHeaders = socket.handshake.headers; if (_.isUndefined(receivedSocketHeaders) || _.isUndefined(receivedSocketHeaders[server.configuration.socket.header])) { server.debug('Socket without valid Authorization token...'); socket.disconnect('Unauthorized'); } else { server.debug(receivedSocketHeaders[server.configuration.socket.header]); if (server.token.bearerTokenCheckFromValue(receivedSocketHeaders[server.configuration.socket.header]) === server.defaultResponses.success) { validSockets.push(socket); server.debug('New Connection', validSockets.length); socket.on('disconnect', function () { const currentSocketIndex = validSockets.indexOf(socket); server.debug('Closing socket with index:', currentSocketIndex); if (currentSocketIndex !== -1) { validSockets.splice(currentSocketIndex, 1); } var currentSubsctiptionIndex = validSubscriptions.map((currentElement) => { return currentElement.socket; }).indexOf(socket); while (currentSubsctiptionIndex !== -1) { validSubscriptions.splice(currentSubsctiptionIndex, 1); currentSubsctiptionIndex = validSubscriptions.map((currentElement) => { return currentElement.socket; }).indexOf(socket); } server.debug('Connection closed'); }); socket.on('ping', function () { if (validSockets.filter(currentSocket => currentSocket === socket) === null) { socket.emit('UNSUBSCRIBE_KO', {code: '0005', message: 'unauthorized'}); return; } socket.emit('pong'); }); socket.on('SUBSCRIBE', function (subscriptionData) { if (validSockets.filter(currentSocket => currentSocket === socket) === null) { socket.emit('UNSUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0005', message: 'unauthorized'}); return; } if (_.isUndefined(subscriptionData) || _.isNull(subscriptionData)) { socket.emit('SUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0001', message: 'missing subscription data'}); return; } if (_.isUndefined(subscriptionData.eventName) || _.isEmpty(subscriptionData.eventName)) { socket.emit('SUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0002', message: 'missing event name'}); return; } for (var i = 0; i < validSubscriptions.length; i++) { const currentSubscription = validSubscriptions[i]; if (currentSubscription.socket === socket && currentSubscription.eventName === subscriptionData.eventName) { socket.emit('SUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0003', message: 'subscription exists yet'}); return; } } subscriptionData.socket = socket; validSubscriptions.push(subscriptionData); socket.emit('SUBSCRIBE_OK', {eventName: subscriptionData.eventName}); }); socket.on('UNSUBSCRIBE', function (subscriptionData) { if (validSockets.filter(currentSocket => currentSocket === socket) === null) { socket.emit('UNSUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0005', message: 'unauthorized'}); return; } if (_.isUndefined(subscriptionData) || _.isNull(subscriptionData)) { socket.emit('UNSUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0001', message: 'missing subscription data'}); return; } if (_.isUndefined(subscriptionData.eventName) || _.isEmpty(subscriptionData.eventName)) { socket.emit('UNSUBSCRIBE_KO', {eventName: subscriptionData.eventName, code: '0002', message: 'missing event name'}); return; } for (var i = 0; i < validSubscriptions.length; i++) { const currentSubscription = validSubscriptions[i]; if (currentSubscription.socket === socket && currentSubscription.eventName === subscriptionData.eventName) { validSubscriptions.splice(i, 1); socket.emit('UNSUBSCRIBE_OK', {eventName: subscriptionData.eventName}); return; } } socket.emit('UNSUBSCRIBE_KO', {code: '0004', message: 'subscription does not exists'}); }); } else { server.debug('Socket with unknown Authorization token...'); socket.disconnect('Unauthorized'); } } }); } } }; module.exports.Emit = function(event, data) { if(server.configuration.socket.enabled && !_.isNull(this.io) && validSubscriptions.length > 0) { validSubscriptions.forEach(currentSubscription => { server.debug('Checking subscription with event name', currentSubscription.eventName); if(currentSubscription.eventName === event) { server.debug('Checking filters', currentSubscription.filters); const currentSocket = currentSubscription.socket; const currentFilters = currentSubscription.filters; const currentSocketHeaders = currentSocket.handshake.headers; server.debug(currentSocketHeaders); if (!_.isUndefined(currentSocketHeaders) && !_.isUndefined(currentSocketHeaders[server.configuration.socket.header])) { if (server.token.bearerTokenCheckFromValue(currentSocketHeaders[server.configuration.socket.header]) === server.defaultResponses.success) { var sendEventToCurrentSocket = _.isUndefined(currentFilters) || _.isNull(currentFilters) || currentFilters.length === 0 || server.utils.contains(data, currentFilters); server.debug('Send?', sendEventToCurrentSocket); if (sendEventToCurrentSocket) currentSocket.emit(event, data); } } } }); } }