@aarconada/urserver
Version:
Basic Server definitions to develope REST API with a node + express Server
161 lines (156 loc) • 10.3 kB
JavaScript
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);
}
}
}
});
}
}