import * as plugins from "./smartsocket.plugins"; import * as helpers from "./smartsocket.helpers"; // import classes import { SocketFunction } from "./smartsocket.classes.socketfunction"; import { SocketRequest, ISocketRequestDataObject, allSocketRequests } from "./smartsocket.classes.socketrequest"; import { SocketRole } from "./smartsocket.classes.socketrole"; // export interfaces /** * interface for constructor of class SocketConnection */ export interface ISocketConnectionConstructorOptions { alias: string; authenticated: boolean; role: SocketRole; socket: SocketIO.Socket | SocketIOClient.Socket; }; /** * interface for authentication data */ export interface ISocketConnectionAuthenticationObject { role: "coreflowContainer", password: "somePassword", alias: "coreflow1" } // export classes /** * class SocketConnection represents a websocket connection */ export class SocketConnection { alias: string; authenticated: boolean = false; role: SocketRole; socket: SocketIO.Socket | SocketIOClient.Socket; constructor(optionsArg: ISocketConnectionConstructorOptions) { this.alias = optionsArg.alias; this.authenticated = optionsArg.authenticated; this.role = optionsArg.role; this.socket = optionsArg.socket; // standard behaviour that is always true this.socket.on("disconnect", () => { plugins.beautylog.info(`Client ${this.alias} disconnected`); }); }; // authenticating -------------------------- /** * authenticate the socket */ authenticate() { let done = plugins.q.defer(); this.socket.on("dataAuth", dataArg => { plugins.beautylog.log("received authentication data. now hashing and comparing..."); this.socket.removeListener("dataAuth", () => { }); if ((true)) { // TODO: authenticate password this.alias = dataArg.alias this.authenticated = true; this.role = helpers.getSocketRoleByName(dataArg.role); this.socket.emit("authenticated"); plugins.beautylog.ok(`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`); done.resolve(this); } else { this.authenticated = false; this.socket.disconnect(); done.reject("not authenticated"); }; }); this.socket.emit("requestAuth"); return done.promise; }; // listening ------------------------------- /** * listen to function requests */ listenToFunctionRequests(){ let done = plugins.q.defer(); if(this.authenticated){ this.socket.on("function", (dataArg:ISocketRequestDataObject) => { // check if requested function is available to the socket's scope plugins.beautylog.log("function request received"); let referencedFunction:SocketFunction = this.role.allowedFunctions.find((socketFunctionArg) => { return socketFunctionArg.name === dataArg.funcCallData.funcName; }); if(referencedFunction !== undefined){ plugins.beautylog.ok!("function in access scope"); let localSocketRequest = new SocketRequest({ side:"responding", originSocketConnection:this, shortId:dataArg.shortId, funcCallData:dataArg.funcCallData }); localSocketRequest.createResponse(); // takes care of creating response and sending it back } else { plugins.beautylog.warn("function not existent or out of access scope"); }; }); this.socket.on("functionResponse", (dataArg:ISocketRequestDataObject) => { 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); } else { let errMessage: "socket needs to be authenticated first"; plugins.beautylog.error(errMessage); done.reject(errMessage); }; return done.promise; }; // sending ---------------------- };