smartsocket/ts/smartsocket.classes.socketconnection.ts

169 lines
5.3 KiB
TypeScript
Raw Permalink Normal View History

2018-03-15 01:29:40 +00:00
import * as plugins from './smartsocket.plugins';
import * as helpers from './smartsocket.helpers';
2016-08-08 16:20:00 +00:00
import { Objectmap } from '@pushrocks/lik';
2016-08-08 16:20:00 +00:00
// import classes
2018-03-15 01:29:40 +00:00
import { Smartsocket } from './smartsocket.classes.smartsocket';
import { SocketFunction } from './smartsocket.classes.socketfunction';
import {
SocketRequest,
ISocketRequestDataObject,
allSocketRequests
} from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole';
// socket.io
import * as SocketIO from 'socket.io';
2016-08-08 16:20:00 +00:00
2016-08-09 09:42:21 +00:00
// export interfaces
/**
* defines is a SocketConnection is server or client side. Important for mesh setups.
*/
2018-03-15 01:29:40 +00:00
export type TSocketConnectionSide = 'server' | 'client';
2016-08-09 09:42:21 +00:00
/**
* interface for constructor of class SocketConnection
*/
2016-08-11 23:32:57 +00:00
export interface ISocketConnectionConstructorOptions {
2018-03-15 01:29:40 +00:00
alias: string;
authenticated: boolean;
role: SocketRole;
side: TSocketConnectionSide;
smartsocketHost: Smartsocket;
socket: SocketIO.Socket | SocketIOClient.Socket;
2017-07-07 20:02:19 +00:00
}
2016-08-08 16:20:00 +00:00
2016-08-09 09:42:21 +00:00
/**
* interface for authentication data
*/
export interface ISocketConnectionAuthenticationObject {
2018-03-15 01:29:40 +00:00
role: 'coreflowContainer';
password: 'somePassword';
alias: 'coreflow1';
2017-07-07 20:02:19 +00:00
}
2016-08-09 09:42:21 +00:00
// export classes
2018-03-15 01:29:40 +00:00
export let allSocketConnections = new Objectmap<SocketConnection>();
2016-08-09 09:42:21 +00:00
/**
* class SocketConnection represents a websocket connection
*/
2016-08-08 16:20:00 +00:00
export class SocketConnection {
2019-06-07 06:40:24 +00:00
public alias: string;
public side: TSocketConnectionSide;
public authenticated: boolean = false;
public role: SocketRole;
public smartsocketHost: Smartsocket;
public socket: SocketIO.Socket | SocketIOClient.Socket;
2018-03-15 01:29:40 +00:00
constructor(optionsArg: ISocketConnectionConstructorOptions) {
this.alias = optionsArg.alias;
this.authenticated = optionsArg.authenticated;
this.role = optionsArg.role;
this.side = optionsArg.side;
this.smartsocketHost = optionsArg.smartsocketHost;
this.socket = optionsArg.socket;
2016-08-12 01:22:36 +00:00
2017-07-07 20:02:19 +00:00
// standard behaviour that is always true
2018-03-15 01:29:40 +00:00
allSocketConnections.add(this);
2017-07-07 20:02:19 +00:00
this.socket.on('disconnect', () => {
plugins.smartlog.defaultLogger.log(
'info',
2018-03-15 01:29:40 +00:00
`SocketConnection with >alias ${this.alias} on >side ${this.side} disconnected`
);
this.socket.disconnect();
allSocketConnections.remove(this);
});
2017-07-07 20:02:19 +00:00
}
2016-08-12 01:22:36 +00:00
2017-07-07 20:02:19 +00:00
// authenticating --------------------------
2016-08-08 16:20:00 +00:00
2017-07-07 20:02:19 +00:00
/**
* authenticate the socket
*/
2018-03-15 01:29:40 +00:00
authenticate() {
let done = plugins.smartpromise.defer();
2017-07-07 20:02:19 +00:00
this.socket.on('dataAuth', (dataArg: ISocketConnectionAuthenticationObject) => {
plugins.smartlog.defaultLogger.log(
'info',
'received authentication data. now hashing and comparing...'
);
2018-03-15 01:29:40 +00:00
this.socket.removeListener('dataAuth', () => {});
if (helpers.checkPasswordForRole(dataArg, this.smartsocketHost)) {
// TODO: authenticate password
this.alias = dataArg.alias;
this.authenticated = true;
this.role = helpers.getSocketRoleByName(dataArg.role, this.smartsocketHost);
this.socket.emit('authenticated');
plugins.smartlog.defaultLogger.log(
'ok',
2018-03-15 01:29:40 +00:00
`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`
);
done.resolve(this);
2017-07-07 20:02:19 +00:00
} else {
2018-03-15 01:29:40 +00:00
this.authenticated = false;
this.socket.disconnect();
done.reject('not authenticated');
2017-07-07 20:02:19 +00:00
}
2018-03-15 01:29:40 +00:00
});
this.socket.emit('requestAuth');
return done.promise;
2017-07-07 20:02:19 +00:00
}
2016-08-12 01:22:36 +00:00
2017-07-07 20:02:19 +00:00
// listening -------------------------------
/**
* listen to function requests
*/
2018-03-15 01:29:40 +00:00
listenToFunctionRequests() {
let done = plugins.smartpromise.defer();
2017-07-07 20:02:19 +00:00
if (this.authenticated) {
this.socket.on('function', (dataArg: ISocketRequestDataObject) => {
// check if requested function is available to the socket's scope
plugins.smartlog.defaultLogger.log('info', 'function request received');
2018-03-15 01:29:40 +00:00
let referencedFunction: SocketFunction = this.role.allowedFunctions.find(
socketFunctionArg => {
return socketFunctionArg.name === dataArg.funcCallData.funcName;
}
);
2017-07-07 20:02:19 +00:00
if (referencedFunction !== undefined) {
plugins.smartlog.defaultLogger.log('ok', 'function in access scope');
2017-07-07 20:02:19 +00:00
let localSocketRequest = new SocketRequest({
side: 'responding',
originSocketConnection: this,
shortId: dataArg.shortId,
funcCallData: dataArg.funcCallData
2018-03-15 01:29:40 +00:00
});
localSocketRequest.createResponse(); // takes care of creating response and sending it back
2016-08-08 16:20:00 +00:00
} else {
plugins.smartlog.defaultLogger.log(
'warn',
'function not existent or out of access scope'
);
2017-07-07 20:02:19 +00:00
}
2018-03-15 01:29:40 +00:00
});
2017-07-07 20:02:19 +00:00
this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject) => {
plugins.smartlog.defaultLogger.log(
'info',
`received response for request with id ${dataArg.shortId}`
);
2018-03-15 01:29:40 +00:00
let targetSocketRequest = helpers.getSocketRequestById(dataArg.shortId);
targetSocketRequest.handleResponse(dataArg);
});
plugins.smartlog.defaultLogger.log(
'info',
`now listening to function requests for ${this.alias}`
);
2018-03-15 01:29:40 +00:00
done.resolve(this);
2017-07-07 20:02:19 +00:00
} else {
2018-03-15 01:29:40 +00:00
let errMessage: 'socket needs to be authenticated first';
plugins.smartlog.defaultLogger.log('error', errMessage);
2018-03-15 01:29:40 +00:00
done.reject(errMessage);
2017-07-07 20:02:19 +00:00
}
2018-03-15 01:29:40 +00:00
return done.promise;
2017-07-07 20:02:19 +00:00
}
// sending ----------------------
}