smartsocket/ts/smartsocket.classes.socketconnection.ts

141 lines
5.3 KiB
TypeScript
Raw Normal View History

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