smartsocket/ts/smartsocket.classes.socketconnection.ts

155 lines
5.0 KiB
TypeScript
Raw 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
2018-03-15 01:29:40 +00:00
import { Objectmap } from '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 {
2018-03-15 01:29:40 +00:00
alias: string;
side: TSocketConnectionSide;
authenticated: boolean = false;
role: SocketRole;
smartsocketHost: Smartsocket;
socket: any; // SocketIO.Socket | SocketIOClient.Socket
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', () => {
2018-03-15 01:29:40 +00:00
plugins.beautylog.info(
`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.smartq.defer();
2017-07-07 20:02:19 +00:00
this.socket.on('dataAuth', (dataArg: ISocketConnectionAuthenticationObject) => {
2018-03-15 01:29:40 +00:00
plugins.beautylog.log('received authentication data. now hashing and comparing...');
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.beautylog.ok(
`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.smartq.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
2018-03-15 01:29:40 +00:00
plugins.beautylog.log('function request received');
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) {
2018-03-15 01:29:40 +00:00
plugins.beautylog.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 {
2018-03-15 01:29:40 +00:00
plugins.beautylog.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) => {
2018-03-15 01:29:40 +00:00
plugins.beautylog.info(`received response for request with id ${dataArg.shortId}`);
let targetSocketRequest = helpers.getSocketRequestById(dataArg.shortId);
targetSocketRequest.handleResponse(dataArg);
});
plugins.beautylog.log(`now listening to function requests for ${this.alias}`);
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.beautylog.error(errMessage);
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 ----------------------
}