fix(core): update

This commit is contained in:
Philipp Kunz 2020-09-24 18:04:11 +00:00
parent b0bf9d7c95
commit 57e6f058be
17 changed files with 236 additions and 174 deletions

4
.gitignore vendored
View File

@ -15,8 +15,6 @@ node_modules/
# builds # builds
dist/ dist/
dist_web/ dist_*/
dist_serve/
dist_ts_web/
# custom # custom

View File

@ -3,14 +3,14 @@ image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache: cache:
paths: paths:
- .npmci_cache/ - .npmci_cache/
key: "$CI_BUILD_STAGE" key: '$CI_BUILD_STAGE'
stages: stages:
- security - security
- test - test
- release - release
- metadata - metadata
# ==================== # ====================
# security stage # security stage
@ -18,60 +18,74 @@ stages:
mirror: mirror:
stage: security stage: security
script: script:
- npmci git mirror - npmci git mirror
only:
- tags
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
snyk: auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security stage: security
script: script:
- npmci npm prepare - npmci npm prepare
- npmci command npm install -g snyk - npmci command npm install --production --ignore-scripts
- npmci command npm install --ignore-scripts - npmci command npm config set registry https://registry.npmjs.org
- npmci command snyk test - npmci command npm audit --audit-level=high --only=prod --production
tags: tags:
- docker - docker
- notpriv
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=dev
tags:
- docker
allow_failure: true
# ==================== # ====================
# test stage # test stage
# ==================== # ====================
testLTS: testStable:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
- npmci node install lts - npmci node install stable
- npmci npm install - npmci npm install
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - docker
- notpriv
testBuild: testBuild:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
- npmci node install lts - npmci node install stable
- npmci npm install - npmci npm install
- npmci command npm run build - npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - docker
- notpriv
release: release:
stage: release stage: release
script: script:
- npmci node install lts - npmci node install stable
- npmci npm publish - npmci npm publish
only: only:
- tags - tags
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
# ==================== # ====================
# metadata stage # metadata stage
@ -79,35 +93,39 @@ release:
codequality: codequality:
stage: metadata stage: metadata
allow_failure: true allow_failure: true
only:
- tags
script: script:
- npmci command npm install -g tslint typescript - npmci command npm install -g tslint typescript
- npmci npm prepare
- npmci npm install - npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts" - npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags: tags:
- docker - lossless
- priv - docker
- priv
trigger: trigger:
stage: metadata stage: metadata
script: script:
- npmci trigger - npmci trigger
only: only:
- tags - tags
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
pages: pages:
image: hosttoday/ht-docker-dbase:npmci
services:
- docker:18-dind
stage: metadata stage: metadata
script: script:
- npmci node install lts
- npmci command npm install -g @gitzone/tsdoc - npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare - npmci npm prepare
- npmci npm install - npmci npm install
- npmci command tsdoc - npmci command tsdoc
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
only: only:
@ -115,5 +133,5 @@ pages:
artifacts: artifacts:
expire_in: 1 week expire_in: 1 week
paths: paths:
- public - public
allow_failure: true allow_failure: true

26
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"schema": {
"type": "object",
"properties": {
"npmci": {
"type": "object",
"description": "settings for npmci"
},
"gitzone": {
"type": "object",
"description": "settings for gitzone",
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}
}
}
}
]
}

View File

@ -1,5 +1,6 @@
{ {
"gitzone": { "gitzone": {
"projectType": "npm",
"module": { "module": {
"githost": "gitlab.com", "githost": "gitlab.com",
"gitscope": "pushrocks", "gitscope": "pushrocks",

View File

@ -2,8 +2,8 @@
"name": "@pushrocks/smartsocket", "name": "@pushrocks/smartsocket",
"version": "1.1.59", "version": "1.1.59",
"description": "easy and secure websocket communication", "description": "easy and secure websocket communication",
"main": "dist/index.js", "main": "dist_ts/index.js",
"typings": "dist/index.d.ts", "typings": "dist_ts/index.d.ts",
"scripts": { "scripts": {
"test": "(tstest test/)", "test": "(tstest test/)",
"build": "(tsbuild --web)" "build": "(tsbuild --web)"
@ -44,14 +44,18 @@
}, },
"private": false, "private": false,
"files": [ "files": [
"ts/*", "ts/**/*",
"ts_web/*", "ts_web/**/*",
"dist/*", "dist/**/*",
"dist_web/*", "dist_*/**/*",
"dist_ts_web/*", "dist_ts/**/*",
"assets/*", "dist_ts_web/**/*",
"assets/**/*",
"cli.js", "cli.js",
"npmextra.json", "npmextra.json",
"readme.md" "readme.md"
],
"browserslist": [
"last 1 chrome versions"
] ]
} }

View File

@ -15,7 +15,7 @@ let testSocketFunction1: smartsocket.SocketFunction<any>;
let myseServer: smartexpress.Server; let myseServer: smartexpress.Server;
const testConfig = { const testConfig = {
port: 3000 port: 3000,
}; };
// class smartsocket // class smartsocket
@ -28,7 +28,7 @@ tap.test('Should accept an smartExpressServer as server', async () => {
myseServer = new smartexpress.Server({ myseServer = new smartexpress.Server({
cors: true, cors: true,
forceSsl: false, forceSsl: false,
port: testConfig.port port: testConfig.port,
}); });
testSmartsocket.setExternalServer('smartexpress', myseServer); testSmartsocket.setExternalServer('smartexpress', myseServer);
@ -40,7 +40,7 @@ tap.test('Should accept an smartExpressServer as server', async () => {
tap.test('should add a socketrole', async () => { tap.test('should add a socketrole', async () => {
testSocketRole1 = new smartsocket.SocketRole({ testSocketRole1 = new smartsocket.SocketRole({
name: 'testRole1', name: 'testRole1',
passwordHash: smarthash.sha256FromStringSync('testPassword') passwordHash: smarthash.sha256FromStringSync('testPassword'),
}); });
testSmartsocket.addSocketRoles([testSocketRole1]); testSmartsocket.addSocketRoles([testSocketRole1]);
}); });
@ -52,7 +52,7 @@ tap.test('should register a new Function', async () => {
funcDef: async (dataArg, socketConnectionArg) => { funcDef: async (dataArg, socketConnectionArg) => {
return dataArg; return dataArg;
}, },
funcName: 'testFunction1' funcName: 'testFunction1',
}); });
testSmartsocket.addSocketFunction(testSocketFunction1); testSmartsocket.addSocketFunction(testSocketFunction1);
console.log(testSmartsocket.socketFunctions); console.log(testSmartsocket.socketFunctions);
@ -69,14 +69,14 @@ tap.test('should react to a new websocket connection from client', async () => {
url: 'http://localhost', url: 'http://localhost',
password: 'testPassword', password: 'testPassword',
alias: 'testClient1', alias: 'testClient1',
role: 'testRole1' role: 'testRole1',
}); });
testSmartsocketClient.addSocketFunction(testSocketFunction1); testSmartsocketClient.addSocketFunction(testSocketFunction1);
console.log(testSmartsocketClient.socketFunctions); console.log(testSmartsocketClient.socketFunctions);
await testSmartsocketClient.connect(); await testSmartsocketClient.connect();
}); });
tap.test('client should disconnect and reconnect', async tools => { tap.test('client should disconnect and reconnect', async (tools) => {
await testSmartsocketClient.disconnect(); await testSmartsocketClient.disconnect();
await tools.delayFor(100); await tools.delayFor(100);
await testSmartsocketClient.connect(); await testSmartsocketClient.connect();
@ -88,7 +88,7 @@ tap.test('2 clients should connect in parallel', async () => {
tap.test('should be able to make a functionCall from client to server', async () => { tap.test('should be able to make a functionCall from client to server', async () => {
const response = await testSmartsocketClient.serverCall('testFunction1', { const response = await testSmartsocketClient.serverCall('testFunction1', {
value1: 'hello' value1: 'hello',
}); });
console.log(response); console.log(response);
}); });

View File

@ -30,12 +30,12 @@ export interface IReqResServer {
hi: string; hi: string;
}; };
response: { response: {
hi: string hi: string;
} };
} }
const testConfig = { const testConfig = {
port: 3000 port: 3000,
}; };
// class smartsocket // class smartsocket
@ -48,7 +48,7 @@ tap.test('should create a new smartsocket', async () => {
tap.test('should add a socketrole', async () => { tap.test('should add a socketrole', async () => {
testSocketRole1 = new smartsocket.SocketRole({ testSocketRole1 = new smartsocket.SocketRole({
name: 'testRole1', name: 'testRole1',
passwordHash: smarthash.sha256FromStringSync('testPassword') passwordHash: smarthash.sha256FromStringSync('testPassword'),
}); });
testSmartsocket.addSocketRoles([testSocketRole1]); testSmartsocket.addSocketRoles([testSocketRole1]);
}); });
@ -60,7 +60,7 @@ tap.test('should register a new Function', async () => {
funcDef: async (dataArg, socketConnectionArg) => { funcDef: async (dataArg, socketConnectionArg) => {
return dataArg; return dataArg;
}, },
funcName: 'testFunction1' funcName: 'testFunction1',
}); });
testSmartsocket.addSocketFunction(testSocketFunctionForServer); testSmartsocket.addSocketFunction(testSocketFunctionForServer);
@ -69,7 +69,7 @@ tap.test('should register a new Function', async () => {
funcDef: async (dataArg, socketConnectionArg) => { funcDef: async (dataArg, socketConnectionArg) => {
return dataArg; return dataArg;
}, },
funcName: 'testFunction2' funcName: 'testFunction2',
}); });
testSmartsocket.addSocketFunction(testSocketFunctionForServer); testSmartsocket.addSocketFunction(testSocketFunctionForServer);
console.log(testSmartsocket.socketFunctions); console.log(testSmartsocket.socketFunctions);
@ -86,7 +86,7 @@ tap.test('should react to a new websocket connection from client', async () => {
url: 'http://localhost', url: 'http://localhost',
password: 'testPassword', password: 'testPassword',
alias: 'testClient1', alias: 'testClient1',
role: 'testRole1' role: 'testRole1',
}); });
testSmartsocketClient.addSocketFunction(testSocketFunctionClient); testSmartsocketClient.addSocketFunction(testSocketFunctionClient);
console.log(testSmartsocketClient.socketFunctions); console.log(testSmartsocketClient.socketFunctions);
@ -99,7 +99,7 @@ tap.test('2 clients should connect in parallel', async () => {
tap.test('should be able to make a functionCall from client to server', async () => { tap.test('should be able to make a functionCall from client to server', async () => {
const response = await testSmartsocketClient.serverCall<IReqResClient>('testFunction1', { const response = await testSmartsocketClient.serverCall<IReqResClient>('testFunction1', {
value1: 'hello' value1: 'hello',
}); });
console.log(response); console.log(response);
expect(response.value1).to.equal('hello'); expect(response.value1).to.equal('hello');
@ -109,9 +109,9 @@ tap.test('should be able to make a functionCall from server to client', async ()
const response = await testSmartsocket.clientCall<IReqResServer>( const response = await testSmartsocket.clientCall<IReqResServer>(
'testFunction2', 'testFunction2',
{ {
hi: 'hi there from server' hi: 'hi there from server',
}, },
testSmartsocket.socketConnections.find(socketConnection => { testSmartsocket.socketConnections.find((socketConnection) => {
return true; return true;
}) })
); );
@ -119,7 +119,7 @@ tap.test('should be able to make a functionCall from server to client', async ()
expect(response.hi).to.equal('hi there from server'); expect(response.hi).to.equal('hi there from server');
}); });
tap.test('client should disconnect and reconnect', async tools => { tap.test('client should disconnect and reconnect', async (tools) => {
await testSmartsocketClient.disconnect(); await testSmartsocketClient.disconnect();
await tools.delayFor(100); await tools.delayFor(100);
await testSmartsocketClient.connect(); await testSmartsocketClient.connect();

View File

@ -2,4 +2,9 @@ export interface IRequestAuthPayload {
serverShortId: string; serverShortId: string;
} }
export type TConnectionStatus = 'new' | 'connecting' | 'connected' | 'disconnecting' | 'disconnected'; export type TConnectionStatus =
| 'new'
| 'connecting'
| 'connected'
| 'disconnecting'
| 'disconnected';

View File

@ -2,7 +2,11 @@ import * as plugins from './smartsocket.plugins';
// classes // classes
import { SocketConnection } from './smartsocket.classes.socketconnection'; import { SocketConnection } from './smartsocket.classes.socketconnection';
import { ISocketFunctionCallDataRequest, SocketFunction, ISocketFunctionCallDataResponse } from './smartsocket.classes.socketfunction'; import {
ISocketFunctionCallDataRequest,
SocketFunction,
ISocketFunctionCallDataResponse,
} from './smartsocket.classes.socketfunction';
import { SocketRequest } from './smartsocket.classes.socketrequest'; import { SocketRequest } from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole'; import { SocketRole } from './smartsocket.classes.socketrole';
import { SocketServer } from './smartsocket.classes.socketserver'; import { SocketServer } from './smartsocket.classes.socketserver';
@ -44,7 +48,7 @@ export class Smartsocket {
public async start() { public async start() {
this.io = plugins.socketIo(this.socketServer.getServerForSocketIo()); this.io = plugins.socketIo(this.socketServer.getServerForSocketIo());
await this.socketServer.start(); await this.socketServer.start();
this.io.on('connection', socketArg => { this.io.on('connection', (socketArg) => {
this._handleSocketConnection(socketArg); this._handleSocketConnection(socketArg);
}); });
} }
@ -55,10 +59,7 @@ export class Smartsocket {
public async stop() { public async stop() {
await plugins.smartdelay.delayFor(1000); await plugins.smartdelay.delayFor(1000);
this.socketConnections.forEach((socketObjectArg: SocketConnection) => { this.socketConnections.forEach((socketObjectArg: SocketConnection) => {
logger.log( logger.log('info', `disconnect socket with >>alias ${socketObjectArg.alias}`);
'info',
`disconnect socket with >>alias ${socketObjectArg.alias}`
);
socketObjectArg.socket.disconnect(); socketObjectArg.socket.disconnect();
}); });
this.socketConnections.wipe(); this.socketConnections.wipe();
@ -81,11 +82,11 @@ export class Smartsocket {
const socketRequest = new SocketRequest<T>(this, { const socketRequest = new SocketRequest<T>(this, {
funcCallData: { funcCallData: {
funcDataArg: dataArg, funcDataArg: dataArg,
funcName: functionNameArg funcName: functionNameArg,
}, },
originSocketConnection: targetSocketConnectionArg, originSocketConnection: targetSocketConnectionArg,
shortId: plugins.smartunique.shortId(), shortId: plugins.smartunique.shortId(),
side: 'requesting' side: 'requesting',
}); });
const response: ISocketFunctionCallDataResponse<T> = await socketRequest.dispatch(); const response: ISocketFunctionCallDataResponse<T> = await socketRequest.dispatch();
const result = response.funcDataArg; const result = response.funcDataArg;
@ -116,7 +117,7 @@ export class Smartsocket {
role: undefined, role: undefined,
side: 'server', side: 'server',
smartsocketHost: this, smartsocketHost: this,
socket: socketArg socket: socketArg,
}); });
logger.log('info', 'Socket connected. Trying to authenticate...'); logger.log('info', 'Socket connected. Trying to authenticate...');
this.socketConnections.add(socketConnection); this.socketConnections.add(socketConnection);

View File

@ -2,7 +2,10 @@ import * as plugins from './smartsocket.plugins';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces';
import { SocketConnection } from './smartsocket.classes.socketconnection'; import { SocketConnection } from './smartsocket.classes.socketconnection';
import { ISocketFunctionCallDataRequest, SocketFunction } from './smartsocket.classes.socketfunction'; import {
ISocketFunctionCallDataRequest,
SocketFunction,
} from './smartsocket.classes.socketfunction';
import { ISocketRequestDataObject, SocketRequest } from './smartsocket.classes.socketrequest'; import { ISocketRequestDataObject, SocketRequest } from './smartsocket.classes.socketrequest';
import { SocketRole } from './smartsocket.classes.socketrole'; import { SocketRole } from './smartsocket.classes.socketrole';
import { logger } from './smartsocket.logging'; import { logger } from './smartsocket.logging';
@ -47,7 +50,7 @@ export class SmartsocketClient {
this.serverPort = optionsArg.port; this.serverPort = optionsArg.port;
this.socketRole = new SocketRole({ this.socketRole = new SocketRole({
name: optionsArg.role, name: optionsArg.role,
passwordHash: optionsArg.password passwordHash: optionsArg.password,
}); });
this.autoReconnect = optionsArg.autoReconnect; this.autoReconnect = optionsArg.autoReconnect;
} }
@ -73,7 +76,7 @@ export class SmartsocketClient {
socket: plugins.socketIoClient(socketUrl, { socket: plugins.socketIoClient(socketUrl, {
multiplex: false, multiplex: false,
reconnectionAttempts: 5, reconnectionAttempts: 5,
}) }),
}); });
const timer = new plugins.smarttime.Timer(5000); const timer = new plugins.smarttime.Timer(5000);
@ -84,33 +87,35 @@ export class SmartsocketClient {
}); });
// authentication flow // authentication flow
this.socketConnection.socket.on('requestAuth', (requestAuthPayload: interfaces.IRequestAuthPayload) => { this.socketConnection.socket.on(
timer.reset(); 'requestAuth',
logger.log('info', 'server requested authentication'); (requestAuthPayload: interfaces.IRequestAuthPayload) => {
timer.reset();
// lets register the authenticated event logger.log('info', 'server requested authentication');
this.socketConnection.socket.on('authenticated', () => {
this.remoteShortId = requestAuthPayload.serverShortId;
logger.log('info', 'client is authenticated');
this.socketConnection.authenticated = true;
this.socketConnection.listenToFunctionRequests();
done.resolve();
});
// lets register the forbidden event // lets register the authenticated event
this.socketConnection.socket.on('forbidden', async () => { this.socketConnection.socket.on('authenticated', () => {
logger.log('warn', `disconnecting due to being forbidden to use the ressource`); this.remoteShortId = requestAuthPayload.serverShortId;
await this.disconnect(); logger.log('info', 'client is authenticated');
}); this.socketConnection.authenticated = true;
this.socketConnection.listenToFunctionRequests();
done.resolve();
});
// lets provide the actual auth data // lets register the forbidden event
this.socketConnection.socket.emit('dataAuth', { this.socketConnection.socket.on('forbidden', async () => {
role: this.socketRole.name, logger.log('warn', `disconnecting due to being forbidden to use the ressource`);
password: this.socketRole.passwordHash, await this.disconnect();
alias: this.alias });
});
}); // lets provide the actual auth data
this.socketConnection.socket.emit('dataAuth', {
role: this.socketRole.name,
password: this.socketRole.passwordHash,
alias: this.alias,
});
}
);
// handle connection // handle connection
this.socketConnection.socket.on('connect', async () => { this.socketConnection.socket.on('connect', async () => {
@ -159,10 +164,13 @@ export class SmartsocketClient {
/** /**
* dispatches a server call * dispatches a server call
* @param functionNameArg * @param functionNameArg
* @param dataArg * @param dataArg
*/ */
public async serverCall<T extends plugins.typedrequestInterfaces.ITypedRequest>(functionNameArg: T['method'], dataArg: T['request']): Promise<T['response']> { public async serverCall<T extends plugins.typedrequestInterfaces.ITypedRequest>(
functionNameArg: T['method'],
dataArg: T['request']
): Promise<T['response']> {
const done = plugins.smartpromise.defer(); const done = plugins.smartpromise.defer();
const socketRequest = new SocketRequest<T>(this, { const socketRequest = new SocketRequest<T>(this, {
side: 'requesting', side: 'requesting',
@ -170,15 +178,15 @@ export class SmartsocketClient {
shortId: plugins.smartunique.shortId(), shortId: plugins.smartunique.shortId(),
funcCallData: { funcCallData: {
funcName: functionNameArg, funcName: functionNameArg,
funcDataArg: dataArg funcDataArg: dataArg,
} },
}); });
const response = await socketRequest.dispatch(); const response = await socketRequest.dispatch();
const result = response.funcDataArg; const result = response.funcDataArg;
return result; return result;
} }
private updateStatus (statusArg: interfaces.TConnectionStatus) { private updateStatus(statusArg: interfaces.TConnectionStatus) {
if (this.eventStatus !== statusArg) { if (this.eventStatus !== statusArg) {
this.eventSubject.next(statusArg); this.eventSubject.next(statusArg);
} }

View File

@ -90,10 +90,7 @@ export class SocketConnection {
public authenticate() { public authenticate() {
const done = plugins.smartpromise.defer(); const done = plugins.smartpromise.defer();
this.socket.on('dataAuth', async (dataArg: ISocketConnectionAuthenticationObject) => { this.socket.on('dataAuth', async (dataArg: ISocketConnectionAuthenticationObject) => {
logger.log( logger.log('info', 'received authentication data. now hashing and comparing...');
'info',
'received authentication data. now hashing and comparing...'
);
this.socket.removeListener('dataAuth', () => {}); this.socket.removeListener('dataAuth', () => {});
if (SocketRole.checkPasswordForRole(dataArg, this.smartsocketRef)) { if (SocketRole.checkPasswordForRole(dataArg, this.smartsocketRef)) {
// TODO: authenticate password // TODO: authenticate password
@ -101,10 +98,7 @@ export class SocketConnection {
this.authenticated = true; this.authenticated = true;
this.role = SocketRole.getSocketRoleByName(this.smartsocketRef, dataArg.role); this.role = SocketRole.getSocketRoleByName(this.smartsocketRef, dataArg.role);
this.socket.emit('authenticated'); this.socket.emit('authenticated');
logger.log( logger.log('ok', `socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`);
'ok',
`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`
);
done.resolve(this); done.resolve(this);
} else { } else {
this.authenticated = false; this.authenticated = false;
@ -113,7 +107,7 @@ export class SocketConnection {
} }
}); });
const requestAuthPayload: interfaces.IRequestAuthPayload = { const requestAuthPayload: interfaces.IRequestAuthPayload = {
serverShortId: this.smartsocketRef.shortId serverShortId: this.smartsocketRef.shortId,
}; };
this.socket.emit('requestAuth', requestAuthPayload); this.socket.emit('requestAuth', requestAuthPayload);
return done.promise; return done.promise;
@ -131,7 +125,7 @@ export class SocketConnection {
// check if requested function is available to the socket's scope // check if requested function is available to the socket's scope
logger.log('info', 'function request received'); logger.log('info', 'function request received');
const referencedFunction: SocketFunction<any> = this.role.allowedFunctions.find( const referencedFunction: SocketFunction<any> = this.role.allowedFunctions.find(
socketFunctionArg => { (socketFunctionArg) => {
return socketFunctionArg.name === dataArg.funcCallData.funcName; return socketFunctionArg.name === dataArg.funcCallData.funcName;
} }
); );
@ -141,31 +135,22 @@ export class SocketConnection {
side: 'responding', side: 'responding',
originSocketConnection: this, originSocketConnection: this,
shortId: dataArg.shortId, shortId: dataArg.shortId,
funcCallData: dataArg.funcCallData funcCallData: dataArg.funcCallData,
}); });
localSocketRequest.createResponse(); // takes care of creating response and sending it back localSocketRequest.createResponse(); // takes care of creating response and sending it back
} else { } else {
logger.log( logger.log('warn', 'function not existent or out of access scope');
'warn',
'function not existent or out of access scope'
);
} }
}); });
this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject<any>) => { this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject<any>) => {
logger.log( logger.log('info', `received response for request with id ${dataArg.shortId}`);
'info',
`received response for request with id ${dataArg.shortId}`
);
const targetSocketRequest = SocketRequest.getSocketRequestById( const targetSocketRequest = SocketRequest.getSocketRequestById(
this.smartsocketRef, this.smartsocketRef,
dataArg.shortId dataArg.shortId
); );
targetSocketRequest.handleResponse(dataArg); targetSocketRequest.handleResponse(dataArg);
}); });
logger.log( logger.log('info', `now listening to function requests for ${this.alias}`);
'info',
`now listening to function requests for ${this.alias}`
);
done.resolve(this); done.resolve(this);
} else { } else {
const errMessage = 'socket needs to be authenticated first'; const errMessage = 'socket needs to be authenticated first';
@ -181,7 +166,7 @@ export class SocketConnection {
this.updateStatus('disconnected'); this.updateStatus('disconnected');
} }
private updateStatus (statusArg: interfaces.TConnectionStatus) { private updateStatus(statusArg: interfaces.TConnectionStatus) {
if (this.eventStatus !== statusArg) { if (this.eventStatus !== statusArg) {
this.eventSubject.next(statusArg); this.eventSubject.next(statusArg);
} }

View File

@ -11,7 +11,9 @@ import { SmartsocketClient } from './smartsocket.classes.smartsocketclient';
/** /**
* interface of the contructor options of class SocketFunction * interface of the contructor options of class SocketFunction
*/ */
export interface ISocketFunctionConstructorOptions<T extends plugins.typedrequestInterfaces.ITypedRequest> { export interface ISocketFunctionConstructorOptions<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
funcName: T['method']; funcName: T['method'];
funcDef: TFuncDef<T>; funcDef: TFuncDef<T>;
allowedRoles: SocketRole[]; // all roles that are allowed to execute a SocketFunction allowedRoles: SocketRole[]; // all roles that are allowed to execute a SocketFunction
@ -20,7 +22,9 @@ export interface ISocketFunctionConstructorOptions<T extends plugins.typedreques
/** /**
* interface of the Socket Function call, in other words the object that routes a call to a function * interface of the Socket Function call, in other words the object that routes a call to a function
*/ */
export interface ISocketFunctionCallDataRequest<T extends plugins.typedrequestInterfaces.ITypedRequest> { export interface ISocketFunctionCallDataRequest<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
funcName: T['method']; funcName: T['method'];
funcDataArg: T['request']; funcDataArg: T['request'];
} }
@ -28,7 +32,9 @@ export interface ISocketFunctionCallDataRequest<T extends plugins.typedrequestIn
/** /**
* interface of the Socket Function call, in other words the object that routes a call to a function * interface of the Socket Function call, in other words the object that routes a call to a function
*/ */
export interface ISocketFunctionCallDataResponse<T extends plugins.typedrequestInterfaces.ITypedRequest> { export interface ISocketFunctionCallDataResponse<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
funcName: T['method']; funcName: T['method'];
funcDataArg: T['response']; funcDataArg: T['response'];
} }
@ -36,7 +42,10 @@ export interface ISocketFunctionCallDataResponse<T extends plugins.typedrequestI
/** /**
* interface for function definition of SocketFunction * interface for function definition of SocketFunction
*/ */
export type TFuncDef<T extends plugins.typedrequestInterfaces.ITypedRequest> = (dataArg: T['request'], connectionArg: SocketConnection) => PromiseLike<T['response']>; export type TFuncDef<T extends plugins.typedrequestInterfaces.ITypedRequest> = (
dataArg: T['request'],
connectionArg: SocketConnection
) => PromiseLike<T['response']>;
// export classes // export classes
@ -49,7 +58,7 @@ export class SocketFunction<T extends plugins.typedrequestInterfaces.ITypedReque
smartsocketRefArg: Smartsocket | SmartsocketClient, smartsocketRefArg: Smartsocket | SmartsocketClient,
functionNameArg: string functionNameArg: string
): SocketFunction<Q> { ): SocketFunction<Q> {
return smartsocketRefArg.socketFunctions.find(socketFunctionArg => { return smartsocketRefArg.socketFunctions.find((socketFunctionArg) => {
return socketFunctionArg.name === functionNameArg; return socketFunctionArg.name === functionNameArg;
}); });
} }
@ -74,11 +83,14 @@ export class SocketFunction<T extends plugins.typedrequestInterfaces.ITypedReque
/** /**
* invokes the function of this SocketFunction * invokes the function of this SocketFunction
*/ */
public async invoke(dataArg: ISocketFunctionCallDataRequest<T>, socketConnectionArg: SocketConnection): Promise<ISocketFunctionCallDataResponse<T>> { public async invoke(
dataArg: ISocketFunctionCallDataRequest<T>,
socketConnectionArg: SocketConnection
): Promise<ISocketFunctionCallDataResponse<T>> {
if (dataArg.funcName === this.name) { if (dataArg.funcName === this.name) {
const funcResponseData: ISocketFunctionCallDataResponse<T> = { const funcResponseData: ISocketFunctionCallDataResponse<T> = {
funcName: this.name, funcName: this.name,
funcDataArg: await this.funcDef(dataArg.funcDataArg, socketConnectionArg) funcDataArg: await this.funcDef(dataArg.funcDataArg, socketConnectionArg),
}; };
return funcResponseData; return funcResponseData;
} else { } else {

View File

@ -1,7 +1,11 @@
import * as plugins from './smartsocket.plugins'; import * as plugins from './smartsocket.plugins';
// import interfaces // import interfaces
import { SocketFunction, ISocketFunctionCallDataRequest, ISocketFunctionCallDataResponse } from './smartsocket.classes.socketfunction'; import {
SocketFunction,
ISocketFunctionCallDataRequest,
ISocketFunctionCallDataResponse,
} from './smartsocket.classes.socketfunction';
// import classes // import classes
import { SocketConnection } from './smartsocket.classes.socketconnection'; import { SocketConnection } from './smartsocket.classes.socketconnection';
@ -16,7 +20,9 @@ export type TSocketRequestSide = 'requesting' | 'responding';
/** /**
* interface of constructor of class SocketRequest * interface of constructor of class SocketRequest
*/ */
export interface ISocketRequestConstructorOptions<T extends plugins.typedrequestInterfaces.ITypedRequest> { export interface ISocketRequestConstructorOptions<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
side: TSocketRequestSide; side: TSocketRequestSide;
originSocketConnection: SocketConnection; originSocketConnection: SocketConnection;
shortId: string; shortId: string;
@ -39,7 +45,7 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
smartsocketRef: Smartsocket | SmartsocketClient, smartsocketRef: Smartsocket | SmartsocketClient,
shortIdArg: string shortIdArg: string
): SocketRequest<any> { ): SocketRequest<any> {
return smartsocketRef.socketRequests.find(socketRequestArg => { return smartsocketRef.socketRequests.find((socketRequestArg) => {
return socketRequestArg.shortid === shortIdArg; return socketRequestArg.shortid === shortIdArg;
}); });
} }
@ -74,7 +80,7 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
public dispatch(): Promise<ISocketFunctionCallDataResponse<T>> { public dispatch(): Promise<ISocketFunctionCallDataResponse<T>> {
const requestData: ISocketRequestDataObject<T> = { const requestData: ISocketRequestDataObject<T> = {
funcCallData: this.funcCallData, funcCallData: this.funcCallData,
shortId: this.shortid shortId: this.shortid,
}; };
this.originSocketConnection.socket.emit('function', requestData); this.originSocketConnection.socket.emit('function', requestData);
return this.done.promise; return this.done.promise;
@ -101,22 +107,21 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
); );
if (!targetSocketFunction) { if (!targetSocketFunction) {
logger.log( logger.log('warn', `There is no SocketFunction defined for ${this.funcCallData.funcName}`);
'warn',
`There is no SocketFunction defined for ${this.funcCallData.funcName}`
);
logger.log('warn', `So now response is being sent.`); logger.log('warn', `So now response is being sent.`);
return; return;
} }
logger.log('info', `invoking ${targetSocketFunction.name}`); logger.log('info', `invoking ${targetSocketFunction.name}`);
targetSocketFunction.invoke(this.funcCallData, this.originSocketConnection).then(resultData => { targetSocketFunction
logger.log('info', 'got resultData. Sending it to requesting party.'); .invoke(this.funcCallData, this.originSocketConnection)
const responseData: ISocketRequestDataObject<T> = { .then((resultData) => {
funcCallData: resultData, logger.log('info', 'got resultData. Sending it to requesting party.');
shortId: this.shortid const responseData: ISocketRequestDataObject<T> = {
}; funcCallData: resultData,
this.originSocketConnection.socket.emit('functionResponse', responseData); shortId: this.shortid,
this.smartsocketRef.socketRequests.remove(this); };
}); this.originSocketConnection.socket.emit('functionResponse', responseData);
this.smartsocketRef.socketRequests.remove(this);
});
} }
} }

View File

@ -23,7 +23,7 @@ export class SocketRole {
referenceSmartsocket: Smartsocket | SmartsocketClient, referenceSmartsocket: Smartsocket | SmartsocketClient,
socketRoleNameArg: string socketRoleNameArg: string
): SocketRole { ): SocketRole {
return referenceSmartsocket.socketRoles.find(socketRoleArg => { return referenceSmartsocket.socketRoles.find((socketRoleArg) => {
return socketRoleArg.name === socketRoleNameArg; return socketRoleArg.name === socketRoleNameArg;
}); });
} }

View File

@ -60,7 +60,10 @@ export class SocketServer {
throw new Error('there should be a port specified for smartsocket'); throw new Error('there should be a port specified for smartsocket');
} }
this.httpServer.listen(this.smartsocket.options.port, () => { this.httpServer.listen(this.smartsocket.options.port, () => {
logger.log('success', `Server started in standalone mode on ${this.smartsocket.options.port}`); logger.log(
'success',
`Server started in standalone mode on ${this.smartsocket.options.port}`
);
done.resolve(); done.resolve();
}); });
} else { } else {

View File

@ -1,3 +1,3 @@
import * as plugins from './smartsocket.plugins'; import * as plugins from './smartsocket.plugins';
export const logger = new plugins.smartlog.ConsoleLog(); export const logger = new plugins.smartlog.ConsoleLog();

View File

@ -1,7 +1,7 @@
// apiglobal scope // apiglobal scope
import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces'; import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces';
export {typedrequestInterfaces}; export { typedrequestInterfaces };
// pushrocks scope // pushrocks scope
import * as lik from '@pushrocks/lik'; import * as lik from '@pushrocks/lik';
@ -14,7 +14,6 @@ import * as smarttime from '@pushrocks/smarttime';
import * as smartunique from '@pushrocks/smartunique'; import * as smartunique from '@pushrocks/smartunique';
import * as smartrx from '@pushrocks/smartrx'; import * as smartrx from '@pushrocks/smartrx';
export { export {
lik, lik,
smartlog, smartlog,
@ -24,14 +23,11 @@ export {
smartpromise, smartpromise,
smarttime, smarttime,
smartunique, smartunique,
smartrx smartrx,
}; };
// third party scope // third party scope
import socketIo from 'socket.io'; import socketIo from 'socket.io';
import socketIoClient from 'socket.io-client'; import socketIoClient from 'socket.io-client';
export { export { socketIo, socketIoClient };
socketIo,
socketIoClient
};